Skip to content

Commit

Permalink
Add sign flip, basis change, amplitude change tasks to Single-Qubit G…
Browse files Browse the repository at this point in the history
…ates kata (#1352)

Add amplitude_change task, basis_change task, sign_flip task, Common.qs
file to Single-Qubit Gates kata.

---------

Co-authored-by: Mariia Mykhailova <michaylova@gmail.com>
  • Loading branch information
WWhitedogi and tcNickolas authored Apr 6, 2024
1 parent 1e876da commit e3fa674
Show file tree
Hide file tree
Showing 16 changed files with 286 additions and 1 deletion.
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Kata {
operation AmplitudeChange (alpha : Double, q : Qubit) : Unit is Adj + Ctl {
// Implement your solution here...

}
}

5 changes: 5 additions & 0 deletions katas/content/single_qubit_gates/amplitude_change/Solution.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace Kata {
operation AmplitudeChange (alpha : Double, q : Qubit) : Unit is Adj + Ctl {
Ry(2.0 * alpha, q);
}
}
32 changes: 32 additions & 0 deletions katas/content/single_qubit_gates/amplitude_change/Verification.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
namespace Kata.Verification {
open Microsoft.Quantum.Katas;
open Microsoft.Quantum.Math;
open Microsoft.Quantum.Convert;

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

operation CheckSolution() : Bool {
for i in 0 .. 36 {
let alpha = ((2.0 * PI()) * IntAsDouble(i)) / 36.0;
let solution = register => Kata.AmplitudeChange(alpha, register[0]);
let reference = register => AmplitudeChange(alpha, register[0]);
let isCorrect = CheckOperationsEquivalenceStrict(solution, reference, 1);
if not isCorrect {
Message("Incorrect.");
Message($"The solution was incorrect for the test case alpha = {alpha}.");
Message("Hint: examine the effect your solution has on the state 0.6|0〉 + 0.8|1〉 and compare it with the effect it " +
"is expected to have.");
use initial = Qubit(); // |0〉
Ry(ArcTan2(0.8, 0.6) * 2.0, initial); // 0.6|0〉 + 0.8|1〉
ShowQuantumStateComparison([initial], solution, reference);
Reset(initial);
return false;
}
}

Message("Correct!");
true
}
}
10 changes: 10 additions & 0 deletions katas/content/single_qubit_gates/amplitude_change/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
**Inputs:**

1. Angle $\alpha$, in radians, represented as Double.
2. A qubit in state $|\psi\rangle = \beta |0\rangle + \gamma |1\rangle$.

**Goal:** Change the state of the qubit as follows:

- If the qubit is in state $|0\rangle$, change its state to $\cos \alpha |0\rangle + \sin \alpha |1\rangle$.
- If the qubit is in state $|1\rangle$, change its state to $-\sin \alpha |0\rangle + \cos \alpha |1\rangle$.
- If the qubit is in superposition, change its state according to the effect on basis vectors.
41 changes: 41 additions & 0 deletions katas/content/single_qubit_gates/amplitude_change/solution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
We can recognize that we need to use one of the rotation gates Rx, Ry, and Rz (named because they "rotate" the qubit state in the three dimensional space visualized as the Bloch sphere about the x, y, and z axes, respectively), since they involve angle parameters. Of these three gates, only Ry rotates the basis states $|0\rangle$ and $|1\rangle$ to have real amplitudes (the other two gates introduce complex coefficients).

As a reminder,

$$
R_{y}(\theta) =
\begin{bmatrix}\cos \frac{\theta}{2} & -\sin \frac{\theta}{2}\\\ \sin \frac{\theta}{2} & \cos \frac{\theta}{2}\end{bmatrix}
$$

Let's see its effect on the $|0\rangle$ state:

$$
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}\cdot1 - \sin \frac{\theta}{2}\cdot0\\\ \sin \frac{\theta}{2}\cdot1 + \cos \frac{\theta}{2}\cdot0
\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
$$

