Create Teleportation kata (#12)
This commit is contained in:
Родитель
48508c5c22
Коммит
3bb9e21043
|
@ -0,0 +1,7 @@
|
|||
{
|
||||
// See http://go.microsoft.com/fwlink/?LinkId=827846
|
||||
// for the documentation about the extensions.json format
|
||||
"recommendations": [
|
||||
"quantum.quantum-devkit-vscode"
|
||||
]
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
{
|
||||
"csharp.suppressDotnetRestoreNotification": true
|
||||
}
|
|
@ -0,0 +1,36 @@
|
|||
{
|
||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||
// for the documentation about the tasks.json format
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"label": "build",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build"
|
||||
],
|
||||
"type": "process",
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"reveal": "silent"
|
||||
},
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "test",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"test"
|
||||
],
|
||||
"type": "process",
|
||||
"group": "test",
|
||||
"presentation": {
|
||||
"echo": true,
|
||||
"reveal": "always",
|
||||
"focus": false,
|
||||
"panel": "shared"
|
||||
},
|
||||
"problemMatcher": "$msCompile"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -0,0 +1,9 @@
|
|||
# Welcome!
|
||||
|
||||
The teleportation kata covers quantum teleportation - a protocol which allows to communicate a quantum state
|
||||
using only classical communication and previously shared quantum entanglement.
|
||||
|
||||
- Teleportation is described as an example in [the Q# documentation](https://docs.microsoft.com/en-us/quantum/quantum-techniques-6-puttingitalltogether).
|
||||
- Another description can be found in [the Wikipedia article](https://en.wikipedia.org/wiki/Quantum_teleportation).
|
||||
|
||||
The principle of deferred measurement, applied to teleportation protocol, is described in Nielsen & Chuang, section 4.4 (pp. 185-187).
|
|
@ -0,0 +1,113 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// This file contains reference solutions to all tasks.
|
||||
// The tasks themselves can be found in Tasks.qs file.
|
||||
// but feel free to look up the solution if you get stuck.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace Quantum.Kata.Teleportation
|
||||
{
|
||||
open Microsoft.Quantum.Primitive;
|
||||
open Microsoft.Quantum.Canon;
|
||||
open Microsoft.Quantum.Extensions.Convert;
|
||||
open Microsoft.Quantum.Extensions.Math;
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Part I. Standard teleportation
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// Task 1.1. Entangled pair
|
||||
operation Entangle_Reference (qAlice : Qubit, qBob : Qubit) : ()
|
||||
{
|
||||
body {
|
||||
H(qAlice);
|
||||
CNOT(qAlice, qBob);
|
||||
}
|
||||
adjoint auto;
|
||||
}
|
||||
|
||||
// Task 1.2. Send the message (Alice's task)
|
||||
operation SendMessage_Reference (qAlice : Qubit, qMessage : Qubit) : (Bool, Bool)
|
||||
{
|
||||
body {
|
||||
CNOT(qMessage, qAlice);
|
||||
H(qMessage);
|
||||
return (M(qMessage) == One, M(qAlice) == One);
|
||||
}
|
||||
}
|
||||
|
||||
// Task 1.3. Reconstruct the message (Bob's task)
|
||||
operation ReconstructMessage_Reference (qBob : Qubit, (b1 : Bool, b2 : Bool)) : ()
|
||||
{
|
||||
body {
|
||||
if (b1) { Z(qBob); }
|
||||
if (b2) { X(qBob); }
|
||||
}
|
||||
}
|
||||
|
||||
// Task 1.4. Standard teleportation protocol
|
||||
operation StandardTeleport_Reference (qAlice : Qubit, qBob : Qubit, qMessage : Qubit):()
|
||||
{
|
||||
body{
|
||||
Entangle_Reference(qAlice, qBob);
|
||||
let classicalBits = SendMessage_Reference(qAlice, qMessage);
|
||||
|
||||
// Alice sends the classical bits to Bob.
|
||||
// Bob uses these bits to transform his part of the entangled pair into |ψ⟩.
|
||||
ReconstructMessage_Reference(qBob, classicalBits);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Part II. Teleportation using different entangled pair
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// Task 2.1. Reconstruct the message if the entangled qubits were in the state |Φ⁻⟩ = (|00⟩ - |11⟩) / sqrt(2).
|
||||
operation ReconstructMessage_PhiMinus_Reference (qBob : Qubit, (b1 : Bool, b2 : Bool)) : ()
|
||||
{
|
||||
body {
|
||||
// Bob can apply a Z gate to his qubit to convert the pair to |Φ⁺⟩
|
||||
// and use the standard teleportation reconstruction process.
|
||||
if (!b1) { Z(qBob); }
|
||||
if (b2) { X(qBob); }
|
||||
}
|
||||
}
|
||||
|
||||
// Task 2.2. Reconstruct the message if the entangled qubits were in the state |Ψ⁺⟩ = (|01⟩ + |10⟩) / sqrt(2).
|
||||
operation ReconstructMessage_PsiPlus_Reference (qBob : Qubit, (b1 : Bool, b2 : Bool)) : ()
|
||||
{
|
||||
body {
|
||||
// Bob can apply an X gate to his qubit to convert the pair to |Φ⁺⟩
|
||||
// and use the standard teleportation reconstruction process.
|
||||
if (b1) { Z(qBob); }
|
||||
if (!b2) { X(qBob); }
|
||||
}
|
||||
}
|
||||
|
||||
// Task 2.3. Reconstruct the message if the entangled qubits were in the state |Ψ⁻⟩ = (|01⟩ - |10⟩) / sqrt(2).
|
||||
operation ReconstructMessage_PsiMinus_Reference (qBob : Qubit, (b1 : Bool, b2 : Bool)) : ()
|
||||
{
|
||||
body {
|
||||
// Bob can apply a Z gate and an X gate to his qubit to convert the pair to |Φ⁺⟩
|
||||
// and use the standard teleportation reconstruction process.
|
||||
if (!b1) { Z(qBob); }
|
||||
if (!b2) { X(qBob); }
|
||||
}
|
||||
}
|
||||
|
||||
// Task 3.1. Measurement-free teleportation.
|
||||
operation MeasurementFreeTeleport_Reference (qAlice : Qubit, qBob : Qubit, qMessage : Qubit) : ()
|
||||
{
|
||||
body {
|
||||
// The first part of the circuit is similar to Alice's part, but without measurements.
|
||||
CNOT(qMessage, qAlice);
|
||||
H(qMessage);
|
||||
|
||||
// Classically controlled gates applied by Bob are replaced by controlled gates
|
||||
(Controlled Z)([qMessage], qBob);
|
||||
(Controlled X)([qAlice], qBob);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,165 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
namespace Quantum.Kata.Teleportation
|
||||
{
|
||||
open Microsoft.Quantum.Primitive;
|
||||
open Microsoft.Quantum.Canon;
|
||||
open Microsoft.Quantum.Extensions.Convert;
|
||||
open Microsoft.Quantum.Extensions.Math;
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Welcome!
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// "Teleportation" quantum kata is a series of exercises designed
|
||||
// to get you familiar with programming in Q#.
|
||||
// It covers the quantum teleportation protocol which allows you
|
||||
// to communicate a quantum state using only classical communication
|
||||
// and previously shared quantum entanglement.
|
||||
//
|
||||
// Each task is wrapped in one operation preceded by the description of the task.
|
||||
// Each task (except tasks in which you have to write a test) has a unit test associated with it,
|
||||
// which initially fails. Your goal is to fill in the blank (marked with // ... comment)
|
||||
// with some Q# code to make the failing test pass.
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Part I. Standard Teleportation
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// We split the teleportation protocol into several steps, following the description at
|
||||
// https://docs.microsoft.com/en-us/quantum/quantum-techniques-6-puttingitalltogether :
|
||||
// * Preparation (creating the entangled pair of qubits that are sent to Alice and Bob).
|
||||
// * Sending the message (Alice's task): Entangling the message qubit with Alice's qubit
|
||||
// and extracting two classical bits to be sent to Bob.
|
||||
// * Reconstructing the message (Bob's task): Using the two classical bits Bob received from Alice
|
||||
// to get Bob's qubit into the state in which the message qubit has been originally.
|
||||
// Finally, we compose these steps into the complete teleportation protocol.
|
||||
|
||||
// Task 1.1. Entangled pair
|
||||
// Input: two qubits qAlice and qBob, each in |0⟩ state.
|
||||
// Goal: create a Bell state |Φ⁺⟩ = (|00⟩ + |11⟩) / sqrt(2) on these qubits.
|
||||
//
|
||||
// In the context of quantum teleportation protocol, this is the preparation step:
|
||||
// qubits qAlice and qBob will be sent to Alice and Bob, respectively.
|
||||
operation Entangle (qAlice : Qubit, qBob : Qubit) : ()
|
||||
{
|
||||
body {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
// Task 1.2. Send the message (Alice's task)
|
||||
// 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 Bool 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.
|
||||
operation SendMessage (qAlice : Qubit, qMessage : Qubit) : (Bool, Bool)
|
||||
{
|
||||
body {
|
||||
// ...
|
||||
return (false, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Task 1.3. Reconstruct the message (Bob's task)
|
||||
// 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 task 1.2.
|
||||
// Goal: transform Bob's qubit qBob into the state in which the message qubit has been originally.
|
||||
operation ReconstructMessage (qBob : Qubit, (b1 : Bool, b2 : Bool)) : ()
|
||||
{
|
||||
body {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
// Task 1.4. Standard teleportation protocol
|
||||
// Put together the steps implemented in tasks 1.1 - 1.3 to implement
|
||||
// the full teleportation protocol.
|
||||
// Inputs:
|
||||
// 1) The two qubits qAlice and qBob in |0⟩ state.
|
||||
// 2) The message qubit qMessage in the state |ψ⟩ to be teleported.
|
||||
// Goal: transform Bob's qubit qBob into the state |ψ⟩.
|
||||
// The state of the qubits qAlice and qBob in the end of the operation doesn't matter.
|
||||
operation StandardTeleport (qAlice : Qubit, qBob : Qubit, qMessage : Qubit) : ()
|
||||
{
|
||||
body {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Part II. Teleportation using different entangled pair
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// In this section we will take a look at the changes in the reconstruction process (Bob's task)
|
||||
// if the qubits shared between Alice and Bob are entangled in a different state.
|
||||
// Alice's part of the protocol remains the same in all tasks.
|
||||
// As a reminder, the standard teleportation protocol requires shared qubits in state
|
||||
// |Φ⁺⟩ = (|00⟩ + |11⟩) / sqrt(2).
|
||||
|
||||
// In each task, the inputs are
|
||||
// 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 task 1.2.
|
||||
// The goal is to transform Bob's qubit qBob into the state in which the message qubit has been originally.
|
||||
|
||||
// Task 2.1. Reconstruct the message if the entangled qubits were in the state |Φ⁻⟩ = (|00⟩ - |11⟩) / sqrt(2).
|
||||
operation ReconstructMessage_PhiMinus (qBob : Qubit, (b1 : Bool, b2 : Bool)) : ()
|
||||
{
|
||||
body {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
// Task 2.2. Reconstruct the message if the entangled qubits were in the state |Ψ⁺⟩ = (|01⟩ + |10⟩) / sqrt(2).
|
||||
operation ReconstructMessage_PsiPlus (qBob : Qubit, (b1 : Bool, b2 : Bool)) : ()
|
||||
{
|
||||
body {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
// Task 2.3. Reconstruct the message if the entangled qubits were in the state |Ψ⁻⟩ = (|01⟩ - |10⟩) / sqrt(2).
|
||||
operation ReconstructMessage_PsiMinus (qBob : Qubit, (b1 : Bool, b2 : Bool)) : ()
|
||||
{
|
||||
body {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////
|
||||
// Part III. Principle of deferred measurement
|
||||
//////////////////////////////////////////////////////////////////
|
||||
|
||||
// The principle of deferred measurement claims that measurements can be moved
|
||||
// from an intermediate stage of a quantum circuit to the end of the circuit.
|
||||
// If the measurement results are used to perform classically controlled operations,
|
||||
// they can be replaced by controlled quantum operations.
|
||||
|
||||
// In this task we will apply this principle to the teleportation circuit.
|
||||
|
||||
// Task 3.1. Measurement-free teleportation.
|
||||
// Inputs:
|
||||
// 1) The two qubits qAlice and qBob in |Φ⁺⟩ state.
|
||||
// 2) The message qubit qMessage in the state |ψ⟩ to be teleported.
|
||||
// Goal: transform Bob's qubit qBob into the state |ψ⟩ using no measurements.
|
||||
// At the end of the operation qubits qAlice and qMessage should not be entangled with qBob.
|
||||
operation MeasurementFreeTeleport (qAlice : Qubit, qBob : Qubit, qMessage : Qubit) : ()
|
||||
{
|
||||
body {
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,22 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp2.0</TargetFramework>
|
||||
<PlatformTarget>x64</PlatformTarget>
|
||||
<IsPackable>false</IsPackable>
|
||||
<RootNamespace>Quantum.Kata.Teleportation</RootNamespace>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Quantum.Canon" Version="0.2.1806.3001-preview" />
|
||||
<PackageReference Include="Microsoft.Quantum.Development.Kit" Version="0.2.1806.3001-preview" />
|
||||
<PackageReference Include="Microsoft.Quantum.Xunit" Version="0.2.1806.3001-preview" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.3.0" />
|
||||
<PackageReference Include="xunit" Version="2.3.1" />
|
||||
<PackageReference Include="xunit.runner.visualstudio" Version="2.3.1" />
|
||||
<DotNetCliToolReference Include="dotnet-xunit" Version="2.3.1" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<None Include="README.md" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,25 @@
|
|||
|
||||
Microsoft Visual Studio Solution File, Format Version 12.00
|
||||
# Visual Studio 15
|
||||
VisualStudioVersion = 15.0.27130.2036
|
||||
MinimumVisualStudioVersion = 10.0.40219.1
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Teleportation", "Teleportation.csproj", "{1FD1C660-6646-44B0-B252-32378CBF682B}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
Release|Any CPU = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(ProjectConfigurationPlatforms) = postSolution
|
||||
{1FD1C660-6646-44B0-B252-32378CBF682B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{1FD1C660-6646-44B0-B252-32378CBF682B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{1FD1C660-6646-44B0-B252-32378CBF682B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{1FD1C660-6646-44B0-B252-32378CBF682B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {0DE89BFF-6EB5-4848-AB40-A01C1CD406FB}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
|
@ -0,0 +1,42 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// This file contains parts of the testing harness.
|
||||
// You should not modify anything in this file.
|
||||
// The tasks themselves can be found in Tasks.qs file.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
using Microsoft.Quantum.Simulation.XUnit;
|
||||
using Microsoft.Quantum.Simulation.Simulators;
|
||||
using Xunit.Abstractions;
|
||||
using System.Diagnostics;
|
||||
|
||||
namespace Quantum.Kata.Teleportation
|
||||
{
|
||||
public class TestSuiteRunner
|
||||
{
|
||||
private readonly ITestOutputHelper output;
|
||||
|
||||
public TestSuiteRunner(ITestOutputHelper output)
|
||||
{
|
||||
this.output = output;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// This driver will run all Q# tests (operations named "...Test")
|
||||
/// that belong to namespace Quantum.Kata.Teleportation.
|
||||
/// </summary>
|
||||
[OperationDriver(TestNamespace = "Quantum.Kata.Teleportation")]
|
||||
public void TestTarget(TestOperation op)
|
||||
{
|
||||
using (var sim = new QuantumSimulator())
|
||||
{
|
||||
// OnLog defines action(s) performed when Q# test calls function Message
|
||||
sim.OnLog += (msg) => { output.WriteLine(msg); };
|
||||
sim.OnLog += (msg) => { Debug.WriteLine(msg); };
|
||||
op.TestOperationRunner(sim);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,237 @@
|
|||
// Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
// Licensed under the MIT license.
|
||||
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// This file contains testing harness for all tasks.
|
||||
// You should not modify anything in this file.
|
||||
// The tasks themselves can be found in Tasks.qs file.
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
namespace Quantum.Kata.Teleportation
|
||||
{
|
||||
open Microsoft.Quantum.Primitive;
|
||||
open Microsoft.Quantum.Canon;
|
||||
open Microsoft.Quantum.Extensions.Testing;
|
||||
|
||||
// ------------------------------------------------------
|
||||
operation T11_Entangle_Test () : ()
|
||||
{
|
||||
body
|
||||
{
|
||||
using (qs = Qubit[2])
|
||||
{
|
||||
let q0 = qs[0];
|
||||
let q1 = qs[1];
|
||||
// apply operation that needs to be tested
|
||||
Entangle(q0, q1);
|
||||
|
||||
// apply adjoint reference operation and check that the result is |00⟩
|
||||
(Adjoint Entangle_Reference)(q0, q1);
|
||||
|
||||
// assert that all qubits end up in |0⟩ state
|
||||
AssertAllZero(qs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
// 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) : () {
|
||||
body {
|
||||
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 runs teleportation using two building blocks
|
||||
// specified as first two parameters.
|
||||
operation ComposeTeleportation(
|
||||
bellPrepOp : ((Qubit, Qubit) => ()),
|
||||
getDescriptionOp : ((Qubit, Qubit) => (Bool, Bool)),
|
||||
reconstructOp : ((Qubit, (Bool, Bool)) => ()),
|
||||
qAlice : Qubit,
|
||||
qBob : Qubit,
|
||||
qMessage : Qubit
|
||||
) : ()
|
||||
{
|
||||
body
|
||||
{
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
// 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) => ()),
|
||||
setupPsiOp : (Qubit => () : Adjoint)
|
||||
) : ()
|
||||
{
|
||||
body{
|
||||
using(qs = Qubit[3])
|
||||
{
|
||||
let qMessage = qs[0];
|
||||
let qAlice = qs[1];
|
||||
let qBob = qs[2];
|
||||
|
||||
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);
|
||||
|
||||
AssertQubit(Zero, qBob);
|
||||
|
||||
ResetAll(qs);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
// 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) => ())) : ()
|
||||
{
|
||||
body
|
||||
{
|
||||
// Define setup operations for the message qubit
|
||||
// on which to test teleportation: |0⟩, |1⟩, |0⟩ + |1⟩, unequal superposition.
|
||||
let setupPsiOps = [I; X; H; Ry(42.0, _)];
|
||||
|
||||
// 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 (i in 0..Length(setupPsiOps)-1)
|
||||
{
|
||||
for (j in 1..numRepetitions)
|
||||
{
|
||||
TeleportTestHelper(teleportOp, setupPsiOps[i]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Test the 'SendMessage' operation by using it as one part of full teleportation,
|
||||
// taking reference implementation for the other parts.
|
||||
operation T12_SendMessage_Test() : ()
|
||||
{
|
||||
body
|
||||
{
|
||||
let teleport = ComposeTeleportation(StatePrep_BellState(_, _, 0), SendMessage, ReconstructMessage_Reference, _, _ , _);
|
||||
TeleportTestLoop(teleport);
|
||||
}
|
||||
}
|
||||
|
||||
// Test the 'ReconstructMessage' operation by using it as one part of full teleportation,
|
||||
// taking reference implementation for the other parts.
|
||||
operation T13_ReconstructMessage_Test() : ()
|
||||
{
|
||||
body
|
||||
{
|
||||
let teleport = ComposeTeleportation(StatePrep_BellState(_, _, 0), SendMessage_Reference, ReconstructMessage, _, _ , _);
|
||||
TeleportTestLoop(teleport);
|
||||
}
|
||||
}
|
||||
|
||||
// Test the full Teleport operation
|
||||
operation T14_Teleport_Test() : ()
|
||||
{
|
||||
body
|
||||
{
|
||||
TeleportTestLoop(StandardTeleport);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
// Test variations of the teleport protocol using different state prep procedures
|
||||
operation T21_ReconstructMessage_PhiMinus_Test() : ()
|
||||
{
|
||||
body
|
||||
{
|
||||
let teleport = ComposeTeleportation(StatePrep_BellState(_, _, 1), SendMessage_Reference, ReconstructMessage_PhiMinus, _, _ , _);
|
||||
TeleportTestLoop(teleport);
|
||||
}
|
||||
}
|
||||
|
||||
operation T22_ReconstructMessage_PsiPlus_Test() : ()
|
||||
{
|
||||
body
|
||||
{
|
||||
let teleport = ComposeTeleportation(StatePrep_BellState(_, _, 2), SendMessage_Reference, ReconstructMessage_PsiPlus, _, _ , _);
|
||||
TeleportTestLoop(teleport);
|
||||
}
|
||||
}
|
||||
|
||||
operation T23_ReconstructMessage_PsiMinus_Test() : ()
|
||||
{
|
||||
body
|
||||
{
|
||||
let teleport = ComposeTeleportation(StatePrep_BellState(_, _, 3), SendMessage_Reference, ReconstructMessage_PsiMinus, _, _ , _);
|
||||
TeleportTestLoop(teleport);
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------
|
||||
operation T31_MeasurementFreeTeleport_Test() : ()
|
||||
{
|
||||
body
|
||||
{
|
||||
let setupPsiOps = [I; X; H; Ry(42.0, _)];
|
||||
let numRepetitions = 100;
|
||||
using(qs = Qubit[3])
|
||||
{
|
||||
let qMessage = qs[0];
|
||||
let qAlice = qs[1];
|
||||
let qBob = qs[2];
|
||||
|
||||
for (i in 0..Length(setupPsiOps)-1)
|
||||
{
|
||||
for (j in 1..numRepetitions)
|
||||
{
|
||||
(setupPsiOps[i])(qMessage);
|
||||
StatePrep_BellState(qAlice, qBob, 0);
|
||||
|
||||
MeasurementFreeTeleport(qAlice, qBob, qMessage);
|
||||
|
||||
(Adjoint setupPsiOps[i])(qBob);
|
||||
|
||||
AssertQubit(Zero, qBob);
|
||||
|
||||
ResetAll(qs);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче