diff --git a/katas/content/multi_qubit_gates/entangle_qubits/Placeholder.qs b/katas/content/multi_qubit_gates/entangle_qubits/Placeholder.qs new file mode 100644 index 0000000000..f5ee355d30 --- /dev/null +++ b/katas/content/multi_qubit_gates/entangle_qubits/Placeholder.qs @@ -0,0 +1,6 @@ +namespace Kata { + operation EntangleQubits (qs : Qubit[]) : Unit is Adj + Ctl { + // Implement your solution here... + + } +} \ No newline at end of file diff --git a/katas/content/multi_qubit_gates/entangle_qubits/Solution.qs b/katas/content/multi_qubit_gates/entangle_qubits/Solution.qs new file mode 100644 index 0000000000..3a2b89e267 --- /dev/null +++ b/katas/content/multi_qubit_gates/entangle_qubits/Solution.qs @@ -0,0 +1,5 @@ +namespace Kata { + operation EntangleQubits (qs : Qubit[]) : Unit is Adj + Ctl { + CNOT(qs[0], qs[1]); + } +} \ No newline at end of file diff --git a/katas/content/multi_qubit_gates/entangle_qubits/Verification.qs b/katas/content/multi_qubit_gates/entangle_qubits/Verification.qs new file mode 100644 index 0000000000..822d40def7 --- /dev/null +++ b/katas/content/multi_qubit_gates/entangle_qubits/Verification.qs @@ -0,0 +1,52 @@ +namespace Kata.Verification { + open Microsoft.Quantum.Katas; + open Microsoft.Quantum.Diagnostics; + open Microsoft.Quantum.Math; + open Microsoft.Quantum.Convert; + + operation EntangleQubits (qs : Qubit[]) : Unit is Adj + Ctl { + CNOT(qs[0], qs[1]); + } + + 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 + } + + operation CheckSolution() : Bool { + let range = 10; + for i in 0 .. range - 1 { + let angle = 2.0 * PI() * IntAsDouble(i) / IntAsDouble(range); + let initialState = qs => Ry(2.0 * angle, qs[0]); + let isCorrect = CheckOperationsEquivalenceOnInitialStateStrict( + initialState, + Kata.EntangleQubits, + EntangleQubits, + 2); + if not isCorrect { + Message("Incorrect"); + Message($"Test fails for alpha = {Cos(angle)}, beta = {Sin(angle)}."); + ShowQuantumStateComparison(2, initialState, Kata.EntangleQubits, EntangleQubits); + return false; + } + } + + Message("Correct!"); + true + } +} \ No newline at end of file diff --git a/katas/content/multi_qubit_gates/entangle_qubits/index.md b/katas/content/multi_qubit_gates/entangle_qubits/index.md new file mode 100644 index 0000000000..07ce922724 --- /dev/null +++ b/katas/content/multi_qubit_gates/entangle_qubits/index.md @@ -0,0 +1,5 @@ +**Input:** Two unentangled qubits (stored in an array of length 2). +The first qubit will be in state $|\psi\rangle = \alpha |0\rangle + \beta |1\rangle$, the second - in state $|0\rangle$ +(this can be written as two-qubit state $\big(\alpha |0\rangle + \beta |1\rangle \big) \otimes |0\rangle = \alpha |00\rangle + \beta |10\rangle$). + +**Goal:** Change the two-qubit state to $\alpha |00\rangle + \beta |11\rangle$. diff --git a/katas/content/multi_qubit_gates/entangle_qubits/solution.md b/katas/content/multi_qubit_gates/entangle_qubits/solution.md new file mode 100644 index 0000000000..7326c09106 --- /dev/null +++ b/katas/content/multi_qubit_gates/entangle_qubits/solution.md @@ -0,0 +1,11 @@ +Let's denote the first qubit in state $\alpha |0\rangle + \beta |1\rangle$ as A and the second qubit in state $|0\rangle$ as B. + +Compare our input state $\alpha |0_A0_B\rangle + \beta |1_A0_B\rangle$ with the goal state $\alpha |0_A0_B\rangle + \beta |1_A1_B\rangle$. +We want to pass our input qubit through a gate or gates (to be decided) that do the following. If qubit A is in the $|0\rangle$ state, then we want to leave qubit B alone (the first term of the superposition). +However, if A is in the $|1\rangle$ state, we want to flip qubit B from $|0\rangle$ into $|1\rangle$ state. In other words, the state of B is to be made contingent upon the state of A. +This is exactly the effect of the $CNOT$ gate. Depending upon the state of the **control** qubit (A in our case), the value of the controlled or **target** qubit (B in our case) is inverted or unchanged. Thus, we get the goal state $\alpha |00\rangle + \beta |11\rangle$. + +@[solution]({ + "id": "multi_qubit_gates__entangle_qubits_solution", + "codePath": "./Solution.qs" +}) diff --git a/katas/content/multi_qubit_gates/index.md b/katas/content/multi_qubit_gates/index.md index c5009d5e50..9fa2736944 100644 --- a/katas/content/multi_qubit_gates/index.md +++ b/katas/content/multi_qubit_gates/index.md @@ -121,6 +121,16 @@ $$\alpha|00\rangle + \beta|11\rangle$$ The $CNOT$ gate is self-adjoint: applying it for the second time reverses its effect. + +@[exercise]({ + "id": "multi_qubit_gates__entangle_qubits", + "title": "Entangle Qubits", + "path": "./entangle_qubits/", + "qsDependencies": [ + "../KatasLibrary.qs" + ] +}) + @[exercise]({ "id": "multi_qubit_gates__preparing_bell_state", "title": "Preparing a Bell State", @@ -130,6 +140,62 @@ The $CNOT$ gate is self-adjoint: applying it for the second time reverses its ef ] }) +@[section]({ + "id": "multi_qubit_gates__cz_gate", + "title": "CZ Gate" +}) + + +The $CZ$ ("controlled-Z") gate is a two-qubit gate, with one qubit referred to as the **control** qubit, and the other as the **target** qubit. Interestingly, for the $CZ$ gate it doesn't matter which qubit is control and which is target - the effect of the gate is the same either way! + +The $CZ$ gate acts as a conditional gate: if the control qubit is in state $|1\rangle$, it applies the $Z$ gate to the target qubit, otherwise it does nothing. + +
Gate | +Matrix | +Applying to $|\psi\rangle = \alpha|00\rangle + \beta|01\rangle + \gamma|10\rangle + \delta|11\rangle$ | +Applying to basis states | +
---|---|---|---|
$CZ$ | ++ $$\begin{bmatrix} + 1 & 0 & 0 & 0 \\ + 0 & 1 & 0 & 0 \\ + 0 & 0 & 1 & 0 \\ + 0 & 0 & 0 & -1 + \end{bmatrix}$$ + | +$CZ|\psi\rangle = \alpha|00\rangle + \beta|01\rangle + \gamma|10\rangle - \delta|11\rangle$ | ++ $$CZ|00\rangle = |00\rangle$$ + $$CZ|01\rangle = |01\rangle$$ + $$CZ|10\rangle = |10\rangle$$ + $$CZ|11\rangle = -|11\rangle$$ + | +