Recall that when applying a gate, you can tell what its matrix does to the basis states by looking at its columns: the first column of the matrix is the state into which it will transform the $|0\rangle$ state, and the second column is the state into which it will transform the $|1\rangle$ state.
One of the examples used by the testing harness has $\beta = 0.6, \gamma = 0.8$ and $\alpha = 1.0471975511965976 = \frac{\pi}{3}$.
Since $\cos \frac{\pi}{3} = 0.5$ and $\sin \frac{\pi}{3} = 0.8660$, working to 4 decimal places, we can use $\frac{\theta}{2} = \alpha$ to compute:

$$
R_{y}(\theta) |\psi\rangle=
\begin{bmatrix}\cos \frac{\theta}{2} & -\sin \frac{\theta}{2}\\\ \sin \frac{\theta}{2} & \cos \frac{\theta}{2} \end{bmatrix}
\begin{bmatrix}\beta\\\ \gamma\\\ \end{bmatrix}=
\begin{bmatrix}\cos \frac{\theta}{2}\cdot\beta - \sin \frac{\theta}{2}\cdot\gamma\\\ \sin \frac{\theta}{2}\cdot\beta +\cos \frac{\theta}{2}\cdot\gamma \end{bmatrix}=
\begin{bmatrix} 0.6\cdot\cos \frac{\pi}{3} -0.8\cdot\sin \frac{\pi}{3}\\\0.6\cdot\sin \frac{\pi}{3} +0.8\cdot\cos \frac{\pi}{3}\end{bmatrix}=
\begin{bmatrix}0.3 - 0.6928\\\ 0.5196 + 0.4\end{bmatrix}=
\begin{bmatrix}-0.3928\\\ 0.9196\\\ \end{bmatrix}
$$

Notice that we used $\frac{\theta}{2} = \alpha$; this means that in the Q# code we need to pass the angle $\theta = 2\alpha$.

@[solution]({
"id": "single_qubit_gates__amplitude_change_solution",
"codePath": "./Solution.qs"
})
7 changes: 7 additions & 0 deletions katas/content/single_qubit_gates/basis_change/Placeholder.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Kata {
operation BasisChange (q : Qubit) : Unit is Adj + Ctl {
// Implement your solution here...

}
}

5 changes: 5 additions & 0 deletions katas/content/single_qubit_gates/basis_change/Solution.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace Kata {
operation BasisChange (q : Qubit) : Unit is Adj + Ctl {
H(q);
}
}
28 changes: 28 additions & 0 deletions katas/content/single_qubit_gates/basis_change/Verification.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace Kata.Verification {
open Microsoft.Quantum.Katas;
open Microsoft.Quantum.Math;

operation BasisChange(q : Qubit) : Unit is Adj + Ctl {
H(q);
}

operation CheckSolution() : Bool {
let solution = register => Kata.BasisChange(register[0]);
let reference = register => BasisChange(register[0]);
let isCorrect = CheckOperationsEquivalenceStrict(solution, reference, 1);

// Output different feedback to the user depending on whether the solution was correct.
if isCorrect {
Message("Correct!");
} else {
Message("Incorrect.");
Message("Hint: examine the effect your solution has on the state 0.6|0〉 + 0.8|1〉 and compare it with the effect it " +
"is expected to have.");
use initial = Qubit(); // |0〉
Ry(ArcTan2(0.8, 0.6) * 2.0, initial); // 0.6|0〉 + 0.8|1〉
ShowQuantumStateComparison([initial], solution, reference);
Reset(initial);
}
isCorrect
}
}
7 changes: 7 additions & 0 deletions katas/content/single_qubit_gates/basis_change/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
**Input**: A qubit in state $|\psi\rangle = \alpha |0\rangle + \beta |1\rangle$.

**Goal**: Change the state of the qubit as follows:

- If the qubit is in state $|0\rangle$, change its state to $|+\rangle = \frac{1}{\sqrt{2}} \big(|0\rangle + |1\rangle\big)$.
- If the qubit is in state $|1\rangle$, change its state to $|-\rangle = \frac{1}{\sqrt{2}} \big(|0\rangle - |1\rangle\big)$.
- If the qubit is in superposition, change its state according to the effect on basis vectors.
36 changes: 36 additions & 0 deletions katas/content/single_qubit_gates/basis_change/solution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
We can recognize that the Hadamard gate changes states $|0\rangle$ and $|1\rangle$ to $|+\rangle$ and $|-\rangle$, respectively, and vice versa.

