Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Teleportation Task 1.2-1.4 added #1556

Merged
merged 5 commits into from
May 31, 2024
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
118 changes: 118 additions & 0 deletions katas/content/teleportation/Common.qs
Original file line number Diff line number Diff line change
@@ -1,7 +1,125 @@
namespace Kata.Verification {
open Microsoft.Quantum.Diagnostics;
open Microsoft.Quantum.Math;

operation EntangleWrapper_Reference(qs : Qubit[]) : Unit is Adj + Ctl {
let (qAlice, qBob) = (qs[0], qs[1]);
H(qAlice);
CNOT(qAlice, qBob);
}

// ------------------------------------------------------
// Helper which prepares proper Bell state on two qubits
// 0 - |Φ⁺⟩ = (|00⟩ + |11⟩) / sqrt(2)
// 1 - |Φ⁻⟩ = (|00⟩ - |11⟩) / sqrt(2)
// 2 - |Ψ⁺⟩ = (|01⟩ + |10⟩) / sqrt(2)
// 3 - |Ψ⁻⟩ = (|01⟩ - |10⟩) / sqrt(2)
operation StatePrep_BellState(q1 : Qubit, q2 : Qubit, state : Int) : Unit {
H(q1);
CNOT(q1, q2);

// now we have |00⟩ + |11⟩ - modify it based on state arg
if state % 2 == 1 {
// negative phase
Z(q2);
}

if state / 2 == 1 {
X(q2);
}
}

// ------------------------------------------------------
// Helper operation that run teleportation using the given operations to prepare the message qubit
// and the entangled pair, and to run sender and receiver parts of the protocol.
operation ComposeTeleportation(
bellPrepOp : ((Qubit, Qubit) => Unit),
getDescriptionOp : ((Qubit, Qubit) => (Bool, Bool)),
reconstructOp : ((Qubit, (Bool, Bool)) => Unit),
qAlice : Qubit,
qBob : Qubit,
qMessage : Qubit) : Unit {

bellPrepOp(qAlice, qBob);
let classicalBits = getDescriptionOp(qAlice, qMessage);

// Alice sends the classical bits to Bob.
// Bob uses these bits to transform his part of the entangled pair into the message.
reconstructOp(qBob, classicalBits);
}

operation SendMessage_Reference(qAlice: Qubit, qMessage: Qubit) : (Bool, Bool) {
CNOT(qMessage, qAlice);
H(qMessage);
return (M(qMessage) == One, M(qAlice) == One);
}

operation ReconstructMessage_Reference(qBob : Qubit, (b1 : Bool, b2 : Bool)) : Unit {
if b1 {
Z(qBob);
}
if b2 {
X(qBob);
}
}

// ------------------------------------------------------
// Helper operation that runs a teleportation operation (specified by teleportOp).
// The state to teleport is set up using an operation (specified by setupPsiOp).
//
// Specifying the state to teleport through an operation allows to get the inverse
// which makes testing easier.
operation TeleportTestHelper(
teleportOp : ((Qubit, Qubit, Qubit) => Unit),
setupPsiOp : (Qubit => Unit is Adj),
psiName: String) : Bool {

use (qMessage, qAlice, qBob) = (Qubit(), Qubit(), Qubit());
setupPsiOp(qMessage);

// This should modify qBob to be identical to the state
// of qMessage before the function call.
teleportOp(qAlice, qBob, qMessage);

// Applying the inverse of the setup operation to qBob
// should make it Zero.
Adjoint setupPsiOp(qBob);
if not CheckZero(qBob) {
Message($"Incorrect. The state {psiName} was teleported incorrectly.");
setupPsiOp(qBob);
Message("The state of the qubits [qMessage, qAlice, qBob] after teleportation:");
DumpMachine();
tcNickolas marked this conversation as resolved.
Show resolved Hide resolved
ResetAll([qMessage, qAlice, qBob]);
return false;
}
ResetAll([qMessage, qAlice, qBob]);
return true;
}

// ------------------------------------------------------
// Run teleportation for a number of different states.
// After each teleportation success is asserted.
// Also repeats for each state several times as
// code is expected to take different paths each time because
// measurements done by Alice are not deterministic.
operation TeleportTestLoop(teleportOp : ((Qubit, Qubit, Qubit) => Unit)) : Bool {
// Define setup operations for the message qubit
// on which to test teleportation: |0⟩, |1⟩, |0⟩ + |1⟩, unequal superposition.
let setupPsiOps = [(I, "|0⟩"), (X, "|1⟩"), (H, "|+⟩"), (Ry(ArcCos(0.6) * 2.0, _), "0.6|0⟩ + 0.8|1⟩")];

// As part of teleportation Alice runs some measurements
// with nondeterministic outcome.
// Depending on the outcomes different paths are taken on Bob's side.
// We repeat each test run several times to ensure that all paths are checked.
let numRepetitions = 100;
for (psiOp, psiName) in setupPsiOps {
for j in 1 .. numRepetitions {
if not TeleportTestHelper(teleportOp, psiOp, psiName) {
return false;
}
}
}
Message("Correct.");
return true;
}
}
30 changes: 30 additions & 0 deletions katas/content/teleportation/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,3 +33,33 @@ We split the teleportation protocol into several steps:
"./Common.qs"
]
})

