Skip to content

Commit

Permalink
Add tasks on Bell states changes to Multi-Qubit States kata (#1385)
Browse files Browse the repository at this point in the history
Co-authored-by: Mariia Mykhailova <[email protected]>
  • Loading branch information
WWhitedogi and tcNickolas authored Apr 19, 2024
1 parent 4db51ce commit b9a6893
Show file tree
Hide file tree
Showing 16 changed files with 305 additions and 4 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Kata {
operation BellStateChange1 (qs : Qubit[]) : Unit is Adj + Ctl {
// Implement your solution here...

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace Kata {
operation BellStateChange1 (qs : Qubit[]) : Unit is Adj + Ctl {
Z(qs[0]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
namespace Kata.Verification {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Diagnostics;
open Microsoft.Quantum.Katas;

operation PrepareBellState(qs : Qubit[]) : Unit is Adj + Ctl {
H(qs[0]);
CNOT(qs[0], qs[1]);
}


operation BellStateChange1_Reference(qs : Qubit[]) : Unit is Adj + Ctl {
Z(qs[0]);
}


operation CheckOperationsEquivalenceOnInitialStateStrict(
initialState : Qubit[] => Unit is Adj,
op : (Qubit[] => Unit is Adj + Ctl),
reference : (Qubit[] => Unit is Adj + Ctl),
inputSize : Int
) : Bool {
use (control, target) = (Qubit(), Qubit[inputSize]);
within {
H(control);
initialState(target);
}
apply {
Controlled op([control], target);
Adjoint Controlled reference([control], target);
}


let isCorrect = CheckAllZero([control] + target);
ResetAll([control] + target);
isCorrect
}


@EntryPoint()
operation CheckSolution() : Bool {
let isCorrect = CheckOperationsEquivalenceOnInitialStateStrict(
PrepareBellState,
Kata.BellStateChange1,
BellStateChange1_Reference,
2);


if isCorrect {
Message("Correct!");
} else {
Message("Incorrect");
ShowQuantumStateComparison(2, PrepareBellState, Kata.BellStateChange1, BellStateChange1_Reference);
}


return isCorrect;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**Input:** Two entangled qubits in Bell state $|\Phi^{+}\rangle = \frac{1}{\sqrt{2}} \big(|00\rangle + |11\rangle\big)$.

**Goal:** Change the two-qubit state to $|\Phi^{-}\rangle = \frac{1}{\sqrt{2}} \big(|00\rangle - |11\rangle\big)$.
16 changes: 16 additions & 0 deletions katas/content/multi_qubit_systems/bell_state_change_1/solution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
We recognize that the goal is another Bell state. In fact, it is one of the four Bell states.

We remember from the Single-Qubit Gates kata that the Pauli Z gate will change the state of the $|1\rangle$ basis state of a single qubit, so this gate seems like a good candidate for what we want to achieve. This gate leaves the sign of the $|0\rangle$ basis state of a superposition unchanged, but flips the sign of the $|1\rangle$ basis state of the superposition.

Don't forget that the Z gate acts on only a single qubit, and we have two here.
Let's also remember how the Bell state is made up from its individual qubits.

If the two qubits are A and B, where A is `qs[0]` and B is `qs[1]`, we can write that
$|\Phi^{+}\rangle = \frac{1}{\sqrt{2}} \big(|0_{A}0_{B}\rangle + |1_{A}1_{B}\rangle\big)$.
If we apply the Z gate to the qubit A, it will flip the phase of the basis state $|1_A\rangle$. As this phase is in a sense spread across the entangled state, with $|1_A\rangle$ basis state being part of the second half of the superposition, this application has the effect of flipping the sign of the whole basis state $|1_A1_B\rangle$, as you can see by running the solution below.

The exact same calculations can be done if we apply Z to the qubit B, so that's another possible solution.
@[solution]({
"id": "multi_qubit_systems__bell_state_change_1_solution",
"codePath": "Solution.qs"
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Kata {
operation BellStateChange2 (qs : Qubit[]) : Unit is Adj + Ctl {
// Implement your solution here...

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace Kata {
operation BellStateChange2 (qs : Qubit[]) : Unit is Adj + Ctl {
X(qs[0]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
namespace Kata.Verification {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Diagnostics;
open Microsoft.Quantum.Katas;

operation PrepareBellState(qs : Qubit[]) : Unit is Adj + Ctl {
H(qs[0]);
CNOT(qs[0], qs[1]);
}


operation BellStateChange2_Reference(qs : Qubit[]) : Unit is Adj + Ctl {
X(qs[0]);
}


operation CheckOperationsEquivalenceOnInitialStateStrict(
initialState : Qubit[] => Unit is Adj,
op : (Qubit[] => Unit is Adj + Ctl),
reference : (Qubit[] => Unit is Adj + Ctl),
inputSize : Int
) : Bool {
use (control, target) = (Qubit(), Qubit[inputSize]);
within {
H(control);
initialState(target);
}
apply {
Controlled op([control], target);
Adjoint Controlled reference([control], target);
}


let isCorrect = CheckAllZero([control] + target);
ResetAll([control] + target);
isCorrect
}


@EntryPoint()
operation CheckSolution() : Bool {
let isCorrect = CheckOperationsEquivalenceOnInitialStateStrict(
PrepareBellState,
Kata.BellStateChange2,
BellStateChange2_Reference,
2);


if isCorrect {
Message("Correct!");
} else {
Message("Incorrect");
ShowQuantumStateComparison(2, PrepareBellState, Kata.BellStateChange2, BellStateChange2_Reference);
}


return isCorrect;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**Input:** Two entangled qubits in Bell state $|\Phi^{+}\rangle = \frac{1}{\sqrt{2}} \big(|00\rangle + |11\rangle\big)$.

**Goal:** Change the two-qubit state to $|\Psi^{+}\rangle = \frac{1}{\sqrt{2}} \big(|01\rangle + |10\rangle\big)$.
10 changes: 10 additions & 0 deletions katas/content/multi_qubit_systems/bell_state_change_2/solution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
We have seen in the Single-Qubit Gates kata that the Pauli X gate flips $|0\rangle$ to $|1\rangle$ and vice versa, and as we seem to need some flipping of states, perhaps this gate may be of use. (Bearing in mind, of course, that the X gate operates on a single qubit).

Let's compare the starting state $\frac{1}{\sqrt{2}} \big(|0_A0_B\rangle + |1_A1_B\rangle\big)$ with the goal state $\frac{1}{\sqrt{2}} \big(1_A0_B\rangle + |0_A1_B\rangle\big)$ term by term and see how we need to transform it to reach the goal.

Using our nomenclature from "Bell state change 1", we can now see by comparing terms that $|0_{A}\rangle$ has flipped to $|1_A\rangle$ to get the first term, and $|1_{A}\rangle$ has flipped to $|0_A\rangle$ to get the second term. This allows us to say that the correct gate to use is Pauli X, applied to `qs[0]`.

@[solution]({
"id": "multi_qubit_systems__bell_state_change_2_solution",
"codePath": "Solution.qs"
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Kata {
operation BellStateChange3(qs : Qubit[]) : Unit is Adj + Ctl {
// Implement your solution here...

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Kata {
operation BellStateChange3(qs : Qubit[]) : Unit is Adj + Ctl {
X(qs[0]);
Z(qs[0]);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
namespace Kata.Verification {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Diagnostics;
open Microsoft.Quantum.Katas;

operation PrepareBellState(qs : Qubit[]) : Unit is Adj + Ctl {
H(qs[0]);
CNOT(qs[0], qs[1]);
}


operation BellStateChange3_Reference(qs : Qubit[]) : Unit is Adj + Ctl {
X(qs[0]);
Z(qs[0]);
}


operation CheckOperationsEquivalenceOnInitialStateStrict(
initialState : Qubit[] => Unit is Adj,
op : (Qubit[] => Unit is Adj + Ctl),
reference : (Qubit[] => Unit is Adj + Ctl),
inputSize : Int
) : Bool {
use (control, target) = (Qubit(), Qubit[inputSize]);
within {
H(control);
initialState(target);
}
apply {
Controlled op([control], target);
Adjoint Controlled reference([control], target);
}


let isCorrect = CheckAllZero([control] + target);
ResetAll([control] + target);
isCorrect
}


@EntryPoint()
operation CheckSolution() : Bool {
let isCorrect = CheckOperationsEquivalenceOnInitialStateStrict(
PrepareBellState,
Kata.BellStateChange3,
BellStateChange3_Reference,
2);


if isCorrect {
Message("Correct!");
} else {
Message("Incorrect");
ShowQuantumStateComparison(2, PrepareBellState, Kata.BellStateChange3, BellStateChange3_Reference);
}


return isCorrect;
}


}
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**Input:** Two entangled qubits in Bell state $|\Phi^{+}\rangle = \frac{1}{\sqrt{2}} \big(|00\rangle + |11\rangle\big)$.

**Goal:** Change the two-qubit state, without adding a global phase, to $|\Psi^{-}\rangle = \frac{1}{\sqrt{2}} \big(|01\rangle - |10\rangle\big)$.
11 changes: 11 additions & 0 deletions katas/content/multi_qubit_systems/bell_state_change_3/solution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
We remember from the Single-Qubit Gates kata that the Pauli Z gate leaves the sign of the $|0\rangle$ component of the single qubit superposition unchanged but flips the sign of the $|1\rangle$ component of the superposition. We have also just seen in "Bell State Change 2" how to change our input state to the state $\frac{1}{\sqrt{2}} \big(|01\rangle + |10\rangle\big)$, which is almost our goal state (disregarding the phase change for the moment). So it would seem that a combination of these two gates will be what we need here. The remaining question is in what order to apply them, and to which qubit.

First of all, which qubit? Looking back at the task "Bell state change 2", it seems clear that we need to use qubit `qs[0]`, like we did there.

Second, in what order should we apply the gates? Remember that the Pauli Z gate flips the phase of the $|1\rangle$ component of the superposition and leaves the $|0\rangle$ component alone.
Let's experiment with applying X to `qs[0]` first. Looking at our "halfway answer" state $\frac{1}{\sqrt{2}} \big(|01\rangle + |10\rangle\big)$, we can see that if we apply the Z gate to `qs[0]`, it will leave the $|0_{A}\rangle$ alone but flip the phase of $|1_{A}\rangle$ to $-|1_{A}\rangle$, thus flipping the phase of the $|11\rangle$ component of our Bell state.

@[solution]({
"id": "multi_qubit_systems__bell_state_change_3_solution",
"codePath": "./Solution.qs"
})
42 changes: 38 additions & 4 deletions katas/content/multi_qubit_systems/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -230,10 +230,10 @@ Just like with single qubits, we can put arbitrary symbols within the kets the s
Whether a ket represents a single qubit or an entire system depends on the context.
Some ket symbols have a commonly accepted usage, such as the symbols for the Bell basis:

$$|\phi^+\rangle = \frac{1}{\sqrt{2}}\big(|00\rangle + |11\rangle\big)$$
$$|\phi^-\rangle = \frac{1}{\sqrt{2}}\big(|00\rangle - |11\rangle\big)$$
$$|\psi^+\rangle = \frac{1}{\sqrt{2}}\big(|01\rangle + |10\rangle\big)$$
$$|\psi^-\rangle = \frac{1}{\sqrt{2}}\big(|01\rangle - |10\rangle\big)$$
$$|\Phi^+\rangle = \frac{1}{\sqrt{2}}\big(|00\rangle + |11\rangle\big)$$
$$|\Phi^-\rangle = \frac{1}{\sqrt{2}}\big(|00\rangle - |11\rangle\big)$$
$$|\Psi^+\rangle = \frac{1}{\sqrt{2}}\big(|01\rangle + |10\rangle\big)$$
$$|\Psi^-\rangle = \frac{1}{\sqrt{2}}\big(|01\rangle - |10\rangle\big)$$

>## Endianness
>
Expand Down Expand Up @@ -364,6 +364,40 @@ Array elements are indexed starting with 0, the first array element corresponds
]
})

@[section]({
"id": "multi_qubit_systems__modifying_entangled_states",
"title": "Modifying Entangled States"
})

Entangled quantum states can be manipulated using single-qubit gates. For example, each state in the Bell basis is entangled and can be transformed into another Bell state through the application of single-qubit gates. In this lesson, you'll learn how to do that. (And we will learn more about applying single-qubit gates to multi-qubit states in the next kata.)

@[exercise]({
"id": "multi_qubit_systems__bell_state_change_1 ",
"title": "Bell State Change 1",
"path": "./bell_state_change_1/",
"qsDependencies": [
"../KatasLibrary.qs"
]
})

@[exercise]({
"id": "multi_qubit_systems__bell_state_change_2 ",
"title": "Bell State Change 2",
"path": "./bell_state_change_2/",
"qsDependencies": [
"../KatasLibrary.qs"
]
})

@[exercise]({
"id": "multi_qubit_systems__bell_state_change_3 ",
"title": "Bell State Change 3",
"path": "./bell_state_change_3/",
"qsDependencies": [
"../KatasLibrary.qs"
]
})

@[section]({
"id": "multi_qubit_systems__conclusion",
"title": "Conclusion"
Expand Down

0 comments on commit b9a6893

Please sign in to comment.