As a reminder, the Hadamard gate is defined by the following matrix:

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

For example, we can work out $H|1\rangle$ as follows:

$$
H|1\rangle=
\frac{1}{\sqrt{2}}\begin{bmatrix} 1 & 1 \\\1 & -1\end{bmatrix}
\begin{bmatrix} 0\\\ 1\end{bmatrix}=
\frac{1}{\sqrt{2}}\begin{bmatrix}1 \cdot 0 + 1 \cdot 1 \\\1 \cdot 0 + (-1) \cdot 1\end{bmatrix}=
\frac{1}{\sqrt{2}}\begin{bmatrix}1\\\ -1\\\ \end{bmatrix}=
\frac{1}{\sqrt{2}} \big(|0\rangle - |1\rangle\big) = |-\rangle
$$

Similarly, we can consider the effect of the Hadamard gate on the superposition state $|\psi\rangle = 0.6|0\rangle + 0.8|1\rangle$ (rounding the numbers to 4 decimal places):

$$
H|\psi⟩ =
\frac{1}{\sqrt{2}}\begin{bmatrix} 1 & 1 \\\ 1 & -1 \end{bmatrix}
\begin{bmatrix} \alpha\\\ \beta\\\ \end{bmatrix} =
\frac{1}{\sqrt{2}}\begin{bmatrix} \alpha + \beta\\\ \alpha - \beta\\\ \end{bmatrix}=
0.7071\begin{bmatrix} 1.4\\\ -0.2\\\ \end{bmatrix} =
\begin{bmatrix}
0.98994\\\ -0.14142\\\ \end{bmatrix} =
0.9899|0\rangle - 0.1414|1\rangle
$$

@[solution]({
"id": "single_qubit_gates__basis_change_solution",
"codePath": "./Solution.qs"
})
29 changes: 28 additions & 1 deletion katas/content/single_qubit_gates/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -334,6 +334,15 @@ All the basic gates we will be covering in this kata are part of the Intrinsic n
]
})

@[exercise]({
"id": "single_qubit_gates__sign_flip",
"title": "Sign Flip",
"path": "./sign_flip/",
"qsDependencies": [
"../KatasLibrary.qs"
]
})

@[exercise]({
"id": "single_qubit_gates__y_gate",
"title": "The Y Gate",
Expand Down Expand Up @@ -367,7 +376,7 @@ All the basic gates we will be covering in this kata are part of the Intrinsic n
})

The identity gate is mostly here for completeness, at least for now. It will come in handy when dealing with multi-qubit systems and multi-qubit gates. It is represented by the identity matrix, and does not affect the state of the qubit.

