From b9a689327554bf815764a0219ec7ca0aca11020c Mon Sep 17 00:00:00 2001 From: YigeL <82920246+WWhitedogi@users.noreply.github.com> Date: Fri, 19 Apr 2024 01:07:21 -0400 Subject: [PATCH] Add tasks on Bell states changes to Multi-Qubit States kata (#1385) Co-authored-by: Mariia Mykhailova --- .../bell_state_change_1/Placeholder.qs | 6 ++ .../bell_state_change_1/Solution.qs | 5 ++ .../bell_state_change_1/Verification.qs | 62 ++++++++++++++++++ .../bell_state_change_1/index.md | 3 + .../bell_state_change_1/solution.md | 16 +++++ .../bell_state_change_2/Placeholder.qs | 6 ++ .../bell_state_change_2/Solution.qs | 5 ++ .../bell_state_change_2/Verification.qs | 62 ++++++++++++++++++ .../bell_state_change_2/index.md | 3 + .../bell_state_change_2/solution.md | 10 +++ .../bell_state_change_3/Placeholder.qs | 6 ++ .../bell_state_change_3/Solution.qs | 6 ++ .../bell_state_change_3/Verification.qs | 63 +++++++++++++++++++ .../bell_state_change_3/index.md | 3 + .../bell_state_change_3/solution.md | 11 ++++ katas/content/multi_qubit_systems/index.md | 42 +++++++++++-- 16 files changed, 305 insertions(+), 4 deletions(-) create mode 100644 katas/content/multi_qubit_systems/bell_state_change_1/Placeholder.qs create mode 100644 katas/content/multi_qubit_systems/bell_state_change_1/Solution.qs create mode 100644 katas/content/multi_qubit_systems/bell_state_change_1/Verification.qs create mode 100644 katas/content/multi_qubit_systems/bell_state_change_1/index.md create mode 100644 katas/content/multi_qubit_systems/bell_state_change_1/solution.md create mode 100644 katas/content/multi_qubit_systems/bell_state_change_2/Placeholder.qs create mode 100644 katas/content/multi_qubit_systems/bell_state_change_2/Solution.qs create mode 100644 katas/content/multi_qubit_systems/bell_state_change_2/Verification.qs create mode 100644 katas/content/multi_qubit_systems/bell_state_change_2/index.md create mode 100644 katas/content/multi_qubit_systems/bell_state_change_2/solution.md create mode 100644 katas/content/multi_qubit_systems/bell_state_change_3/Placeholder.qs create mode 100644 katas/content/multi_qubit_systems/bell_state_change_3/Solution.qs create mode 100644 katas/content/multi_qubit_systems/bell_state_change_3/Verification.qs create mode 100644 katas/content/multi_qubit_systems/bell_state_change_3/index.md create mode 100644 katas/content/multi_qubit_systems/bell_state_change_3/solution.md diff --git a/katas/content/multi_qubit_systems/bell_state_change_1/Placeholder.qs b/katas/content/multi_qubit_systems/bell_state_change_1/Placeholder.qs new file mode 100644 index 0000000000..f17bd7edf7 --- /dev/null +++ b/katas/content/multi_qubit_systems/bell_state_change_1/Placeholder.qs @@ -0,0 +1,6 @@ +namespace Kata { + operation BellStateChange1 (qs : Qubit[]) : Unit is Adj + Ctl { + // Implement your solution here... + + } +} \ No newline at end of file diff --git a/katas/content/multi_qubit_systems/bell_state_change_1/Solution.qs b/katas/content/multi_qubit_systems/bell_state_change_1/Solution.qs new file mode 100644 index 0000000000..404c630ca4 --- /dev/null +++ b/katas/content/multi_qubit_systems/bell_state_change_1/Solution.qs @@ -0,0 +1,5 @@ +namespace Kata { + operation BellStateChange1 (qs : Qubit[]) : Unit is Adj + Ctl { + Z(qs[0]); + } +} \ No newline at end of file diff --git a/katas/content/multi_qubit_systems/bell_state_change_1/Verification.qs b/katas/content/multi_qubit_systems/bell_state_change_1/Verification.qs new file mode 100644 index 0000000000..8e8f52eb98 --- /dev/null +++ b/katas/content/multi_qubit_systems/bell_state_change_1/Verification.qs @@ -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; + } + + +} diff --git a/katas/content/multi_qubit_systems/bell_state_change_1/index.md b/katas/content/multi_qubit_systems/bell_state_change_1/index.md new file mode 100644 index 0000000000..74b1d6fc57 --- /dev/null +++ b/katas/content/multi_qubit_systems/bell_state_change_1/index.md @@ -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)$. diff --git a/katas/content/multi_qubit_systems/bell_state_change_1/solution.md b/katas/content/multi_qubit_systems/bell_state_change_1/solution.md new file mode 100644 index 0000000000..070ba5263e --- /dev/null +++ b/katas/content/multi_qubit_systems/bell_state_change_1/solution.md @@ -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" +}) diff --git a/katas/content/multi_qubit_systems/bell_state_change_2/Placeholder.qs b/katas/content/multi_qubit_systems/bell_state_change_2/Placeholder.qs new file mode 100644 index 0000000000..3d68892d08 --- /dev/null +++ b/katas/content/multi_qubit_systems/bell_state_change_2/Placeholder.qs @@ -0,0 +1,6 @@ +namespace Kata { + operation BellStateChange2 (qs : Qubit[]) : Unit is Adj + Ctl { + // Implement your solution here... + + } +} \ No newline at end of file diff --git a/katas/content/multi_qubit_systems/bell_state_change_2/Solution.qs b/katas/content/multi_qubit_systems/bell_state_change_2/Solution.qs new file mode 100644 index 0000000000..ffad742359 --- /dev/null +++ b/katas/content/multi_qubit_systems/bell_state_change_2/Solution.qs @@ -0,0 +1,5 @@ +namespace Kata { + operation BellStateChange2 (qs : Qubit[]) : Unit is Adj + Ctl { + X(qs[0]); + } +} \ No newline at end of file diff --git a/katas/content/multi_qubit_systems/bell_state_change_2/Verification.qs b/katas/content/multi_qubit_systems/bell_state_change_2/Verification.qs new file mode 100644 index 0000000000..10810e0389 --- /dev/null +++ b/katas/content/multi_qubit_systems/bell_state_change_2/Verification.qs @@ -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; + } + + +} diff --git a/katas/content/multi_qubit_systems/bell_state_change_2/index.md b/katas/content/multi_qubit_systems/bell_state_change_2/index.md new file mode 100644 index 0000000000..2d97bc3f49 --- /dev/null +++ b/katas/content/multi_qubit_systems/bell_state_change_2/index.md @@ -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)$. \ No newline at end of file diff --git a/katas/content/multi_qubit_systems/bell_state_change_2/solution.md b/katas/content/multi_qubit_systems/bell_state_change_2/solution.md new file mode 100644 index 0000000000..263966d3ec --- /dev/null +++ b/katas/content/multi_qubit_systems/bell_state_change_2/solution.md @@ -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" +}) diff --git a/katas/content/multi_qubit_systems/bell_state_change_3/Placeholder.qs b/katas/content/multi_qubit_systems/bell_state_change_3/Placeholder.qs new file mode 100644 index 0000000000..c8605a172a --- /dev/null +++ b/katas/content/multi_qubit_systems/bell_state_change_3/Placeholder.qs @@ -0,0 +1,6 @@ +namespace Kata { + operation BellStateChange3(qs : Qubit[]) : Unit is Adj + Ctl { + // Implement your solution here... + + } +} \ No newline at end of file diff --git a/katas/content/multi_qubit_systems/bell_state_change_3/Solution.qs b/katas/content/multi_qubit_systems/bell_state_change_3/Solution.qs new file mode 100644 index 0000000000..1ca5339915 --- /dev/null +++ b/katas/content/multi_qubit_systems/bell_state_change_3/Solution.qs @@ -0,0 +1,6 @@ +namespace Kata { + operation BellStateChange3(qs : Qubit[]) : Unit is Adj + Ctl { + X(qs[0]); + Z(qs[0]); + } +} \ No newline at end of file diff --git a/katas/content/multi_qubit_systems/bell_state_change_3/Verification.qs b/katas/content/multi_qubit_systems/bell_state_change_3/Verification.qs new file mode 100644 index 0000000000..874988a7b9 --- /dev/null +++ b/katas/content/multi_qubit_systems/bell_state_change_3/Verification.qs @@ -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; + } + + +} diff --git a/katas/content/multi_qubit_systems/bell_state_change_3/index.md b/katas/content/multi_qubit_systems/bell_state_change_3/index.md new file mode 100644 index 0000000000..389db465be --- /dev/null +++ b/katas/content/multi_qubit_systems/bell_state_change_3/index.md @@ -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)$. \ No newline at end of file diff --git a/katas/content/multi_qubit_systems/bell_state_change_3/solution.md b/katas/content/multi_qubit_systems/bell_state_change_3/solution.md new file mode 100644 index 0000000000..c5b30bc3be --- /dev/null +++ b/katas/content/multi_qubit_systems/bell_state_change_3/solution.md @@ -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" +}) diff --git a/katas/content/multi_qubit_systems/index.md b/katas/content/multi_qubit_systems/index.md index 18c485b767..2efa8043d7 100644 --- a/katas/content/multi_qubit_systems/index.md +++ b/katas/content/multi_qubit_systems/index.md @@ -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 > @@ -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"