# Intro⌗

In the previous katas, we learned how to send qubits through quantum gates, and how to prepare them in various states of superposition.

In this guide, we will be taking a look at measuring qubit states, and what effect measurement has on them.

# Task 1.1: |0⟩ or |1⟩ ?⌗

Here we are tasked with returning true if the input qubit is $$|1\rangle$$ and false if the qubit is $$|0\rangle$$.

To collapse the superposition and measure a qubit, we need to use the measurement gate M().

M() returns One if the qubit is $$|1\rangle$$ and Zero if it is $$|0\rangle$$.

The simplest way to do this task is to evaluate M(q) and test that it is equal to One. The result is a boolean, which we can then return.

operation IsQubitOne (q : Qubit) : Bool {
return (M(q) == One);
}


# Task 1.2: Set qubit to |0⟩ state⌗

In this task we are given a qubit in an arbitrary superposition. Firstly, we can measure the qubit to narrow it down to $$|0\rangle$$ or $$|1\rangle$$.

We check if it measured to be $$|1\rangle$$, and if so, apply an X() gate to change it to $$|0\rangle$$.

operation InitializeQubit (q : Qubit) : Unit {
if(M(q) == One){
X(q);
}
}


# Task 1.3: |+⟩ or |-⟩ ?⌗

We are now given a qubit which is in the state $$|+\rangle$$ or $$|-\rangle$$.

Let us first recall the mappings of the Hadamard gate.

$$|0\rangle \rightarrow |+\rangle$$ $$|1\rangle \rightarrow |-\rangle$$

Also, we can leverage the reversible properties of quantum gates to undo the Hadamard gate, returning our qubit to it's original state.

If the qubit measures to be zero, that means it was just $$|+\rangle$$ state and we can return true.

operation IsQubitPlus (q : Qubit) : Bool {
H(q);
if(M(q) == Zero){
return true;
}
else{
return false;
}
}


# Task 1.4: |A⟩ or |B⟩ ?⌗

We are given an angle $$\alpha$$ in radians and a qubit which will be in one of the following states:

$$|A\rangle = cos(\alpha)|0\rangle + sin(\alpha)|1\rangle$$ $$|B\rangle = - sin(\alpha)|0\rangle + cos(\alpha)|1\rangle$$

If we measure state $$|A\rangle$$ we return true, and false if we measure $$|B\rangle$$

We can think of these states as being some rotation of a qubit by $$\alpha$$ degrees.

operation AmplitudeChange_Reference (alpha : Double, q : Qubit) : Unit is Adj+Ctl {
Ry(2.0 * alpha, q);
}


# Task 1.5: |00⟩ or |11⟩ ?⌗

Here we are given a two qubit state with equal probability of being in state $$|11\rangle$$ and $$|00\rangle$$.

Since there are no possible mixed states, we only have to measure one of the qubits to determine the state of the other.

operation ZeroZeroOrOneOne (qs : Qubit[]) : Int {
if(M(qs) == One){
return 1;
}
else{
return 0;
}
}


# Task 1.6: Distinguish four basis states⌗

This task is the same as the task above, but we must add an additional check to account for the possibility of mixed states $$|01\rangle$$ and $$|10\rangle$$.

operation BasisStateMeasurement (qs : Qubit[]) : Int {
if(M(qs) == One){
if(M(qs) == One){
return 3; // |11⟩
}
else{
return 2; // |10⟩
}
}
else{
if(M(qs) == One){
return 1; // |01⟩
}
else{
return 0; // |00⟩
}
}
}


# Task 1.7: Distinguish two basis states given by bit strings⌗

In this task we are given two bit strings, as well as $$N$$ qubits that are in a state described by one of the two bitstrings.

First, we need to find where the bitstrings diverge. We can reuse our helper function from the last kata to find that index.

function FindFirstDiff (bits1 : Bool[], bits2 : Bool[]) : Int {
for (i in 0 .. Length(bits1) - 1) {
if (bits1[i] != bits2[i]) {
return i;
}
}
return -1;
}