<table>
<tr>
<th>Gate</th>
Expand Down Expand Up @@ -416,6 +425,16 @@ $H|-i\rangle = e^{-i\pi/4}|i\rangle $ <br>
> As a reminder, $e^{i\pi/4} = \frac{1}{\sqrt2} (1 + i)$ and $e^{-i\pi/4} = \frac{1}{\sqrt2} (1 - i)$. This is an application of Euler's formula, $e^{i\theta} = \cos \theta + i\sin \theta$, where $\theta$ is measured in radians.
> See this [Wikipedia article](https://en.wikipedia.org/wiki/Euler%27s_formula) for an explanation of Euler's formula and/or [this video](https://youtu.be/v0YEaeIClKY) for a more intuitive explanation.
@[exercise]({
"id": "single_qubit_gates__basis_change",
"title": "Basis Change",
"path": "./basis_change/",
"qsDependencies": [
"../KatasLibrary.qs"
]
})


@[exercise]({
"id": "single_qubit_gates__prepare_minus",
"title": "Prepare Minus",
Expand Down Expand Up @@ -552,6 +571,14 @@ In addition, the rotation gates are very closely related to their respective Pau

$$X = iR_x(\pi), Y = iR_y(\pi), Z = iR_z(\pi)$$

@[exercise]({
"id": "single_qubit_gates__amplitude_change",
"title": "Amplitude_Change",
"path": "./amplitude_change/",
"qsDependencies": [
"../KatasLibrary.qs"
]
})
@[exercise]({
"id": "single_qubit_gates__prepare_rotated_state",
"title": "Prepare Rotated State",
Expand Down
7 changes: 7 additions & 0 deletions katas/content/single_qubit_gates/sign_flip/Placeholder.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Kata {
operation SignFlip (q : Qubit) : Unit is Adj + Ctl {
// Implement your solution here...

}
}

5 changes: 5 additions & 0 deletions katas/content/single_qubit_gates/sign_flip/Solution.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace Kata {
operation SignFlip (q : Qubit) : Unit is Adj + Ctl {
Z(q);
}
}
28 changes: 28 additions & 0 deletions katas/content/single_qubit_gates/sign_flip/Verification.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
namespace Kata.Verification {
open Microsoft.Quantum.Katas;
open Microsoft.Quantum.Math;

operation SignFlip(q : Qubit) : Unit is Adj + Ctl {
Z(q);
}

operation CheckSolution() : Bool {
let solution = register => Kata.SignFlip(register[0]);
let reference = register => SignFlip(register[0]);
let isCorrect = CheckOperationsEquivalenceStrict(solution, reference, 1);

// Output different feedback to the user depending on whether the solution was correct.
if isCorrect {
Message("Correct!");
} else {
Message("Incorrect.");
Message("Hint: examine the effect your solution has on the state 0.6|0〉 + 0.8|1〉 and compare it with the effect it " +
"is expected to have.");
use initial = Qubit(); // |0〉
Ry(ArcTan2(0.8, 0.6) * 2.0, initial); // 0.6|0〉 + 0.8|1〉
ShowQuantumStateComparison([initial], solution, reference);
Reset(initial);
}
isCorrect
}
}
3 changes: 3 additions & 0 deletions katas/content/single_qubit_gates/sign_flip/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
**Input**: A qubit in state $|\psi\rangle = \alpha |0\rangle + \beta |1\rangle$.

**Goal** : Change the qubit state to $\alpha |0\rangle - \beta |1\rangle$ (i.e., flip the sign of the $|1\rangle$ component of the superposition).
37 changes: 37 additions & 0 deletions katas/content/single_qubit_gates/sign_flip/solution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
The action of the Pauli Z gate is exactly what is required by this question.
This gate leaves the sign of the $|0\rangle$ component of the superposition unchanged but flips the sign of the $|1\rangle$ component of the superposition.

As a reminder, the Pauli Z gate is defined by the following matrix:

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

Let's see its effect on the only computational basis state that it changes, $|1\rangle$:

$$
Z|1\rangle =
\begin{bmatrix} 1 & 0\\\0 & -1 \end{bmatrix}
\begin{bmatrix}0\\\ 1\\\ \end{bmatrix}=
\begin{bmatrix}1 \cdot 0 + 0 \cdot1\\\0 \cdot 1 + (-1) \cdot 1\\\ \end{bmatrix}=
\begin{bmatrix}0\\\ -1\\\ \end{bmatrix}=
-\begin{bmatrix}0\\\ 1\\\ \end{bmatrix}=
-|1\rangle
$$

In general applying the Z gate to a single qubit superposition state $|\psi\rangle = \alpha |0\rangle + \beta |1\rangle$ gives

$$
Z|\psi\rangle =
\begin{bmatrix}1 & 0 \\\0 & -1\end{bmatrix}
\begin{bmatrix}\alpha\\\ \beta\\\ \end{bmatrix}=
\begin{bmatrix}1\cdot\alpha + 0\cdot\beta\\\0\cdot\alpha + (-1)\cdot\beta\\\ \end{bmatrix}=
\begin{bmatrix}\alpha\\\ -\beta\\\ \end{bmatrix}=
\alpha |0\rangle -\beta |1\rangle
$$

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

0 comments on commit e3fa674

Please sign in to comment.