Skip to content
This repository was archived by the owner on Jan 12, 2024. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
7bf6470
add RUS sample
Jul 6, 2020
7eda2bf
add whitepaper reference
Jul 6, 2020
7e60588
Z rotation correction should be adjoint Z
Jul 6, 2020
d028bef
rename ancilla to auxiliary, make done and success mutable instead of…
Jul 6, 2020
f98f92d
rephrase circuit vs program
Jul 6, 2020
9a389b7
rename PrepareXZero to SetXZeroFromOne
Jul 6, 2020
4bc5524
Update samples/algorithms/repeat-until-success/RepeatUntilSuccess.qs
Jul 6, 2020
3984b05
add missing semicolon
Jul 6, 2020
d9ad262
update QDK to version 0.12.20070124
Jul 6, 2020
a57cd0e
remove qubit reset (not needed in latest release) and unused Rz
Jul 6, 2020
17ff719
add README.m, update docstring
Jul 7, 2020
fa3cf02
Apply suggestions from code review
Jul 7, 2020
b660692
import AssertQubit from Diagnostics
Jul 8, 2020
9747f0b
fix typo in readme (wrong folder name)
Jul 8, 2020
0ab0e06
Update samples/algorithms/repeat-until-success/README.md
Jul 8, 2020
c02e197
convert ket bracket to unicode, remove superfluous comment dashes
Jul 8, 2020
21e4cb5
Assertions and fixes to make sure qubits are in the correct start sta…
Jul 9, 2020
f80433f
WIP: Add UT
Jul 9, 2020
bcadcf5
Address build warnings by updating to 0.12.20070124.
cgranade Jul 9, 2020
59d620e
Refactor to take ApplyArcTan2 into separate operation, fix issue with…
Jul 10, 2020
2cd35c7
add unit test for ApplyRzArcTan2
Jul 10, 2020
335efc1
Merge branch 'master' into guen/samples-12394-rus
Jul 10, 2020
03c8f36
Remove Program.cs from manifest in README
Jul 10, 2020
c775107
Update samples/algorithms/repeat-until-success/RepeatUntilSuccess.qs
Jul 10, 2020
8d61cf5
fix version bug from master merge commit
Jul 10, 2020
07d001c
address build errors by upgrading samples to version 0.12.20070124
Jul 11, 2020
a934d84
Apply suggestions from code review
Jul 13, 2020
c6185a4
add YAML metadata for sample discoverability
Jul 13, 2020
af7ec7e
improve doc(string)s, reorder input variables to have qubits last
Jul 13, 2020
db413c7
follow style guidelines
Jul 13, 2020
d1bb1a6
Apply suggestions from code review
Jul 13, 2020
d21bb59
consistency in variable type annotations, fix grammar error in docstring
Jul 13, 2020
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
2 changes: 1 addition & 1 deletion samples/algorithms/chsh-game/CHSHGame.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.Quantum.Sdk/0.11.2004.2825">
<Project Sdk="Microsoft.Quantum.Sdk/0.12.20070124">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.Quantum.Sdk/0.11.2004.2825">
<Project Sdk="Microsoft.Quantum.Sdk/0.12.20070124">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.Quantum.Sdk/0.11.2004.2825">
<Project Sdk="Microsoft.Quantum.Sdk/0.12.20070124">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand Down
2 changes: 1 addition & 1 deletion samples/algorithms/oracle-synthesis/OracleSynthesis.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.Quantum.Sdk/0.11.2004.2825">
<Project Sdk="Microsoft.Quantum.Sdk/0.12.20070124">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand Down
2 changes: 1 addition & 1 deletion samples/algorithms/order-finding/OrderFinding.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.Quantum.Sdk/0.11.2004.2825">
<Project Sdk="Microsoft.Quantum.Sdk/0.12.20070124">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
Expand Down
55 changes: 55 additions & 0 deletions samples/algorithms/repeat-until-success/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
---
page_type: sample
languages:
- qsharp
products:
- qdk
description: "Using repeat-until-success patterns in quantum programs"
---

# Repeat-until-success

