# Superposition Kata Workbook

**What is this workbook?**
A workbook is a collection of problems, accompanied by solutions to them. 
The explanations focus on the logical steps required to solve a problem; they illustrate the concepts that need to be applied to come up with a solution to the problem, explaining the mathematical steps required. 

Note that a workbook should not be the primary source of knowledge on the subject matter; it assumes that you've already read a tutorial or a textbook and that you are now seeking to improve your problem-solving skills. You should attempt solving the tasks of the respective kata first, and turn to the workbook only if stuck. While a textbook emphasizes knowledge acquisition, a workbook emphasizes skill acquisition.

This workbook describes the solutions to the problems offered in the [Superposition kata](./Superposition.ipynb). 
Since the tasks are offered as programming problems, the explanations also cover some elements of Q# that might be non-obvious for a first-time user.

**What you should know for this workbook**

You should be familiar with the following concepts before tackling the Superposition kata (and this workbook):
1. Basic linear algebra
2. The concept of qubit and multi-qubit systems
3. Single-qubit and multi-qubit quantum gates

To begin, first prepare this notebook for execution (if you skip this step, you'll get "Syntax does not match any known patterns" error when you try to execute Q# code in the next cells):


```qsharp
%package Microsoft.Quantum.Katas::0.9.1909.3002
```

> The package versions in the output of the cell above should always match. If you are running the Notebooks locally and the versions do not match, please install the IQ# version that matches the version of the `Microsoft.Quantum.Katas` package.
> <details>
> <summary><u>How to install the right IQ# version</u></summary>
> For example, if the version of `Microsoft.Quantum.Katas` package above is 0.1.2.3, the installation steps are as follows:
>
> 1. Stop the kernel.
> 2. Uninstall the existing version of IQ#:
>        dotnet tool uninstall microsoft.quantum.iqsharp -g
> 3. Install the matching version:
>        dotnet tool install microsoft.quantum.iqsharp -g --version 0.1.2.3
> 4. Reinstall the kernel:
>        dotnet iqsharp install
> 5. Restart the Notebook.
> </details>


## <a name="plus-state"></a> Task 1. Plus state.

**Input:** A qubit in the $|0\rangle$ state.

**Goal:**  Change the state of the qubit to $|+\rangle = \frac{1}{\sqrt{2}} \big(|0\rangle + |1\rangle\big)$.

### Solution

Look up any list of quantum gates, for example, [Quantum logic gate @ Wikipedia](https://en.wikipedia.org/wiki/Quantum_gate). Typically one of the first gates described will be the [Hadamard gate](https://en.wikipedia.org/wiki/Quantum_logic_gate#Hadamard_(H)_gate): 

$$H = \frac{1}{\sqrt2} \begin{bmatrix} 1 & 1 \\ 1 & -1 \end{bmatrix}$$

This gate converts $|0\rangle$ into $|+\rangle = \frac{1}{\sqrt{2}} \big(|0\rangle + |1\rangle\big)$ and $|1\rangle$ into $|−\rangle = \frac{1}{\sqrt{2}} \big(|0\rangle - |1\rangle\big)$.  The first of these transformations is exactly the one we're looking for!

To implement this operation in Q#, look at the list of [intrinsic gates](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic) available in Q#. 
[Hadamard gate](https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.h) is one of them. 
`Microsoft.Quantum.Intrinsic` namespace is open in Notebooks by default, so you can use the gates in the code right away. 


```qsharp
%kata T01_PlusState_Test 

operation PlusState (q : Qubit) : Unit {
    H(q);
}
```

[Return to task 1 of the Superposition kata.](./Superposition.ipynb#plus-state)

## <a name="minus-state"></a> Task 2. Minus State.

**Input:** A qubit in the $|0\rangle$ state.

**Goal:**  Change the state of the qubit to $|-\rangle = \frac{1}{\sqrt{2}} \big(|0\rangle - |1\rangle\big)$.

### Solution

As we've seen in the previous task, the Hadamard gate maps the basis state $|0\rangle$ to $\frac{1}{\sqrt2}\big(|0\rangle + |1\rangle\big)$ and $|1\rangle$ to $\frac{1}{\sqrt2}\big(|0\rangle - |1\rangle\big)$. 
If our qubit was already in the $|1\rangle$ state, we would simply apply the Hadamard gate to prepare the required $|-\rangle$ state. 
However, there is another operation we can use to change the state $|0\rangle$ to $|1\rangle$, namely the [X gate](https://en.wikipedia.org/wiki/Quantum_logic_gate#Pauli-X_gate):

$$X = \begin{bmatrix} 0 & 1 \\ 1 & 0 \end{bmatrix}$$

This gate transforms $|0\rangle \longmapsto |1\rangle$ and $|1\rangle \longmapsto |0\rangle$.

Here is the sequence of the steps to arrive to the solution:

<table style="background-color: white; border:1px solid; tr  { background-color:transparent; }">
    <col width=400>
    <col width=300>
    <col width=300>
    <tr>
        <th style="text-align:center; border:1px solid">Description of operation</th>
        <th style="text-align:center; border:1px solid">Notation</th>
        <th style="text-align:center; border:1px solid">Circuit</th>
    </tr>
    <tr>
        <td style="text-align:left; border:1px solid">Apply the X gate to $|0\rangle$ to get $|1\rangle$</td>
        <td style="text-align:center; border:1px solid">$X|0\rangle = |1\rangle$</td>
        <td style="text-align:center; border:1px solid"></td>    
      </tr>
    <tr>
        <td style="text-align:left; border:1px solid">Apply the Hadamard gate to $|1\rangle$ to get $\frac{1}{\sqrt2}\big(|0\rangle - |1\rangle\big)$</td>
        <td style="text-align:center; border:1px solid">$H|1\rangle = \frac{1}{\sqrt2}\big(|0\rangle - |1\rangle\big)$</td>
        <td style="text-align:center; border:1px solid"></td>       
    </tr>   
</table>

In Q#, each gate is applied to the qubit sequentially, transforming its internal state. [X gate](https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.x) is another gate in the `Microsoft.Quantum.Intrinsic` namespace.


```qsharp
%kata T02_MinusState_Test 

operation MinusState (q : Qubit) : Unit {
    X(q);
    H(q);
}
```

[Return to task 2 of the Superposition kata.](./Superposition.ipynb#minus-state)

## <a name="unequal-superposition"></a>  Task 3. Unequal superposition.

**Input:** 

1. A qubit in the $|0\rangle$ state.
2. Angle $\alpha$, in radians, represented as `Double`.

**Goal:**  Change the state of the qubit to $\cos\alpha|0\rangle$ + $\sin\alpha|1\rangle$.

### Solution
<table style="background-color: white; border:0 solid; tr  { background-color:white; }">
    <col width=130>
    <col width=300>
    <col width=130>
    <col width=230>
        <td style="text-align:center; font-bold; font-size: 14px; background-color:white; border:0">We want to move from the starting state</td>
        <td style="text-align:center; background-color:white; border:0"></td>
        <td style="text-align:center; font-bold; font-size: 14px; background-color:white; border:0">To the desired final state</td>
        <td style="text-align:center; background-color:white; border:0"></td>       
       </tr>
 </table>
In other words, we are looking for some kind of a rotation operation. There are three special gates that implement rotations around various axis of the Bloch Sphere: 

<table style="background-color: white; border:0 solid; tr  { background-color:white; }">
    <col width=300>
    <col width=300>
    <col width=250>
    <tr>
        <td style="text-align:left; font-size: 14px; background-color:white; border:0">$R_x(\theta) = \begin{bmatrix} \cos\frac{\theta}{2} & -i\sin\frac{\theta}{2} \\ -i\sin\frac{\theta}{2} & \cos\frac{\theta}{2} \end{bmatrix}$</td>
        <td style="text-align:left; font-size: 14px; background-color:white; border:0">$R_y(\theta) = \begin{bmatrix} \cos\frac{\theta}{2} & -\sin\frac{\theta}{2} \\ \sin\frac{\theta}{2} & \cos\frac{\theta}{2} \end{bmatrix}$</td>
        <td style="text-align:left; font-size: 14px; background-color:white; border:0">$R_z(\theta) = \begin{bmatrix} e^{-i\theta/2} & 0 \\ 0 & e^{i\theta/2} \end{bmatrix}$</td>
      </tr>    
</table>

If we were to apply the $R_x$ gate to a qubit in the $|0\rangle$ state, we would introduce complex coefficients to the amplitudes, which is clearly not what we're looking for. Similarly, the $R_z$ gate introduces only a global phase when applied to $|0\rangle$ state, so we can rule it out as well. This leaves only the $R_y$ as a starting point for the solution.

Applying the $R_y$ gate to the $|0\rangle$ state, we get:
$$R_y(\theta) |0\rangle = \begin{bmatrix} \cos\frac{\theta}{2} & -\sin\frac{\theta}{2} \\ \sin\frac{\theta}{2} & \cos\frac{\theta}{2} \end{bmatrix} \begin{bmatrix} 1 \\ 0 \end{bmatrix} = \begin{bmatrix} \cos\frac{\theta}{2} \\ \sin\frac{\theta}{2} \end{bmatrix} = \cos\frac{\theta}{2}|0\rangle + \sin\frac{\theta}{2}|1\rangle$$

Therefore, applying the $R_y(2\alpha$) gate to $|0\rangle$ is the solution to our problem. 

> <table style="background-color: white; font-size: 14px; border:0 solid; tr  { background-color:white; }">
    <col width=600>
    <col width=300>
    <tr>
        <td style="text-align:left; background-color:white; border:0">
Let us have a look at the Bloch sphere to obtain a geometrical interpretation of the operation.
<br/><br/>
The X-Z plane has no complex numbers, i.e. for qubit states that fall on it the amplitudes for both $|0\rangle$ and $|1\rangle$ basis states will always be real. We can see that the $R_y$ gate, which rotates the qubit state around the Y axis, keeps it within the X-Z plane. 
<br/><br/> 
Looking at the other two gates, $R_x$ gate rotates the qubit state around the X axis and thus takes the qubit state out of the X-Z plane, introducing complex coefficients. $R_z$ gate rotates the qubit state around the Z axis, so it doesn't modify the $|0\rangle$ state which lies on the Z axis.
<br/><br/> 
In case you are surprised to see the $|0\rangle$ and $|1\rangle$ vectors 180 degrees apart from each other, the Bloch sphere represents orthogonal vectors as opposite points on the sphere.  
You can learn more about the bloch sphere from <a href="http://www.vcpc.univie.ac.at/~ian/hotlist/qc/talks/bloch-sphere.pdf">this presentation</a></td>
        <td style="text-align:center; font-size: 14px; background-color:white; border:0"></td> 
      </tr>    
</table>

In Q#, $R_y$ gate is represented as [Ry](https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.ry) operation. Note that you have to apply $R_y(2\alpha)$, not $R_y(\alpha)$; Q# does not have implicit type casing from `Int` to `Double`, so you have to calculate the angle parameter of the operation as `2.0 * alpha`, using a double constant 2.0 instead of an integer 2.


```qsharp
%kata T03_UnequalSuperposition_Test 

operation UnequalSuperposition (q : Qubit, alpha : Double) : Unit {
    Ry(2.0 * alpha, q);
}
```

[Return to task 3 of the Superposition kata.](./Superposition.ipynb#unequal-superposition)

## <a name="superposition-of-all-basis-vectors-on-two-qubits"></a>Task 4. Superposition of all basis vectors on two qubits.

**Input:** Two qubits in the $|00\rangle$ state (stored in an array of length 2).

**Goal:** Change the state of the qubits to $|+\rangle \otimes |+\rangle = \frac{1}{2} \big(|00\rangle + |01\rangle + |10\rangle + |11\rangle\big)$.

### Solution

We know that the Hadamard gate maps the basis state $|0\rangle$ to $\frac{1}{\sqrt2}(|0\rangle + |1\rangle)$, so it is a logical starting point for solving this problem. 

Next, we see that the final state has a $\frac{1}{2}$ term hinting that we might be applying two operations involving a $\frac{1}{\sqrt{2}}$ term. 

Now, how do we get the $|00\rangle + |01\rangle + |10\rangle + |11\rangle$ expression? Let's see what does multiplying the expression $|0\rangle + |1\rangle$ by itself look like:

$$\big(|0\rangle + |1\rangle\big) \otimes \big(|0\rangle + |1\rangle\big) = |0\rangle|0\rangle + |0\rangle|1\rangle + |1\rangle|0\rangle + |1\rangle|1\rangle = \\
= |00\rangle + |01\rangle + |10\rangle + |11\rangle$$

Thus, applying the Hadamard gate to each qubit in isolation will deliver the desired final result:

$$H|0\rangle \otimes H|0\rangle = \frac{1}{\sqrt2} \big(|0\rangle + |1\rangle\big) \otimes \frac{1}{\sqrt2}\big(|0\rangle + |1\rangle\big) = \\
= \frac{1}{2} (|00\rangle + |01\rangle + |10\rangle + |11\rangle)$$

Q# arrays are similar to arrays in other languages: you can access the $i$-th element of the array `qs` as `qs[i]` (indices are 0-based).


```qsharp
%kata T04_AllBasisVectors_TwoQubits_Test

operation AllBasisVectors_TwoQubits (qs : Qubit[]) : Unit {
    H(qs[0]);
    H(qs[1]);   
}
```

[Return to task 4 of the Superposition kata.](./Superposition.ipynb#superposition-of-all-basis-vectors-on-two-qubits)

## <a name="superposition-of-basis-vectors-with-phases"></a>Task 5. Superposition of basis vectors with phases.

**Input:** Two qubits in the $|00\rangle$ state (stored in an array of length 2).

**Goal:** Change the state of the qubits to $\frac{1}{2} \big(|00\rangle + i|01\rangle - |10\rangle - i|11\rangle\big)$.

### Solution

We will start approaching the problem from the desired end result. Let’s see if we can factor any expressions out of $\big(|00\rangle + i|01\rangle - |10\rangle - i|11\rangle\big)$:

\begin{equation}
|00\rangle + i|01\rangle - |10\rangle - i|11\rangle
= |00\rangle + \big(|0\rangle - |1\rangle\big) i|1\rangle - |10\rangle = \\
= \big(|0\rangle - |1\rangle\big) |0\rangle + \big(|0\rangle - |1\rangle\big) i|1\rangle
= \big(|0\rangle - |1\rangle\big) \otimes \big(|0\rangle + i|1\rangle\big)
\label{5.1} \tag{5.1}
\end{equation}

The fact that we were able to factor out the state into a tensor product of two terms means the state is separable.

This is looking promising.  Now let’s try to approach the problem from the other end, i.e. from the starting state of $|00\rangle$. 
As we've seen in the previous task, applying a Hadamard operation to each $|0\rangle$ gets us closer to the factored-out expression:

\begin{equation}
H|0\rangle \otimes H|0\rangle = \frac{1}{\sqrt2} \big(|0\rangle + |1\rangle\big) \otimes \frac{1}{\sqrt2} \big(|0\rangle + |1\rangle\big)
=\frac{1}{2} \big(|0\rangle + |1\rangle\big) \otimes \big(|0\rangle + |1\rangle\big) 
\label{5.2} \tag{5.2}
\end{equation}

If we compare equations 5.1 and 5.2 (while ignoring the $\frac{1}{2}$ term in equation 5.2), we end up with the following transformations that we need to perform on the individual qubits:

\begin{equation}
|0\rangle + |1\rangle \overset{???}\rightarrow |0\rangle - |1\rangle
\label{5.3} \tag{5.3}
\end{equation}

\begin{equation}
|0\rangle + |1\rangle \overset{???}\rightarrow |0\rangle + i|1\rangle
\label{5.4} \tag{5.4}
\end{equation}


Next lets take a look at our basic gates, in particular the <a href="https://en.wikipedia.org/wiki/Quantum_logic_gate#Pauli-Z_(%7F'%22%60UNIQ--postMath-00000021-QINU%60%22'%7F)_gate">Pauli Z gate</a>:

$$Z = \begin{bmatrix} 1 & 0 \\ 0 & -1 \end{bmatrix}$$

If it is applied to the state $\frac{1}{\sqrt2} \big(|0\rangle + |1\rangle\big)$, it will leave the basis state $|0\rangle$ unchanged and will map $|1\rangle$ to $-|1\rangle$. Thus, 

$$Z\frac{1}{\sqrt2} \big(|0\rangle + |1\rangle\big) = \frac{1}{\sqrt2} \big(|0\rangle - |1\rangle\big)$$

So the Z gate is the answers to the question of how to do the conversion 5.3. 

Looking for another gate to address the conversion 5.4, we find the <a href="https://docs.microsoft.com/en-us/qsharp/api/qsharp/microsoft.quantum.intrinsic.s">S gate</a>:

$$S = \begin{bmatrix} 1 & 0 \\ 0 & i \end{bmatrix}$$ 

If it is applied to the state $\frac{1}{\sqrt2} \big(|0\rangle + |1\rangle\big)$, it will leave the basis state $|0\rangle$ unchanged and will map $|1\rangle$ to $i|1\rangle$. Thus, 

$$S\frac{1}{\sqrt2} \big(|0\rangle + |1\rangle\big) = \frac{1}{\sqrt2} \big(|0\rangle + i|1\rangle\big)$$

So the S gate now answers the question of how to do the conversion 5.4.

To summarize, the state we need to prepare can be represented as follows:
$$ZH|0\rangle \otimes SH|0\rangle$$

Remember that in Q# the gates have to be applied in reverse order compared to the mathematical notation - the gate closest to the ket symbol is applied first.


```qsharp
%kata T05_AllBasisVectorsWithPhases_TwoQubits_Test

operation AllBasisVectorsWithPhases_TwoQubits (qs : Qubit[]) : Unit {
    H(qs[0]);
    Z(qs[0]);

    H(qs[1]);
    S(qs[1]);
}
```

[Return to task 5 of the Superposition kata.](./Superposition.ipynb#superposition-of-basis-vectors-with-phases)

*Solutions to the rest of the tasks coming up soon...*

a967fe3d621ef596ebc5d46fcc55bf0ed766d24e
ipynb
Jupyter Notebook
Superposition/Workbook_Superposition.ipynb
bookRa/QuantumKatas
e06a7adf610c11711a8f20b35062034811bac8c2
MIT
Superposition/Workbook_Superposition.ipynb
bookRa/QuantumKatas
e06a7adf610c11711a8f20b35062034811bac8c2
MIT
Superposition/Workbook_Superposition.ipynb
bookRa/QuantumKatas
e06a7adf610c11711a8f20b35062034811bac8c2
MIT
Qwen/Qwen-72B
1. YES
2. YES