Then we can measure our qubit array at the FirstDiff index. We can turn the result of our measurement into a boolean by testing it's equality to One.

If our qubit measured $$|1\rangle$$, our variable will be true. If we measured $$|0\rangle$$, our variable will be false.

Now we can check if the bit we measured belongs to the state describe by the first or second bitstring.

If the boolean at bits1[firstDiff] is the same as our measured value, we know bits1[] describes our current state and we can return 0.

operation TwoBitstringsMeasurement (qs : Qubit[], bits1 : Bool[], bits2 : Bool[]) : Int {

// find the first index at which the bit strings are different
let firstDiff = FindFirstDiff(bits1, bits2);

// res = true if the first different qubit measures to be one
let res = M(qs[firstDiff]) == One;

// If the measurement aligns with the value in the first bitstring, return 0
// Otherwise it's the second state, return false.
return res == bits1[firstDiff] ? 0 | 1;
}


# Task 1.8: |0...0⟩ state or W state ?⌗

In this task, we must determine if the supplied qubits are in a $$W$$ state or a $$|0..0\rangle$$ state.

We know from our last kata that the $$W$$ state looks like

$|W_N\rangle = \frac{\overbrace{|100...0\rangle + |010...0\rangle + ... + |00..01\rangle}^{N \text{ states}}}{\sqrt{N}}$

Notice how every possible measurement in a $$W$$ state includes a single $$1$$. If we find even a single one in our measured state, it can no longer be in state $$|0...0\rangle$$ and thus it must be a $$W$$ state.

operation AllZerosOrWState (qs : Qubit[]) : Int {
for (q in 0 .. Length(qs) - 1){
if(M(qs[q]) == One){
return 1; // We found a one, it's W
}
}
return 0; // it's |0...0⟩
}


# Task 1.9: GHZ state or W state ?⌗

Like the last task, we are given a qubit register and must determine which of two possible states they are in.

They can either be in a $$W$$ state, or a $$GHZ$$ state. Recall that a $$GHZ$$ state is:

$GHZ_n = \frac{ \overbrace{|0...0\rangle}^{n} + \overbrace{|1...1\rangle}^{n} }{\sqrt{2}}$

If our qubits are in a $$GHZ$$ state, we can expect them to be either all $$|0\rangle$$ or all $$|1\rangle$$. If we find two of our qubits measure as different values, we can assume they are in the $$W$$ state.

operation GHZOrWState (qs : Qubit[]) : Int {
for(q in 1 .. Length(qs) - 1){
if (M(qs[q-1]) != M(qs[q])){
return 1;
}
}
return 0;
}


# Task 1.10: Distinguish four Bell states⌗

As input we receive an array of two qubits that are guaranteed to be in a Bell state.

Let us recall the four Bell states, as well as the return values we use to distinguish them in this task.

$$0: |\Phi^+\rangle = \frac{|00\rangle + |11\rangle}{\sqrt{2}}$$ $$1: |\Phi^-\rangle = \frac{|00\rangle - |11\rangle}{\sqrt{2}}$$ $$2: |\Psi^+\rangle = \frac{|01\rangle + |10\rangle}{\sqrt{2}}$$ $$3: |\Psi^-\rangle = \frac{|01\rangle - |10\rangle}{\sqrt{2}}$$

The first step is to apply the H() gate to both of our qubits.

Then, we can reverse our Bell circuit by preforming a CNOT using the second bit as control, and then applying the H() gate to it.

This will change our state to one of the following: $$|00\rangle$$, $$|01\rangle$$, $$|10\rangle$$, $$|11\rangle$$.

We can then create two integer variables my measuring each of the qubits and testing their equality to Zero or One.

We can finally compute m2 * 2 + m1 and return it.

operation BellState (qs : Qubit[]) : Int {
H(qs);
H(qs);

CNOT(qs, qs);
H(qs);

let m1 = M(qs) == Zero ? 0 | 1;
let  m2 = M(qs) == Zero ? 0 | 1;
return m2 * 2 + m1;
} In this Quirk circuit, we can see that we input the $$|\Psi^-\rangle$$ state, and we received the value $$|11\rangle$$. $$(1 * 2) + 1 = 3$$, which corresponds to $$|\Psi^-\rangle$$.