@[exercise]({
"id": "teleportation__send_message",
"title": "Send Message (Alice's Task)",
"path": "./send_message/",
"qsDependencies": [
"../KatasLibrary.qs",
"./Common.qs"
]
})

@[exercise]({
"id": "teleportation__reconstruct_message",
"title": "Reconstruct Message (Bob's Task)",
"path": "./reconstruct_message/",
"qsDependencies": [
"../KatasLibrary.qs",
"./Common.qs"
]
})

@[exercise]({
"id": "teleportation__standard_teleportation_protocol",
"title": "Standard Teleportation Protocol",
"path": "./standard_teleportation_protocol/",
"qsDependencies": [
"../KatasLibrary.qs",
"./Common.qs"
]
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
namespace Kata {
operation ReconstructMessage(qBob : Qubit, (b1 : Bool, b2 : Bool)) : Unit {
// Implement your solution here...
}
}
10 changes: 10 additions & 0 deletions katas/content/teleportation/reconstruct_message/Solution.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Kata {
operation ReconstructMessage(qBob : Qubit, (b1 : Bool, b2 : Bool)) : Unit {
if b1 {
Z(qBob);
}
if b2 {
X(qBob);
}
}
}
10 changes: 10 additions & 0 deletions katas/content/teleportation/reconstruct_message/Verification.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Kata.Verification {
open Microsoft.Quantum.Diagnostics;
open Microsoft.Quantum.Katas;

@EntryPoint()
operation CheckSolution() : Bool {
let teleport = ComposeTeleportation(StatePrep_BellState(_, _, 0), SendMessage_Reference, Kata.ReconstructMessage, _, _, _);
return TeleportTestLoop(teleport);
}
}
8 changes: 8 additions & 0 deletions katas/content/teleportation/reconstruct_message/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Transform Bob's qubit into the required state using the two classical bits received from Alice.

**Inputs:**
1. Bob's part of the entangled pair of qubits `qBob`.
2. The tuple of classical bits received from Alice, in the format used in previous exercise.

**Goal:**
Transform Bob's qubit `qBob` into the state in which the message qubit had been originally.
10 changes: 10 additions & 0 deletions katas/content/teleportation/reconstruct_message/solution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Bob's qubit now contains the information about the amplitudes of the teleported state, but it needs correction based on the classical message received for his qubit to match the teleported state precisely:
- For 00, no change is required.
- For 01, only Z correction is required.
- For 10, only X correction is required.
- For 11, both Z and X correction is requried.

@[solution]({
"id": "teleportation__reconstruct_the_message_solution",
"codePath": "./Solution.qs"
})
6 changes: 6 additions & 0 deletions katas/content/teleportation/send_message/Placeholder.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
namespace Kata {
operation SendMessage(qAlice : Qubit, qMessage : Qubit) : (Bool, Bool) {
// Implement your solution here...
return (false, false);
}
}
7 changes: 7 additions & 0 deletions katas/content/teleportation/send_message/Solution.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace Kata {
operation SendMessage(qAlice : Qubit, qMessage : Qubit) : (Bool, Bool) {
CNOT(qMessage, qAlice);
H(qMessage);
return (M(qMessage) == One, M(qAlice) == One);
}
}
10 changes: 10 additions & 0 deletions katas/content/teleportation/send_message/Verification.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Kata.Verification {
open Microsoft.Quantum.Diagnostics;
open Microsoft.Quantum.Katas;

@EntryPoint()
operation CheckSolution() : Bool {
let teleport = ComposeTeleportation(StatePrep_BellState(_, _, 0), Kata.SendMessage, ReconstructMessage_Reference, _, _, _);
return TeleportTestLoop(teleport);
}
}
8 changes: 8 additions & 0 deletions katas/content/teleportation/send_message/index.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Entangle the message qubit with Alice's qubit and extract two classical bits to be sent to Bob.

**Inputs:**
1. Alice's part of the entangled pair of qubits `qAlice`.
2. The message qubit `qMessage`.

**Output:**
Two classical bits Alice will send to Bob via classical channel as a tuple of Boolean values. The first bit in the tuple should hold the result of measurement of the message qubit, the second bit - the result of measurement of Alice's qubit. Represent measurement result `One` as `true` and `Zero` as `false`. The state of the qubits in the end of the operation doesn't matter.
9 changes: 9 additions & 0 deletions katas/content/teleportation/send_message/solution.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
Requirement is to perform measurement in bell state:
- Apply $CNOT$ with $qMessage$ as control qubit
- Apply Hadamard on $qMessage$ qubit
- Measure both the qubits and report in boolean format

@[solution]({
"id": "teleportation__send_the_message_solution",
"codePath": "./Solution.qs"
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
namespace Kata {
operation StandardTeleport(qAlice : Qubit, qBob : Qubit, qMessage : Qubit) : Unit {
// Implement your solution here...
}

// You might find these helper operations from earlier tasks useful.
operation Entangle(qAlice : Qubit, qBob : Qubit) : Unit is Adj + Ctl {
H(qAlice);
CNOT(qAlice, qBob);
}

operation SendMessage(qAlice: Qubit, qMessage: Qubit) : (Bool, Bool) {
CNOT(qMessage, qAlice);
H(qMessage);
return (M(qMessage) == One, M(qAlice) == One);
}

operation ReconstructMessage(qBob : Qubit, (b1 : Bool, b2 : Bool)) : Unit {
if b1 {
Z(qBob);
}
if b2 {
X(qBob);
}
}
}
devikamehra marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
namespace Kata {
operation StandardTeleport(qAlice : Qubit, qBob : Qubit, qMessage : Qubit) : Unit {
Entangle(qAlice, qBob);
let classicalBits = SendMessage(qAlice, qMessage);
ReconstructMessage(qBob, classicalBits);
}

operation Entangle(qAlice : Qubit, qBob : Qubit) : Unit is Adj + Ctl {
H(qAlice);
CNOT(qAlice, qBob);
}

operation SendMessage(qAlice: Qubit, qMessage: Qubit) : (Bool, Bool) {
CNOT(qMessage, qAlice);
H(qMessage);
return (M(qMessage) == One, M(qAlice) == One);
}

operation ReconstructMessage(qBob : Qubit, (b1 : Bool, b2 : Bool)) : Unit {
if b1 {
Z(qBob);
}
if b2 {
X(qBob);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Kata.Verification {
open Microsoft.Quantum.Katas;

@EntryPoint()
operation CheckSolution() : Bool {
let teleport = Kata.StandardTeleport;
return TeleportTestLoop(teleport);
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
Put together the steps implemented in previous three exercises to implement the full teleportation protocol.

**Inputs:**
1. The two qubits `qAlice` and `qBob` in $\ket{0}$ state.
2. The message qubit `qMessage` in the state $\ket{\psi}$ to be teleported.

**Goal:**
Transform Bob's qubit `qBob` into the state $\ket{\psi}$. The state of the qubits `qAlice` and `qMessage` in the end of the operation doesn't matter.
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
Combine solutions of all three exercises in the correct order

- Entangle qubits of Alice and Bob
- Send the message using Alice's qubit and message qubit
- Based on the message qubit, reconstruct the state of Bob's qubit

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