Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

BasicGates kata: Improve test harness #147

Merged
merged 3 commits into from
Jul 16, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 24 additions & 20 deletions BasicGates/BasicGates.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,12 @@
"\n",
"### Q# materials\n",
"\n",
"* Basic gates provided in Q# belong to the `Microsoft.Quantum.Intrinsic` namespace and are listed [here](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic)."
"* Basic gates provided in Q# belong to the `Microsoft.Quantum.Intrinsic` namespace and are listed [here](https://docs.microsoft.com/qsharp/api/qsharp/microsoft.quantum.intrinsic).\n",
"\n",
"> Note that all operations in this section have `is Adj+Ctl` in their signature.\n",
"This means that they should be implemented in a way that allows Q# \n",
"to compute their adjoint and controlled variants automatically.\n",
"Since each task is solved using only intrinsic gates, you should not need to put any special effort in this."
]
},
{
Expand All @@ -93,8 +98,7 @@
"If the qubit is in state $|1\\rangle$, change its state to $|0\\rangle$.\n",
"\n",
"> Note that this operation is self-adjoint: applying it for a second time\n",
"> returns the qubit to the original state. `is Adj` at the end of the operation signature means that Q# will compute \n",
"> the operation that returns the qubit to the original state automatically."
"> returns the qubit to the original state. "
]
},
{
Expand All @@ -105,7 +109,7 @@
"source": [
"%kata T11_StateFlip_Test \n",
"\n",
"operation StateFlip (q : Qubit) : Unit is Adj {\n",
"operation StateFlip (q : Qubit) : Unit is Adj+Ctl {\n",
" // The Pauli X gate will change the |0⟩ state to the |1⟩ state and vice versa.\n",
" // Type X(q);\n",
" // Then run the cell using Ctrl/⌘+Enter.\n",
Expand Down Expand Up @@ -140,7 +144,7 @@
"source": [
"%kata T12_BasisChange_Test \n",
"\n",
"operation BasisChange (q : Qubit) : Unit is Adj {\n",
"operation BasisChange (q : Qubit) : Unit is Adj+Ctl {\n",
" // ...\n",
"}"
]
Expand All @@ -164,7 +168,7 @@
"source": [
"%kata T13_SignFlip_Test \n",
"\n",
"operation SignFlip (q : Qubit) : Unit is Adj {\n",
"operation SignFlip (q : Qubit) : Unit is Adj+Ctl {\n",
" // ...\n",
"}"
]
Expand Down Expand Up @@ -197,7 +201,7 @@
"source": [
"%kata T14_AmplitudeChange_Test\n",
"\n",
"operation AmplitudeChange (alpha : Double, q : Qubit) : Unit is Adj {\n",
"operation AmplitudeChange (alpha : Double, q : Qubit) : Unit is Adj+Ctl {\n",
" // ...\n",
"}"
]
Expand All @@ -210,7 +214,7 @@
"\n",
"**Input:** A qubit in state $|\\psi\\rangle = \\alpha |0\\rangle + \\beta |1\\rangle$.\n",
"\n",
"**Goal:** Change the qubit state to $\\alpha |0\\rangle + i\\beta |1\\rangle$ (add a relative phase $i$ to $|1\\rangle$ component of the superposition).\n"
"**Goal:** Change the qubit state to $\\alpha |0\\rangle + \\color{red}i\\beta |1\\rangle$ (add a relative phase $i$ to $|1\\rangle$ component of the superposition).\n"
]
},
{
Expand All @@ -221,7 +225,7 @@
"source": [
"%kata T15_PhaseFlip_Test\n",
"\n",
"operation PhaseFlip (q : Qubit) : Unit is Adj { \n",
"operation PhaseFlip (q : Qubit) : Unit is Adj+Ctl {\n",
" // ...\n",
"}"
]
Expand All @@ -239,8 +243,8 @@
"\n",
"**Goal:** Change the state of the qubit as follows:\n",
"- If the qubit is in state $|0\\rangle$, don't change its state.\n",
"- If the qubit is in state $|1\\rangle$, change its state to $\\exp^{i\\alpha} |1\\rangle$.\n",
"- If the qubit is in superposition, change its state according to the effect on basis vectors.\n"
"- If the qubit is in state $|1\\rangle$, change its state to $e^{i\\alpha} |1\\rangle$.\n",
"- If the qubit is in superposition, change its state according to the effect on basis vectors: $\\beta |0\\rangle + \\color{red}{e^{i\\alpha}} \\gamma |1\\rangle$.\n"
]
},
{
Expand All @@ -251,7 +255,7 @@
"source": [
"%kata T16_PhaseChange_Test\n",
"\n",
"operation PhaseChange (alpha : Double, q : Qubit) : Unit is Adj {\n",
"operation PhaseChange (alpha : Double, q : Qubit) : Unit is Adj+Ctl {\n",
" // ...\n",
"}"
]
Expand All @@ -275,7 +279,7 @@
"source": [
"%kata T17_BellStateChange1_Test\n",
"\n",
"operation BellStateChange1 (qs : Qubit[]) : Unit is Adj {\n",
"operation BellStateChange1 (qs : Qubit[]) : Unit is Adj+Ctl {\n",
" // ...\n",
"}"
]
Expand All @@ -299,7 +303,7 @@
"source": [
"%kata T18_BellStateChange2_Test\n",
"\n",
"operation BellStateChange2 (qs : Qubit[]) : Unit is Adj {\n",
"operation BellStateChange2 (qs : Qubit[]) : Unit is Adj+Ctl {\n",
" // ...\n",
"}"
]
Expand All @@ -323,7 +327,7 @@
"source": [
"%kata T19_BellStateChange3_Test\n",
"\n",
"operation BellStateChange3 (qs : Qubit[]) : Unit is Adj {\n",
"operation BellStateChange3 (qs : Qubit[]) : Unit is Adj+Ctl {\n",
" // ...\n",
"}"
]
Expand All @@ -347,7 +351,7 @@
"\n",
"**Input:** Two unentangled qubits (stored in an array of length 2).\n",
"The first qubit will be in state $|\\psi\\rangle = \\alpha |0\\rangle + \\beta |1\\rangle$, the second - in state $|0\\rangle$\n",
"(this can be written as two-qubit state $\\big(\\alpha |0\\rangle + \\beta |1\\rangle \\big) \\otimes |0\\rangle$.\n",
"(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$.\n",
"\n",
"\n",
"**Goal:** Change the two-qubit state to $\\alpha |00\\rangle + \\beta |11\\rangle$.\n",
Expand Down Expand Up @@ -376,7 +380,7 @@
"source": [
"### Task 2.2. Two-qubit gate - 2\n",
"\n",
"**Input:** Two unentangled qubits (stored in an array of length 2) in state $|+\\rangle \\otimes |+\\rangle = \\frac{1}{2} \\big( |00\\rangle + |01\\rangle + |10\\rangle + |11\\rangle \\big)$.\n",
"**Input:** Two unentangled qubits (stored in an array of length 2) in state $|+\\rangle \\otimes |+\\rangle = \\frac{1}{2} \\big( |00\\rangle + |01\\rangle + |10\\rangle \\color{blue}+ |11\\rangle \\big)$.\n",
"\n",
"\n",
"**Goal:** Change the two-qubit state to $\\frac{1}{2} \\big( |00\\rangle + |01\\rangle + |10\\rangle \\color{red}- |11\\rangle \\big)$.\n",
Expand Down Expand Up @@ -404,7 +408,7 @@
"source": [
"### Task 2.3. Two-qubit gate - 3\n",
"\n",
"**Input:** Two unentangled qubits (stored in an array of length 2) in an arbitrary two-qubit state $\\alpha |00\\rangle + \\beta |01\\rangle + \\gamma |10\\rangle + \\delta |11\\rangle$.\n",
"**Input:** Two unentangled qubits (stored in an array of length 2) in an arbitrary two-qubit state $\\alpha |00\\rangle + \\color{blue}\\beta |01\\rangle + \\color{blue}\\gamma |10\\rangle + \\delta |11\\rangle$.\n",
"\n",
"\n",
"**Goal:** Change the two-qubit state to $\\alpha |00\\rangle + \\color{red}\\gamma |01\\rangle + \\color{red}\\beta |10\\rangle + \\delta |11\\rangle$.\n",
Expand Down Expand Up @@ -432,7 +436,7 @@
"### Task 2.4. Toffoli gate\n",
"\n",
"**Input:** Three qubits (stored in an array of length 3) in an arbitrary three-qubit state \n",
"$\\alpha |000\\rangle + \\beta |001\\rangle + \\gamma |010\\rangle + \\delta |011\\rangle + \\epsilon |100\\rangle + \\zeta|101\\rangle + \\eta|110\\rangle + \\theta|111\\rangle$.\n",
"$\\alpha |000\\rangle + \\beta |001\\rangle + \\gamma |010\\rangle + \\delta |011\\rangle + \\epsilon |100\\rangle + \\zeta|101\\rangle + \\color{blue}\\eta|110\\rangle + \\color{blue}\\theta|111\\rangle$.\n",
"\n",
"**Goal:** Flip the state of the third qubit if the state of the first two is $|11\\rangle$, i.e., change the three-qubit state to $\\alpha |000\\rangle + \\beta |001\\rangle + \\gamma |010\\rangle + \\delta |011\\rangle + \\epsilon |100\\rangle + \\zeta|101\\rangle + \\color{red}\\theta|110\\rangle + \\color{red}\\eta|111\\rangle$."
]
Expand All @@ -457,7 +461,7 @@
"### Task 2.5. Fredkin gate\n",
"\n",
"**Input:** Three qubits (stored in an array of length 3) in an arbitrary three-qubit state \n",
"$\\alpha |000\\rangle + \\beta |001\\rangle + \\gamma |010\\rangle + \\delta |011\\rangle + \\epsilon |100\\rangle + \\zeta|101\\rangle + \\eta|110\\rangle + \\theta|111\\rangle$.\n",
"$\\alpha |000\\rangle + \\beta |001\\rangle + \\gamma |010\\rangle + \\delta |011\\rangle + \\epsilon |100\\rangle + \\color{blue}\\zeta|101\\rangle + \\color{blue}\\eta|110\\rangle + \\theta|111\\rangle$.\n",
"\n",
"**Goal:** Swap the states of second and third qubit if and only if the state of the first qubit is $|1\\rangle$, i.e., change the three-qubit state to $\\alpha |000\\rangle + \\beta |001\\rangle + \\gamma |010\\rangle + \\delta |011\\rangle + \\epsilon |100\\rangle + \\color{red}\\eta|101\\rangle + \\color{red}\\zeta|110\\rangle + \\theta|111\\rangle$."
]
Expand Down
24 changes: 13 additions & 11 deletions BasicGates/ReferenceImplementation.qs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ namespace Quantum.Kata.BasicGates {
// Example:
// If the qubit is in state |0⟩, change its state to |1⟩.
// If the qubit is in state |1⟩, change its state to |0⟩.
operation StateFlip_Reference (q : Qubit) : Unit is Adj {
operation StateFlip_Reference (q : Qubit) : Unit is Adj+Ctl {
X(q);
}

Expand All @@ -34,15 +34,15 @@ namespace Quantum.Kata.BasicGates {
// If the qubit is in state |1⟩, change its state to |-⟩ = (|0⟩ - |1⟩) / sqrt(2).
// If the qubit is in superposition, change its state according to the effect on basis vectors.
// Note: |+⟩ and |-⟩ form a different basis for single-qubit states, called X basis.
operation BasisChange_Reference (q : Qubit) : Unit is Adj {
operation BasisChange_Reference (q : Qubit) : Unit is Adj+Ctl {
H(q);
}


// Task 1.3. Sign flip: |+⟩ to |-⟩ and vice versa.
// Inputs: A qubit in state |ψ⟩ = α |0⟩ + β |1⟩.
// Goal: Change the qubit state to α |0⟩ - β |1⟩ (flip the sign of |1⟩ component of the superposition).
operation SignFlip_Reference (q : Qubit) : Unit is Adj {
operation SignFlip_Reference (q : Qubit) : Unit is Adj+Ctl {
Z(q);
}

Expand All @@ -55,17 +55,17 @@ namespace Quantum.Kata.BasicGates {
// If the qubit is in state |0⟩, change its state to cos(alpha)*|0⟩ + sin(alpha)*|1⟩.
// If the qubit is in state |1⟩, change its state to -sin(alpha)*|0⟩ + cos(alpha)*|1⟩.
// If the qubit is in superposition, change its state according to the effect on basis vectors.
operation AmplitudeChange_Reference (alpha : Double, q : Qubit) : Unit is Adj {
operation AmplitudeChange_Reference (alpha : Double, q : Qubit) : Unit is Adj+Ctl {
Ry(2.0 * alpha, q);
}


// Task 1.5. Phase flip
// Input: A qubit in state |ψ⟩ = α |0⟩ + β |1⟩.
// Goal: Change the qubit state to α |0⟩ + iβ |1⟩ (flip the phase of |1⟩ component of the superposition).
operation PhaseFlip_Reference (q : Qubit) : Unit is Adj {
operation PhaseFlip_Reference (q : Qubit) : Unit is Adj+Ctl {
S(q);
// alternatively Rz(0.5 * PI(), q);
// alternatively R1(0.5 * PI(), q);
}


Expand All @@ -77,15 +77,15 @@ namespace Quantum.Kata.BasicGates {
// If the qubit is in state |0⟩, don't change its state.
// If the qubit is in state |1⟩, change its state to exp(i*alpha)|1⟩.
// If the qubit is in superposition, change its state according to the effect on basis vectors.
operation PhaseChange_Reference (alpha : Double, q : Qubit) : Unit is Adj {
operation PhaseChange_Reference (alpha : Double, q : Qubit) : Unit is Adj+Ctl {
R1(alpha, q);
}


// Task 1.7. Bell state change - 1
// Input: Two entangled qubits in Bell state |Φ⁺⟩ = (|00⟩ + |11⟩) / sqrt(2).
// Goal: Change the two-qubit state to |Φ⁻⟩ = (|00⟩ - |11⟩) / sqrt(2).
operation BellStateChange1_Reference (qs : Qubit[]) : Unit is Adj {
operation BellStateChange1_Reference (qs : Qubit[]) : Unit is Adj+Ctl {
Z(qs[0]);
// alternatively Z(qs[1]);
}
Expand All @@ -94,7 +94,7 @@ namespace Quantum.Kata.BasicGates {
// Task 1.8. Bell state change - 2
// Input: Two entangled qubits in Bell state |Φ⁺⟩ = (|00⟩ + |11⟩) / sqrt(2).
// Goal: Change the two-qubit state to |Ψ⁺⟩ = (|01⟩ + |10⟩) / sqrt(2).
operation BellStateChange2_Reference (qs : Qubit[]) : Unit is Adj {
operation BellStateChange2_Reference (qs : Qubit[]) : Unit is Adj+Ctl {
X(qs[0]);
// alternatively X(qs[1]);
}
Expand All @@ -103,8 +103,10 @@ namespace Quantum.Kata.BasicGates {
// Task 1.9. Bell state change - 3
// Input: Two entangled qubits in Bell state |Φ⁺⟩ = (|00⟩ + |11⟩) / sqrt(2).
// Goal: Change the two-qubit state to |Ψ⁻⟩ = (|01⟩ - |10⟩) / sqrt(2).
operation BellStateChange3_Reference (qs : Qubit[]) : Unit is Adj {
Y(qs[0]);
operation BellStateChange3_Reference (qs : Qubit[]) : Unit is Adj+Ctl {
X(qs[0]);
Z(qs[0]);
// note that this is not equivalent to Y(qs[0]), since Y gate adds an extra global phase
}


Expand Down
27 changes: 16 additions & 11 deletions BasicGates/Tasks.qs
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,12 @@ namespace Quantum.Kata.BasicGates {
// Part I. Single-Qubit Gates
//////////////////////////////////////////////////////////////////

// Note that all operations in this section have `is Adj+Ctl` in their signature.
// This means that they should be implemented in a way that allows Q#
// to compute their adjoint and controlled variants automatically.
// Since each task is solved using only intrinsic gates, you should not need to put any special effort in this.


// Task 1.1. State flip: |0⟩ to |1⟩ and vice versa
// Input: A qubit in state |ψ⟩ = α |0⟩ + β |1⟩.
// Goal: Change the state of the qubit to α |1⟩ + β |0⟩.
Expand All @@ -40,16 +46,15 @@ namespace Quantum.Kata.BasicGates {
// If the qubit is in state |1⟩, change its state to |0⟩.
// Note that this operation is self-adjoint: applying it for a second time
// returns the qubit to the original state.
// `is Adj` at the end of the operation signature means that Q# will compute
// the operation that returns the qubit to the original state automatically.
operation StateFlip (q : Qubit) : Unit is Adj {
operation StateFlip (q : Qubit) : Unit is Adj+Ctl {
// The Pauli X gate will change the |0⟩ state to the |1⟩ state and vice versa.
// Type X(q);
// Then rebuild the project and rerun the tests - T11_StateFlip_Test should now pass!

// ...
}


// Task 1.2. Basis change: |0⟩ to |+⟩ and |1⟩ to |-⟩ (and vice versa)
// Input: A qubit in state |ψ⟩ = α |0⟩ + β |1⟩.
// Goal: Change the state of the qubit as follows:
Expand All @@ -58,15 +63,15 @@ namespace Quantum.Kata.BasicGates {
// If the qubit is in superposition, change its state according to the effect on basis vectors.
// Note: |+⟩ and |-⟩ form a different basis for single-qubit states, called X basis.
// |0⟩ and |1⟩ are called Z basis.
operation BasisChange (q : Qubit) : Unit is Adj {
operation BasisChange (q : Qubit) : Unit is Adj+Ctl {
// ...
}


// Task 1.3. Sign flip: |+⟩ to |-⟩ and vice versa.
// Input: A qubit in state |ψ⟩ = α |0⟩ + β |1⟩.
// Goal: Change the qubit state to α |0⟩ - β |1⟩ (flip the sign of |1⟩ component of the superposition).
operation SignFlip (q : Qubit) : Unit is Adj {
operation SignFlip (q : Qubit) : Unit is Adj+Ctl {
// ...
}

Expand All @@ -81,15 +86,15 @@ namespace Quantum.Kata.BasicGates {
// If the qubit is in superposition, change its state according to the effect on basis vectors.
// This is the first operation in this kata that is not self-adjoint,
// i.e., applying it for a second time does not return the qubit to the original state.
operation AmplitudeChange (alpha : Double, q : Qubit) : Unit is Adj {
operation AmplitudeChange (alpha : Double, q : Qubit) : Unit is Adj+Ctl {
// ...
}


// Task 1.5. Phase flip
// Input: A qubit in state |ψ⟩ = α |0⟩ + β |1⟩.
// Goal: Change the qubit state to α |0⟩ + iβ |1⟩ (flip the phase of |1⟩ component of the superposition).
operation PhaseFlip (q : Qubit) : Unit is Adj {
operation PhaseFlip (q : Qubit) : Unit is Adj+Ctl {
// ...
}

Expand All @@ -102,31 +107,31 @@ namespace Quantum.Kata.BasicGates {
// If the qubit is in state |0⟩, don't change its state.
// If the qubit is in state |1⟩, change its state to exp(i*alpha)|1⟩.
// If the qubit is in superposition, change its state according to the effect on basis vectors.
operation PhaseChange (alpha : Double, q : Qubit) : Unit is Adj {
operation PhaseChange (alpha : Double, q : Qubit) : Unit is Adj+Ctl {
// ...
}


// Task 1.7. Bell state change - 1
// Input: Two entangled qubits in Bell state |Φ⁺⟩ = (|00⟩ + |11⟩) / sqrt(2).
// Goal: Change the two-qubit state to |Φ⁻⟩ = (|00⟩ - |11⟩) / sqrt(2).
operation BellStateChange1 (qs : Qubit[]) : Unit is Adj {
operation BellStateChange1 (qs : Qubit[]) : Unit is Adj+Ctl {
// ...
}


// Task 1.8. Bell state change - 2
// Input: Two entangled qubits in Bell state |Φ⁺⟩ = (|00⟩ + |11⟩) / sqrt(2).
// Goal: Change the two-qubit state to |Ψ⁺⟩ = (|01⟩ + |10⟩) / sqrt(2).
operation BellStateChange2 (qs : Qubit[]) : Unit is Adj {
operation BellStateChange2 (qs : Qubit[]) : Unit is Adj+Ctl {
// ...
}


// Task 1.9. Bell state change - 3
// Input: Two entangled qubits in Bell state |Φ⁺⟩ = (|00⟩ + |11⟩) / sqrt(2).
// Goal: Change the two-qubit state to |Ψ⁻⟩ = (|01⟩ - |10⟩) / sqrt(2).
operation BellStateChange3 (qs : Qubit[]) : Unit is Adj {
operation BellStateChange3 (qs : Qubit[]) : Unit is Adj+Ctl {
// ...
}

Expand Down
Loading