-
Notifications
You must be signed in to change notification settings - Fork 86
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Superdense coding kata finish (#1479)
Part of #1185. Changes Done: - Revamped Task 1: Using `qAlice` and `qBob` for better clarity. Replaced `\rangle` with `\ket` - Added tasks 2-4. - Using a tuple of boolean variables instead of `ProtocolMessage` to improve learner and developer productivity. --------- Co-authored-by: Mariia Mykhailova <[email protected]>
- Loading branch information
1 parent
aeea75f
commit 3897cea
Showing
23 changed files
with
352 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,75 @@ | ||
namespace Kata.Verification { | ||
operation CreateEntangledPairWrapper_Reference(qs : Qubit[]) : Unit is Adj + Ctl { | ||
let (qAlice, qBob) = (qs[0], qs[1]); | ||
H(qAlice); | ||
CNOT(qAlice, qBob); | ||
} | ||
|
||
operation EncodeMessageInQubit_Reference(qAlice : Qubit, message : (Bool, Bool)) : Unit { | ||
let (bit1, bit2) = message; | ||
|
||
if bit1 { | ||
Z(qAlice); | ||
} | ||
|
||
if bit2 { | ||
X(qAlice); | ||
} | ||
} | ||
|
||
operation DecodeMessageFromQubits_Reference(qAlice : Qubit, qBob : Qubit) : (Bool, Bool) { | ||
CNOT(qAlice, qBob); | ||
H(qAlice); | ||
return (MResetZ(qAlice) == One, MResetZ(qBob) == One); | ||
} | ||
|
||
|
||
// ------------------------------------------------------ | ||
// Helper operation that runs superdense coding protocol using two building blocks | ||
// specified as first two parameters. | ||
operation ComposeProtocol( | ||
encodeOp : ((Qubit, (Bool, Bool)) => Unit), | ||
decodeOp : ((Qubit, Qubit) => (Bool, Bool)), | ||
message : (Bool, Bool) | ||
) : (Bool, Bool) { | ||
|
||
use (qAlice, qBob) = (Qubit(), Qubit()); | ||
|
||
CreateEntangledPairWrapper_Reference([qAlice, qBob]); | ||
|
||
encodeOp(qAlice, message); | ||
|
||
let (bit1, bit2) = decodeOp(qAlice, qBob); | ||
|
||
ResetAll([qAlice, qBob]); | ||
|
||
return (bit1, bit2); | ||
} | ||
|
||
// ------------------------------------------------------ | ||
// Helper operation that runs superdense coding protocol (specified by protocolOp) | ||
// on all possible input values and verifies that decoding result matches the inputs | ||
operation CheckProtocolWithFeedback(protocolOp : ((Bool, Bool) => (Bool, Bool))) : Bool { | ||
|
||
// Loop over the 4 possible combinations of two bits | ||
for n in 0..3 { | ||
let data = (1 == n / 2, 1 == n % 2); | ||
let (dataBit1, dataBit2) = data; | ||
|
||
for iter in 1..100 { | ||
let (bit1, bit2) = protocolOp(data); | ||
|
||
// Now test if the bits were transfered correctly. | ||
if not (bit1 == dataBit1 and bit2 == dataBit2) { | ||
Message("Incorrect."); | ||
Message($"({dataBit1}, {dataBit2}) was transfered incorrectly as ({bit1}, {bit2})"); | ||
return false; | ||
} | ||
} | ||
} | ||
|
||
Message("Correct!"); | ||
return true; | ||
} | ||
|
||
} |
9 changes: 9 additions & 0 deletions
9
katas/content/superdense_coding/alice_sends_message/Placeholder.qs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
namespace Kata { | ||
operation EncodeMessageInQubit(qAlice : Qubit, message : (Bool, Bool)) : Unit { | ||
// Get the bits from the message | ||
let (bit1, bit2) = message; | ||
|
||
// Implement your solution here... | ||
|
||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
katas/content/superdense_coding/alice_sends_message/Solution.qs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
namespace Kata { | ||
operation EncodeMessageInQubit(qAlice : Qubit, message : (Bool, Bool)) : Unit { | ||
let (bit1, bit2) = message; | ||
|
||
if bit2 { | ||
X(qAlice); | ||
} | ||
|
||
if bit1 { | ||
Z(qAlice); | ||
} | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
katas/content/superdense_coding/alice_sends_message/Verification.qs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace Kata.Verification { | ||
@EntryPoint() | ||
operation CheckSolution() : Bool { | ||
return CheckProtocolWithFeedback(ComposeProtocol(Kata.EncodeMessageInQubit, DecodeMessageFromQubits_Reference, _)); | ||
} | ||
|
||
} |
16 changes: 16 additions & 0 deletions
16
katas/content/superdense_coding/alice_sends_message/index.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
**Inputs**: | ||
|
||
1. `qAlice` : Alice's part of the entangled pair of qubits. | ||
2. `message`: Two classical bits represented by a tuple of of two `Bool` variables to represent `bit1` and `bit2` respectively. | ||
|
||
**Goal**: | ||
Encode the message (two classical bits) by manipulating Alice's qubit. | ||
|
||
Superdense coding protocol changes the joint state of the two qubits to one of the following four states based on the value of message: | ||
|
||
- `(0, 0)`: $\ket{\Phi^{+}} = \frac{1}{\sqrt{2}} (\ket{00} + \ket{11})$ | ||
- `(0, 1)`: $\ket{\Psi^{+}} = \frac{1}{\sqrt{2}} (\ket{01} + \ket{10})$ | ||
- `(1, 0)`: $\ket{\Phi^{-}} = \frac{1}{\sqrt{2}} (\ket{00} - \ket{11})$ | ||
- `(1, 1)`: $\ket{\Psi^{-}} = \frac{1}{\sqrt{2}} (\ket{01} - \ket{10})$ | ||
|
||
Note that your solution is tested as part of an end-to-end implementation of the protocol; the goal is to get the message transmitted correctly. |
35 changes: 35 additions & 0 deletions
35
katas/content/superdense_coding/alice_sends_message/solution.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
Recall that we learnt how to prepare all Bell states in "Preparing Quantum States" kata. This is slightly advanced version of that task demonstrating how operations applied to one qubit of a Bell state allow us to transform it into any other Bell state. | ||
|
||
Superdense coding protocol uses the below Bell state we prepared in the previous task: | ||
|
||
$$\frac{1}{\sqrt{2}} \big(\ket{00} + \ket{11} \big)$$ | ||
|
||
We can transform it into every other Bell state according to the value of `message`: | ||
|
||
- `(0, 0)`: $\ket{\Phi^{+}} = \frac{1}{\sqrt{2}} (\ket{00} + \ket{11})$ | ||
- `(0, 1)`: $\ket{\Psi^{+}} = \frac{1}{\sqrt{2}} (\ket{01} + \ket{10})$ | ||
- `(1, 0)`: $\ket{\Phi^{-}} = \frac{1}{\sqrt{2}} (\ket{00} - \ket{11})$ | ||
- `(1, 1)`: $\ket{\Psi^{-}} = \frac{1}{\sqrt{2}} (\ket{01} - \ket{10})$ | ||
|
||
Here is how we can perform this transformation: | ||
|
||
- If `bits == (0, 0)`, we do nothing - the prepared state is already $\ket{\Phi^{+}}$. | ||
|
||
- If `bits == (0, 1)`, we need to change the second qubit in both $\ket{00}$ and $\ket{11}$ terms. Observe that applying an $X$ gate to Alice's qubit does exactly that: | ||
$$(X \otimes I) \ket{\Phi^{+}} = \frac{1}{\sqrt{2}} (\ket{10} + \ket{01})$$ | ||
|
||
- If `bits == (1, 0)`, we need to add a relative phase of $-1$ to the $\ket{11}$ term. Observe that applying $Z$ gate to Alice's qubit does exactly that: | ||
$$(Z \otimes I) \ket{\Phi^{+}} = \frac{1}{\sqrt{2}} (\ket{00} - \ket{11})$$ | ||
|
||
- If `bits = (1, 1)`, we use the same logic to realize that we need to apply both the $Z$ and $X$ corrections to get $\ket{\Psi^{-}}$ state. | ||
$$ (Z \otimes I) \cdot (X \otimes I) \ket{\Psi^{+}} = (Z \otimes I) \frac{1}{\sqrt{2}} (\ket{10} + \ket{01}) = \frac{1}{\sqrt{2}} (-\ket{10} + \ket{01}) = \frac{1}{\sqrt{2}} (\ket{01} - \ket{10}) $$ | ||
|
||
The final sequence of steps is as follows: | ||
|
||
1. Apply the $X$ gate to Alice's qubit if `bit2 == 1`. | ||
2. Apply the $Z$ gate to Alice's qubit if `bit1 == 1`. | ||
|
||
@[solution]({ | ||
"id": "superdense_coding__alice_sends_message_solution", | ||
"codePath": "./Solution.qs" | ||
}) |
7 changes: 7 additions & 0 deletions
7
katas/content/superdense_coding/bob_decodes_message/Placeholder.qs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace Kata { | ||
operation DecodeMessageFromQubits(qAlice : Qubit, qBob : Qubit) : (Bool, Bool) { | ||
// Implement your solution here... | ||
|
||
return (false, false); | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
katas/content/superdense_coding/bob_decodes_message/Solution.qs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace Kata { | ||
operation DecodeMessageFromQubits(qAlice : Qubit, qBob : Qubit) : (Bool, Bool) { | ||
CNOT(qAlice, qBob); | ||
H(qAlice); | ||
return (MResetZ(qAlice) == One, MResetZ(qBob) == One); | ||
} | ||
} |
7 changes: 7 additions & 0 deletions
7
katas/content/superdense_coding/bob_decodes_message/Verification.qs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,7 @@ | ||
namespace Kata.Verification { | ||
@EntryPoint() | ||
operation CheckSolution() : Bool { | ||
return CheckProtocolWithFeedback(ComposeProtocol(EncodeMessageInQubit_Reference, Kata.DecodeMessageFromQubits, _)); | ||
} | ||
} | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,8 @@ | ||
**Inputs:** | ||
|
||
1. `qAlice` : Qubit received from Alice. | ||
2. `qBob` : Bob's part of the entangled pair. | ||
|
||
**Goal** : Decode the message using the qubit received from Alice. For this, retrieve two bits of classic data from the qubits and return a tuple of the form `(Bool, Bool)` to represent `message`. The state of the qubits in the end of the operation does not matter. | ||
|
||
Note that your solution is tested as part of an end-to-end implementation of the protocol; the goal is to get the message transmitted correctly. |
22 changes: 22 additions & 0 deletions
22
katas/content/superdense_coding/bob_decodes_message/solution.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
Recall that Alice encoded qubits as follows: | ||
|
||
- `(0, 0)`: $\ket{\Phi^{+}} = \frac{1}{\sqrt{2}} (\ket{00} + \ket{11})$ | ||
- `(0, 1)`: $\ket{\Psi^{+}} = \frac{1}{\sqrt{2}} (\ket{01} + \ket{10})$ | ||
- `(1, 0)`: $\ket{\Phi^{-}} = \frac{1}{\sqrt{2}} (\ket{00} - \ket{11})$ | ||
- `(1, 1)`: $\ket{\Psi^{-}} = \frac{1}{\sqrt{2}} (\ket{01} - \ket{10})$ | ||
|
||
To read out the encoded message, Bob needs to figure out which of the four Bell states he has. We can map the Bell states to basis states by applying a $CNOT$ gate with the first qubit as control and the second qubit as target, followed by an $H$ gate on the first qubit. (Notice that this is exactly what [`Adjoint`](https://learn.microsoft.com/azure/quantum/user-guide/language/expressions/functorapplication#adjoint-functor) of the state preparation operation in the first task does.) | ||
|
||
What is the outcome of this transformation, assuming each of the possible quantum states after the encoding step? | ||
|
||
- $\ket{\Phi^{+}} = \frac{1}{\sqrt{2}} (\ket{00} + \ket{11}) \rightarrow \ket{00}$ | ||
- $\ket{\Psi^{+}} = \frac{1}{\sqrt{2}} (\ket{01} + \ket{10}) \rightarrow \ket{01}$ | ||
- $\ket{\Phi^{-}} = \frac{1}{\sqrt{2}} (\ket{00} - \ket{11}) \rightarrow \ket{10}$ | ||
- $\ket{\Psi^{-}} = \frac{1}{\sqrt{2}} (\ket{01} - \ket{10}) \rightarrow \ket{11}$ | ||
|
||
Hence, we can retrieve the encoded bits just by measuring the bits. | ||
|
||
@[solution]({ | ||
"id": "superdense_coding__bob_decodes_message_solution", | ||
"codePath": "./Solution.qs" | ||
}) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
namespace Kata { | ||
operation CreateEntangledPair(qs : Qubit[]) : Unit is Adj { | ||
H(qs[0]); | ||
CNOT(qs[0], qs[1]); | ||
operation CreateEntangledPair(qAlice : Qubit, qBob : Qubit) : Unit is Adj { | ||
H(qAlice); | ||
CNOT(qAlice, qBob); | ||
} | ||
} |
9 changes: 4 additions & 5 deletions
9
katas/content/superdense_coding/entangled_pair/Verification.qs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,6 @@ | ||
**Input:** Two qubits in the $|00\rangle$ state (stored in an array of length 2). | ||
**Inputs:** | ||
|
||
**Goal:** Prepare a Bell state $|\Phi^{+}\rangle = \frac{1}{\sqrt{2}} (|00\rangle + |11\rangle)$ on these qubits. | ||
1. `qAlice` : Alice's qubit in $\ket{0}$ state. | ||
2. `qBob` : Bob's qubit in $\ket{0}$ state. | ||
|
||
**Goal:** Prepare a Bell state $|\Phi^{+}\rangle = \frac{1}{\sqrt{2}} (\ket{00} + \ket{11})$ on these qubits. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
31 changes: 31 additions & 0 deletions
31
katas/content/superdense_coding/protocol_e2e/Placeholder.qs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,31 @@ | ||
namespace Kata { | ||
operation SuperdenseCodingProtocol(message : (Bool, Bool)) : (Bool, Bool) { | ||
// Implement your solution here... | ||
|
||
return (false, false); | ||
} | ||
|
||
// You might find these helper operations from earlier tasks useful. | ||
operation CreateEntangledPair(qAlice : Qubit, qBob : Qubit) : Unit is Adj { | ||
H(qAlice); | ||
CNOT(qAlice, qBob); | ||
} | ||
|
||
operation EncodeMessageInQubit(qAlice : Qubit, message : (Bool, Bool)) : Unit { | ||
let (bit1, bit2) = message; | ||
|
||
if bit2 { | ||
X(qAlice); | ||
} | ||
|
||
if bit1 { | ||
Z(qAlice); | ||
} | ||
} | ||
|
||
operation DecodeMessageFromQubits(qAlice : Qubit, qBob : Qubit) : (Bool, Bool) { | ||
CNOT(qAlice, qBob); | ||
H(qAlice); | ||
return (MResetZ(qAlice) == One, MResetZ(qBob) == One); | ||
} | ||
} |
Oops, something went wrong.