# Task 1.11: Distinguish four orthogonal 2-qubit states⌗

We have the four following states, one of which represents the state of the supplied qubits:

$$|S_0\rangle = \frac{|00\rangle + |01\rangle + |10\rangle + |11\rangle}{2}$$ $$|S_1\rangle = \frac{|00\rangle - |01\rangle + |10\rangle - |11\rangle}{2}$$ $$|S_2\rangle = \frac{|00\rangle + |01\rangle - |10\rangle - |11\rangle}{2}$$ $$|S_3\rangle = \frac{|00\rangle - |01\rangle - |10\rangle + |11\rangle}{2}$$

We can again apply the Hadamard gate to both our qubits to collapse them into one of the two qubit basis states $$|00\rangle$$, $$|01\rangle$$, $$|10\rangle$$, or $$|11\rangle$$.

Then we can use the solution from task 1.6 to identify the correct basis state.

operation TwoQubitState (qs : Qubit[]) : Int {
H(qs);
H(qs);
return BasisStateMeasurement(qs);
}


# Task 1.12: Distinguish four orthogonal 2-qubit states, part two⌗

The trick to this task is applying the Hadamard gate to transform the four orthogonal states into the Bell states.

After this is achieved, we can implement code similar to task 1.10 to determine what the bell state is.

operation TwoQubitStatePartTwo (qs : Qubit[]) : Int {
H(qs);

CNOT(qs, qs);
H(qs);

let m1 = M(qs) == One ? 0 | 1;
let m2 = M(qs) == One ? 0 | 1;
return m2 * 2 + m1;
}


# Task 1.13: Distinguish two orthogonal states on three qubits⌗

As input, we are given three qubits stored in an array. The array is guaranteed to be in one of the following states:

$$\frac{|100\rangle + \omega|010\rangle + \omega^2|001\rangle }{\sqrt{3}}$$ $$\frac{|100\rangle + \omega^2|010\rangle + \omega|001\rangle }{\sqrt{3}}$$

where $$\omega = \text{exp}(2\pi \frac{i}{3})$$. We are to output 0 if we find our qubits in the first state, 1 if we find them in the second.

In order to solve this, we must map our first state to a $$W$$ state, and our second state to the first.

$\frac{|100\rangle + \omega|010\rangle + \omega^2|001\rangle }{\sqrt{3}} \rightarrow \frac{|100\rangle + |010\rangle + |001\rangle }{\sqrt{3}}$

$\frac{|100\rangle + \omega^2|010\rangle + \omega|001\rangle }{\sqrt{3}} \rightarrow \frac{|100\rangle + \omega|010\rangle + \omega^2|001\rangle }{\sqrt{3}}$

We can achieve this by applying a unitary operation of the form $$I_2 \otimes R \otimes R^2$$

$$\begin{bmatrix} 1 & 0\\ 0 & 1\\ \end{bmatrix} \otimes \begin{bmatrix} 1 & 0\\ 0 & \omega^2\\ \end{bmatrix} \otimes \begin{bmatrix} 1 & 0\\ 0 & \omega\\ \end{bmatrix}$$

Now we can take the new $$W$$ state and undo it into the state $$|000\rangle$$, by utilizing the Adjoint if the operation that let us prepare the $$W$$ state in the last kata.

Our second state will then be mapped to some state guaranteed to be perpendicular to $$|000\rangle$$. In simple terms, the second state will never be measured to be $$|000\rangle$$.

Now we can measure our state, which is either $$|000\rangle$$ (state 1) or something else (state 2). To measure this, I prefer to implement the alternate solution provided in the solutions file.

operation ThreeQubitMeasurement (qs : Qubit[]) : Int {
// map the first state to 000 state and the second one to something orthogonal to it
// (as described in reference solution)
R1(-2.0 * PI() / 3.0, qs);
R1(-4.0 * PI() / 3.0, qs);