This is an example of a Repeat-Until-Success (RUS) algorithm implemented in a Q# program.
The algorithm has been described in [Adam Paetznick, Krysta M. Svore, Quantum Information & Computation 14(15 & 16): 1277-1301 (2014)](https://arxiv.org/abs/1311.1074).

## Prerequisites ##

- The Microsoft [Quantum Development Kit](https://docs.microsoft.com/quantum/install-guide/).
## Description

The idea for the RUS algorithm originates from the goal of decomposing a single-qubit unitary operation into a sequence of gates from a given universal basis set. In general, the goal of a RUS algorithm is to reduce the number of Clifford gates needed to execute said unitary operation by using one or more auxiliary qubits that are measured during the execution of the algorithm to indicate whether the desired output state has been achieved. This specific RUS algorithm consists of a circuit that uses two auxiliary qubits, which we label `auxiliary` and `resource`, and one `target` qubit.

In this example, the RUS algorithm aims to apply exp(i⋅ArcTan(2)⋅Z) or a 𝑉₃-gate on the `target` qubit. The algorithm is based on the logic mapped out in the below circuit diagram (Fig. 1(c) from [source](https://arxiv.org/abs/1311.1074)). The qubits on the left hand side are labeled from top to bottom: `auxiliary`, `resource` and `target`. As described in the whitepaper, the desired operation will have been achieved when the measurements on both `auxiliary` and `resource` qubits returns `Zero`. When that happens we can exit the program and return the result. In all other cases, we would have to re-run the circuit. Important to note is that if the auxiliary qubit returns `Zero` but the `resource` qubit returns `One`, the resulting operation will have been an effective `Z` rotation which we will then need to correct for.

![RUS circuit diagram](RUS.png)

Since both the `auxiliary` and `resource` qubits need to return `Zero`, we can split this circuit into two parts, in the diagram circled in red and blue. If we execute the first part and it returns `One`, we can skip running the second part and start over. Since the first part doesn't perform any operations on the `target` qubit, we don't have to make any corrections on the `target` qubit and just reinitialize the `auxiliary` and `resource` qubit.

If we measure `Zero` on the `auxiliary` qubit, we run the second part and measure the `resource` qubit. If the measurement returns `Zero`, we measure the `target` qubit and exit the program successfully. If the measurement returns `One`, we need to apply an `Adjoint Z` operation on the `target` qubit as mentioned above.

The program returns a tuple with three values: whether the program ran successfully, the measurement result on the `target` qubit and the number of iterations that was run to obtain the result.

## Running the Sample

Browse to the `samples/algorithms/repeat-until-success` folder and run `dotnet build` to build the project. Then run `dotnet run [options] --no-build`. Optionally, omit the `--no-build` option to automatically build the project before execution.

To see options, run `dotnet run -- --help`.
```
Options:
--input-value (REQUIRED) Boolean value for input qubit (true maps to One, false maps to Zero)
--input-basis <PauliI|PauliX|PauliY|PauliZ> (REQUIRED) Pauli basis to prepare input qubit in
--limit <limit> (REQUIRED) Integer limit to number of repeats of circuit
```

## Manifest

- **repeat-until-success/**
- [RepeatUntilSuccess.csproj](./RepeatUntilSuccess.csproj): Main C# project for the example.
- [RepeatUntilSuccess.qs](./RepeatUntilSuccess.qs): The Q# implementation of the RUS algorithm.

## Example run

```
> dotnet run --input-value true --input-basis PauliZ --limit 10
(True, One, 3)
```
Binary file added samples/algorithms/repeat-until-success/RUS.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project Sdk="Microsoft.Quantum.Sdk/0.12.20070124">

<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
</PropertyGroup>

</Project>
222 changes: 222 additions & 0 deletions samples/algorithms/repeat-until-success/RepeatUntilSuccess.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,222 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
namespace Microsoft.Quantum.Samples.RepeatUntilSuccess {
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Math;
open Microsoft.Quantum.Preparation;
open Microsoft.Quantum.Diagnostics;

/// # Summary
/// Example of a Repeat-until-success algorithm implementing a circuit
/// that achieves exp(i⋅ArcTan(2)⋅Z) by Paetznick & Svore.
/// The exp(𝑖 ArcTan(2) 𝑍) operation is also known as the "𝑉 gate."
/// # References
/// - [ *Adam Paetznick, Krysta M. Svore*,
/// Quantum Information & Computation 14(15 & 16): 1277-1301 (2014)
/// ](https://arxiv.org/abs/1311.1074)
/// For circuit diagram, see file RUS.png.
///
/// # Input
/// ## inputBasis
/// Pauli basis in which to prepare input qubit
/// ## inputValue
/// Boolean value for input qubit (true maps to One, false maps to Zero)
/// ## limit
/// Integer limit to number of repeats of circuit
///
/// # Remarks
/// The program executes a circuit on a "target" qubit using an "auxiliary"
/// and "resource" qubit. The circuit consists of two parts (red and blue
/// in image).
/// The goal is to measure Zero for both the auxiliary and resource qubit.
/// If this succeeds, the program will have effectively applied an
/// Rz(arctan(2)) gate (also known as V_3 gate) on the target qubit.
/// If this fails, the program reruns the circuit up to <limit> times.
@EntryPoint()
operation CreateQubitsAndApplyRzArcTan2(
inputValue : Bool,
inputBasis : Pauli,
limit : Int
)
: (Bool, Result, Int) {
using ((auxiliary, resource, target) = (Qubit(), Qubit(), Qubit())) {
// Initialize qubits to starting values (|+⟩, |+⟩, |0⟩/|1⟩)
InitializeQubits(
inputBasis, inputValue, auxiliary, resource, target
);
let (success, numIter) = ApplyRzArcTan2(
inputBasis, inputValue, limit, auxiliary, resource, target);
let result = Measure([inputBasis], [target]);
// From version 0.12 it is no longer necessary to release qubits
/// in zero state.
ResetAll([target, resource, auxiliary]);
return (success, result, numIter);
}
}

/// # Summary
/// Apply Rz(arctan(2)) on qubits using repeat until success algorithm.
///
/// # Input
/// ## inputBasis
/// Pauli basis in which to prepare input qubit
/// ## inputValue
/// Boolean value for input qubit (true maps to One, false maps to Zero)
/// ## limit
/// Integer limit to number of repeats of circuit
/// ## auxiliary
/// Auxiliary qubit
/// ## resource
/// Resource qubit
/// ## target
/// Target qubit
///
/// # Output
/// Tuple of (success, numIter) where success = false if the number of
/// iterations (numIter) exceeds the input <limit>
operation ApplyRzArcTan2(
inputBasis : Pauli,
inputValue : Bool,
limit : Int,
auxiliary : Qubit,
resource : Qubit,
target : Qubit
)
: (Bool, Int) {
// Initialize results to One by default.
mutable done = false;
mutable success = false;
mutable numIter = 0;

repeat {
// Assert valid starting states for all qubits
AssertMeasurement([PauliX], [auxiliary], Zero,
"Auxiliary qubit is not in |+⟩ state.");
AssertMeasurement([PauliX], [resource], Zero,
"Resource qubit is not in |+⟩ state.");
AssertQubitIsInState(target, inputBasis, inputValue);

// Run Part 1 of the program.
let result1 = ApplyAndMeasurePart1(auxiliary, resource);
// We'll only run Part 2 if Part 1 returns Zero.
// Otherwise, we'll skip and rerun Part 1 again.
if (result1 == Zero) { //|0+⟩
let result2 = ApplyAndMeasurePart2(resource, target);
if (result2 == Zero) { //|00⟩
set success = true;
} else { //|01⟩
Z(resource); // Reset resource from |-⟩ to |+⟩
Adjoint Z(target); // Correct effective Z rotation on target
}
} else { //|1+⟩
// Set auxiliary and resource qubit back to |+⟩
Z(auxiliary);
Reset(resource);
H(resource);
}
set done = success or (numIter >= limit);
set numIter = numIter + 1;
}
until (done);
return (success, numIter);
}

/// # Summary
/// Initialize axiliary and resource qubits in |+⟩, target in |0⟩ or |1⟩.
///
/// # Input
/// ## inputBasis
/// Pauli basis in which to prepare input qubit
/// ## inputValue
/// Boolean value for input qubit (true maps to One, false maps to Zero)
/// ## limit
/// Integer limit to number of repeats of circuit
/// ## auxiliary
/// Auxiliary qubit
/// ## resource
/// Resource qubit
/// ## target
/// Target qubit
operation InitializeQubits(
inputBasis : Pauli,
inputValue : Bool,
auxiliary : Qubit,
resource : Qubit,
target : Qubit
)
: Unit {
// Prepare auxiliary and resource qubits in |+⟩ state
H(auxiliary);
H(resource);

// Prepare target qubit in |0⟩ or |1⟩ state, depending on input value
if (inputValue) {
X(target);
}
PrepareQubit(inputBasis, target);
}

/// # Summary
/// Apply part 1 of RUS circuit (red circuit shown in README) and measure
/// auxiliary qubit in Pauli X basis
///
/// # Input
/// ## auxiliary
/// Auxiliary qubit
/// ## resource
/// Resource qubit
operation ApplyAndMeasurePart1(
auxiliary : Qubit,
resource : Qubit
)
: Result {
within {
T(auxiliary);
} apply {
CNOT(resource, auxiliary);
}

return Measure([PauliX], [auxiliary]);
}

/// # Summary
/// Apply part 2 of RUS circuit (blue circuit shown in README) and measure
/// resource qubit in Pauli X basis
///
/// # Input
/// ## resource
/// Resource qubit
/// ## target
/// Target qubit
operation ApplyAndMeasurePart2(resource : Qubit, target : Qubit) : Result {
T(target);
Z(target);
CNOT(target, resource);
T(resource);

return Measure([PauliX], [resource]);
}

/// # Summary
/// Assert target qubit state is the desired input value in the desired
/// input basis.
///
/// ## target
/// Target qubit
/// ## inputBasis
/// Pauli basis in which to prepare input qubit
/// ## inputValue
/// Boolean value for input qubit (true maps to One, false maps to Zero)
operation AssertQubitIsInState(
target : Qubit,
inputBasis : Pauli,
inputValue : Bool
)
: Unit {
AssertMeasurement(
[inputBasis], [target], inputValue ? One | Zero,
$"Qubit is not in {inputValue ? One | Zero} state for given input basis."
);
}
}
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.Quantum.Sdk/0.11.2004.2825">
<Project Sdk="Microsoft.Quantum.Sdk/0.12.20070124">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand Down
2 changes: 1 addition & 1 deletion samples/algorithms/simple-grover/SimpleGroverSample.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.Quantum.Sdk/0.11.2004.2825">
<Project Sdk="Microsoft.Quantum.Sdk/0.12.20070124">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.Quantum.Sdk/0.11.2004.2825">
<Project Sdk="Microsoft.Quantum.Sdk/0.12.20070124">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand Down
2 changes: 1 addition & 1 deletion samples/error-correction/bit-flip-code/BitFlipCode.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.Quantum.Sdk/0.11.2004.2825">
<Project Sdk="Microsoft.Quantum.Sdk/0.12.20070124">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand Down
2 changes: 1 addition & 1 deletion samples/getting-started/measurement/Measurement.csproj
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.Quantum.Sdk/0.11.2004.2825">
<Project Sdk="Microsoft.Quantum.Sdk/0.12.20070124">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.Quantum.Sdk/0.11.2004.2825">
<Project Sdk="Microsoft.Quantum.Sdk/0.12.20070124">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.Quantum.Sdk/0.11.2004.2825">
<Project Sdk="Microsoft.Quantum.Sdk/0.12.20070124">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.Quantum.Sdk/0.11.2004.2825">
<Project Sdk="Microsoft.Quantum.Sdk/0.12.20070124">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
<Project Sdk="Microsoft.Quantum.Sdk/0.11.2004.2825">
<Project Sdk="Microsoft.Quantum.Sdk/0.12.20070124">

<PropertyGroup>
<OutputType>Exe</OutputType>
Expand Down
Loading