Skip to content

Commit

Permalink
Migrate tasks 1.10-1.15 from Measurements to Distinguishing States ka…
Browse files Browse the repository at this point in the history
…ta (#1622)

Migrate tasks 1.10 - 1.15 from the Measurements workbook to
Distinguishing States Kata.
This resolves a part of the [Issue
1185](#1185).

---------

Co-authored-by: Mariia Mykhailova <[email protected]>
  • Loading branch information
moumita-halder and tcNickolas authored Jun 12, 2024
1 parent 6e1a07b commit 7897294
Show file tree
Hide file tree
Showing 35 changed files with 740 additions and 15 deletions.
22 changes: 21 additions & 1 deletion katas/content/KatasLibrary.qs
Original file line number Diff line number Diff line change
Expand Up @@ -342,5 +342,25 @@ namespace Microsoft.Quantum.Katas {
}
}
return true;
}
}

operation WState_Arbitrary_Reference(qs : Qubit[]) : Unit is Adj + Ctl {
let N = Length(qs);

if N == 1 {
// base case of recursion: |1⟩
X(qs[0]);
} else {
// |W_N⟩ = |0⟩|W_(N-1)⟩ + |1⟩|0...0⟩
// do a rotation on the first qubit to split it into |0⟩ and |1⟩ with proper weights
// |0⟩ -> sqrt((N-1)/N) |0⟩ + 1/sqrt(N) |1⟩
let theta = ArcSin(1.0 / Sqrt(IntAsDouble(N)));
Ry(2.0 * theta, qs[0]);

// do a zero-controlled W-state generation for qubits 1..N-1
X(qs[0]);
Controlled WState_Arbitrary_Reference(qs[0..0], qs[1..N - 1]);
X(qs[0]);
}
}
}
17 changes: 17 additions & 0 deletions katas/content/distinguishing_states/Common.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
namespace Kata.Verification{
operation StatePrep_BasisStateMeasurement(
qs : Qubit[],
state : Int,
dummyVar : Double
) : Unit is Adj {
if state / 2 == 1 {
// |10⟩ or |11⟩
X(qs[0]);
}

if state % 2 == 1 {
// |01⟩ or |11⟩
X(qs[1]);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Kata {
operation AllZerosOrWState(qs : Qubit[]) : Int {
// Implement your solution here...

return -1;
}
}
13 changes: 13 additions & 0 deletions katas/content/distinguishing_states/all_zeros_w/SolutionA.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
namespace Kata {
operation AllZerosOrWState(qs : Qubit[]) : Int {
mutable countOnes = 0;

for q in qs {
if M(q) == One {
set countOnes += 1;
}
}

return countOnes == 0 ? 0 | 1;
}
}
5 changes: 5 additions & 0 deletions katas/content/distinguishing_states/all_zeros_w/SolutionB.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace Kata {
operation AllZerosOrWState(qs : Qubit[]) : Int {
return MeasureInteger(qs) == 0 ? 0 | 1;
}
}
34 changes: 34 additions & 0 deletions katas/content/distinguishing_states/all_zeros_w/Verification.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
namespace Kata.Verification {
open Microsoft.Quantum.Katas;

operation StatePrep_AllZerosOrWState(
qs : Qubit[],
state : Int,
dummyVar : Double
) : Unit is Adj {
if state == 1 {
// Prepare W state
WState_Arbitrary_Reference(qs);
}
}

@EntryPoint()
operation CheckSolution() : Bool {
for i in 2 .. 6 {
let isCorrect = DistinguishStates_MultiQubit(
i, 2,
StatePrep_AllZerosOrWState,
Kata.AllZerosOrWState,
false,
["|0...0⟩", "|W⟩"]);

if not isCorrect {
Message("Incorrect.");
return false;
}
}

Message("Correct!");
return true;
}
}
8 changes: 8 additions & 0 deletions katas/content/distinguishing_states/all_zeros_w/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
**Input:**
$N$ qubits (stored in an array of length $N$) which are guaranteed to be either in the $\ket{0...0}$ state or in the W state - an equal superposition of all $N$ basis states that have exactly one $\ket{1}$ in them. (For example, for $N = 3$ the W state is $\frac1{\sqrt3} (\ket{100} + \ket{010} + \ket{001})$).

**Output:**
* 0 if the qubits were in the $\ket{0...0}$ state,
* 1 if they were in the W state.

The state of the qubits at the end of the operation does not matter.
17 changes: 17 additions & 0 deletions katas/content/distinguishing_states/all_zeros_w/solution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
We can see that each basis state in the W state always has exactly one qubit in the $\ket{1}$ state, while in the $\ket{0...0}$ state, all qubits are in the $\ket{0}$ state.

We can use this to arrive to the solution: we will count the number of qubits that were measured in `One` state; if this number equals 1, we had a W state, if it equals 0, we know it was the $\ket{0...0}$ state.

> Note the use of a mutable variable `countOnes` to store the number of qubits measured in `One` state, and the use of a ternary operator `condition ? trueValue | falseValue` to express the return value.
@[solution]({
"id": "distinguishing_states__all_zeros_w_solution_A",
"codePath": "SolutionA.qs"
})

`MeasureInteger()` can also be used in this task to make the solution shorter.

@[solution]({
"id": "distinguishing_states__all_zeros_w_solution_B",
"codePath": "SolutionB.qs"
})
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,6 @@ namespace Kata.Verification {
open Microsoft.Quantum.Math;
open Microsoft.Quantum.Katas;

operation StatePrep_BasisStateMeasurement(qs : Qubit[], state : Int, dummyVar : Double) : Unit is Adj {

if state / 2 == 1 {
// |10⟩ or |11⟩
X(qs[0]);
}

if state % 2 == 1 {
// |01⟩ or |11⟩
X(qs[1]);
}
}

operation CheckSolution() : Bool {
let isCorrect = DistinguishStates_MultiQubit(2, 4, StatePrep_BasisStateMeasurement, Kata.BasisStateMeasurement, false, ["|00⟩", "|01⟩", "|10⟩", "|11⟩"]);
if (isCorrect) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Kata {
operation BellState(qs : Qubit[]) : Int {
// Implement your solution here...

return -1;
}
}
11 changes: 11 additions & 0 deletions katas/content/distinguishing_states/four_bell_states/Solution.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
namespace Kata {
operation BellState(qs : Qubit[]) : Int {
CNOT(qs[0], qs[1]);
H(qs[0]);

let m1 = M(qs[0]) == Zero ? 0 | 1;
let m2 = M(qs[1]) == Zero ? 0 | 1;

return m2 * 2 + m1;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
namespace Kata.Verification {
open Microsoft.Quantum.Katas;

// 0 - |Φ⁺⟩ = (|00⟩ + |11⟩) / sqrt(2)
// 1 - |Φ⁻⟩ = (|00⟩ - |11⟩) / sqrt(2)
// 2 - |Ψ⁺⟩ = (|01⟩ + |10⟩) / sqrt(2)
// 3 - |Ψ⁻⟩ = (|01⟩ - |10⟩) / sqrt(2)
operation StatePrep_BellState(
qs : Qubit[],
state : Int,
dummyVar : Double
) : Unit is Adj {
H(qs[0]);
CNOT(qs[0], qs[1]);

// Now we have |00⟩ + |11⟩ - modify it based on state arg
if state % 2 == 1 {
// negative phase
Z(qs[1]);
}
if state / 2 == 1 {
X(qs[1]);
}
}

@EntryPoint()
operation CheckSolution() : Bool {
let isCorrect = DistinguishStates_MultiQubit(
2,
4,
StatePrep_BellState,
Kata.BellState,
false,
["|Φ⁺⟩ = (|00⟩ + |11⟩) / sqrt(2)", "|Φ⁻⟩ = (|00⟩ - |11⟩) / sqrt(2)", "|Ψ⁺⟩ = (|01⟩ + |10⟩) / sqrt(2)", "|Ψ⁻⟩ = (|01⟩ - |10⟩) / sqrt(2)"]
);

if not isCorrect {
Message("Incorrect.");
} else {
Message("Correct!");
}

return isCorrect;
}
}
9 changes: 9 additions & 0 deletions katas/content/distinguishing_states/four_bell_states/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
**Input:** Two qubits (stored in an array of length 2) which are guaranteed to be in one of the four Bell states.

Output:
* 0 if they were in the state $\ket{\Phi^{+}} = \frac{1}{\sqrt{2}} \big(\ket{00} + \ket{11}\big)$,
* 1 if they were in the state $\ket{\Phi^{-}} = \frac{1}{\sqrt{2}} \big(\ket{00} - \ket{11}\big)$,
* 2 if they were in the state $\ket{\Psi^{+}} = \frac{1}{\sqrt{2}} \big(\ket{01} + \ket{10}\big)$,
* 3 if they were in the state $\ket{\Psi^{-}} = \frac{1}{\sqrt{2}} \big(\ket{01} - \ket{10}\big)$.

The state of the qubits at the end of the operation does not matter.
48 changes: 48 additions & 0 deletions katas/content/distinguishing_states/four_bell_states/solution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
If the qubits are entangled in one of the Bell states, you can't simply measure individual qubits to distinguish the states: if you do, the first two states will both give you 00 or 11, and the last two: 01 or 10. We need to come up with a way to transform the original states to states that are easy to distinguish before measuring them.

First, let's take a look at the preparation of the Bell states starting with the $\ket{00}$ basis state.

> A more detailed discussion of preparing all the Bell states can be found in the task "All Bell States" of the Preparing Quantum States kata.
The unitary transformation $\text{CNOT}\cdot(H \otimes I)$ (which corresponds to applying the $H$ gate to the first qubit, followed by applying the $\text{CNOT}$ gate with the first qubit as control and the second qubit as target) transforms the 4 basis vectors of the computational basis into the 4 Bell states.

$$\text{CNOT}\cdot(H \otimes I) = \frac{1}{\sqrt2} \begin{bmatrix} 1 & 0 & 1 & 0 \\ 0 & 1 & 0 & 1 \\ 0 & 1 & 0 & -1 \\ \underset{\ket{\Phi^{+}}}{\underbrace{1}} & \underset{\ket{\Psi^{+}}}{\underbrace{0}} & \underset{\ket{\Phi^{-}}}{\underbrace{-1}} & \underset{\ket{\Psi^{-}}}{\underbrace{0}} \end{bmatrix}$$

To transform the Bell states back to the basis states, you can apply adjoint of this transformation, which will undo its effects. In this case, both gates used are self-adjoint, so the adjoint transformation will require applying the same gates in reverse order (first $\text{CNOT}$, then $H$).

After this the original states will be transformed as follows:

<table>
<tr>
<th>Return value</th>
<th>Original state</th>
<th>Maps to basis state</th>
</tr>
<tr>
<td>0</td>
<td>$\ket{\Phi^{+}} = \frac{1}{\sqrt{2}} \big (\ket{00} + \ket{11}\big)$</td>
<td>$\ket{00}$</td>
</tr>
<tr>
<td>1</td>
<td>$\ket{\Phi^{-}} = \frac{1}{\sqrt{2}} \big (\ket{00} - \ket{11}\big)$</td>
<td>$\ket{10}$</td>
</tr>
<tr>
<td>2</td>
<td>$\ket{\Psi^{+}} = \frac{1}{\sqrt{2}} \big (\ket{01} + \ket{10}\big)$</td>
<td>$\ket{01}$</td>
</tr>
<tr>
<td>3</td>
<td>$\ket{\Psi^{-}} = \frac{1}{\sqrt{2}} \big (\ket{01} - \ket{10}\big)$</td>
<td>$\ket{11}$</td>
</tr>
</table>

These are the same four two-qubit basis states we've seen in the task "Distinguish Four Basis States", though in a different order compared to that task, so mapping the measurement results to the return values will differ slightly.

@[solution]({
"id": "distinguishing_states__four_bell_states_solution",
"codePath": "Solution.qs"
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Kata {
operation TwoQubitState(qs : Qubit[]) : Int {
// Implement your solution here...

return -1;
}

// You might find this helper operation from an earlier task useful.
operation BasisStateMeasurement(qs : Qubit[]) : Int {
let m1 = M(qs[0]) == Zero ? 0 | 1;
let m2 = M(qs[1]) == Zero ? 0 | 1;

return m1 * 2 + m2;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
namespace Kata {
operation TwoQubitState(qs : Qubit[]) : Int {
H(qs[0]);
H(qs[1]);

return BasisStateMeasurement(qs);
}

operation BasisStateMeasurement(qs : Qubit[]) : Int {
let m1 = M(qs[0]) == Zero ? 0 | 1;
let m2 = M(qs[1]) == Zero ? 0 | 1;

return m1 * 2 + m2;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
namespace Kata.Verification {
open Microsoft.Quantum.Katas;

// 0 - (|00⟩ + |01⟩ + |10⟩ + |11⟩) / 2
// 1 - (|00⟩ - |01⟩ + |10⟩ - |11⟩) / 2
// 2 - (|00⟩ + |01⟩ - |10⟩ - |11⟩) / 2
// 3 - (|00⟩ - |01⟩ - |10⟩ + |11⟩) / 2
operation StatePrep_TwoQubitState(
qs : Qubit[],
state : Int,
dummyVar : Double
) : Unit is Adj {
StatePrep_BasisStateMeasurement(qs, state, dummyVar);

H(qs[0]);
H(qs[1]);
}

@EntryPoint()
operation CheckSolution() : Bool {
let isCorrect = DistinguishStates_MultiQubit(
2,
4,
StatePrep_TwoQubitState,
Kata.TwoQubitState,
false,
["(|00⟩ + |01⟩ + |10⟩ + |11⟩) / 2", "(|00⟩ - |01⟩ + |10⟩ - |11⟩) / 2", "(|00⟩ + |01⟩ - |10⟩ - |11⟩) / 2", "(|00⟩ - |01⟩ - |10⟩ + |11⟩) / 2"]
);

if not isCorrect {
Message("Incorrect.");
} else {
Message("Correct!");
}

return isCorrect
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
**Input:** Two qubits (stored in an array of length 2) which are guaranteed to be in one of the four orthogonal states.

**Output:**
* 0 if they were in the state
$\ket{S_0} = \frac{1}{2} \big(\ket{00} + \ket{01} + \ket{10} + \ket{11}\big)$,
* 1 if they were in the state
$\ket{S_1} = \frac{1}{2} \big(\ket{00} - \ket{01} + \ket{10} - \ket{11}\big)$,
* 2 if they were in the state
$\ket{S_2} = \frac{1}{2} \big(\ket{00} + \ket{01} - \ket{10} - \ket{11}\big)$,
* 3 if they were in the state
$\ket{S_3} = \frac{1}{2} \big(\ket{00} - \ket{01} - \ket{10} + \ket{11}\big)$.

The state of the qubits at the end of the operation does not matter.
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
Similarly to the previous task, let's see whether these states can be converted back to the basis states from the task "Distinguish Four Basis States".

To find a transformation that would convert the basis states to $\ket{S_0},...\ket{S_3}$, let's write out the coefficients of these states as column vectors side by side, so that they form a matrix.

$$\frac12 \begin{bmatrix} 1 & 1 & 1 & 1 \\ 1 & -1 & 1 & -1 \\ 1 & 1 & -1 & -1 \\
\underset{\ket{S_0}}{\underbrace{1}} & \underset{\ket{S_1}}{\underbrace{-1}} & \underset{\ket{S_2}}{\underbrace{-1}} & \underset{\ket{S_3}}{\underbrace{1}} \end{bmatrix}$$

Applying this matrix to each of the basis states will produce the given states. You can check explicitly that applying this transformation to the basis state $\ket{00}$ gives:

$$\frac{1}{2} \begin{bmatrix} 1 & 1 & 1 & 1 \\ 1 & -1 & 1 & -1 \\ 1 & 1 & -1 & -1 \\ 1 & -1 & -1 & 1 \end{bmatrix} \cdot \begin{bmatrix}1 \\ 0 \\ 0 \\ 0 \end{bmatrix} =
\frac{1}{2}\begin{bmatrix}1 \\ 1 \\ 1 \\ 1 \end{bmatrix} =
\frac{1}{2} \big(\ket{00} + \ket{01} + \ket{10} + \ket{11}\big) = \ket{S_0}$$

and similarly for the rest of the states.

Notice that the top left $2\times2$ block of this matrix is the same as the top right and the bottom left, and same as the bottom right block multiplied by $-1$. This means that we can represent this transformation as a tensor product of two $H$ gates (for background on this, check the Multi-Qubit Gates kata):

$$ H \otimes H =
\frac{1}{\sqrt{2}} \begin{bmatrix} 1 & 1 \\ 1 & -1 \end{bmatrix} \otimes \frac{1}{\sqrt{2}} \begin{bmatrix} 1 & 1 \\ 1 & -1 \end{bmatrix} =
\frac{1}{2} \begin{bmatrix} 1 & 1 & 1 & 1 \\ 1 & -1 & 1 & -1 \\ 1 & 1 & -1 & -1 \\ 1 & -1 & -1 & 1 \end{bmatrix} $$

Knowing how to prepare the given states, we can convert the input state back to the corresponding basis state, like we've done in the previous task, and measure both qubits to get the answer.

@[solution]({
"id": "distinguishing_states__four_orthogonal_two_qubit_solution",
"codePath": "Solution.qs"
})
Loading

0 comments on commit 7897294

Please sign in to comment.