This commit is contained in:
thilow 2018-09-10 17:56:39 +02:00 коммит произвёл Mariia Mykhailova
Родитель 48508c5c22
Коммит 3bb9e21043
10 изменённых файлов: 659 добавлений и 0 удалений

7
Teleportation/.vscode/extensions.json поставляемый Normal file
Просмотреть файл

@ -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"
]
}

3
Teleportation/.vscode/settings.json поставляемый Normal file
Просмотреть файл

@ -0,0 +1,3 @@
{
"csharp.suppressDotnetRestoreNotification": true
}

36
Teleportation/.vscode/tasks.json поставляемый Normal file
Просмотреть файл

@ -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"
}
]
}

9
Teleportation/README.md Normal file
Просмотреть файл

@ -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);
}
}
}

165
Teleportation/Tasks.qs Normal file
Просмотреть файл

@ -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);
}
}
}
}

237
Teleportation/Tests.qs Normal file
Просмотреть файл

@ -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);
}
}
}
}
}
}