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
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
4 changes: 3 additions & 1 deletion samples/error-correction/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,6 @@ These samples show how to work with quantum error correcting codes in Q# program

- **[Bit-flip Code](./bit-flip-code)**:
This sample describes a simple quantum code that encodes 1 qubit into 3 qubits and protects against a single bit-flip error.


- **[Syndrome](./syndrome)**:
This sample implements a simple syndrome that can be used to detect errors in quantum algorithms executed on quantum hardware.
40 changes: 40 additions & 0 deletions samples/error-correction/syndrome/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
---
page_type: sample
languages:
- qsharp
Comment thread
guenp marked this conversation as resolved.
- python
products:
- qdk
description: "This sample uses the Q# standard libraries to implement a syndrome for detecting errors in a given number of data qubits."
urlFragment: quantum-syndrome
---


# Measuring quantum error syndromes with Q\#

This sample demonstrates how to create a partially implemented Syndrome for detecting errors generated in noisy hardware. The sample shows how this is implemented using Q# standard libraries. Currently, it does not simulate realistic noise so the resulting unitary operator is trivial. However, the program is useful to demonstrate the concept of a syndrome.

The algorithm used is described in [Surface codes: Towards practical large-scale quantum computation](https://arxiv.org/abs/1208.0928) by Fowler et al. In particular, this example implements the circuit shown in Figure 1 c. in this paper.

The circuit uses _N data qubits_, where _N_ is a number given as input to the script, plus one _auxiliary_ qubit. The principle of the circuit is as follows. First, we prepare our data qubits in random states of a set of random bases, in order to simulate a noisy process. The circuit then propagates these errors to the auxiliary qubit using the principle of _phase kickback_. Phase kickback works by encoding pieces of a quantum algorithm into the global phase of an extra (auxiliary) qubit.

We start by preparing an auxiliary qubit into the superposition state by applying a `H` operation, to change to the _X_ computational basis. Subsequently, we apply controlled Pauli operators to each of the data qubits in random order, using the auxiliary qubit as control. The goal is to create a global phase shift on the auxiliary qubit, that will depend on the state of the data qubits. After the circuit runs, the auxiliary qubit is measured in the _X_-basis, which reveals its phase information.

## Prerequisites

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

## Running the Sample

To run the sample, run `python syndrome.py --qubits <N>`, where `<N>` is replaced by the number of qubits. For more information, run `python syndrome.py --help`.

## Manifest

- [Syndrome.qs](https://github.com/microsoft/Quantum/blob/master/samples/error-correction/syndrome/Syndrome.qs): Q# code implementing quantum operations for this sample.
- [syndrome.py](https://github.com/microsoft/Quantum/blob/master/samples/error-correction/syndrome/syndrome.py): Python script to interact with and print out results of the Q# operations for this sample for a given number of data qubits. Example usage: `python syndrome.py --qubits 5`.
- [Syndrome.csproj](https://github.com/microsoft/Quantum/blob/master/samples/error-correction/syndrome/Syndrome.csproj): Main Q# project for the sample.

## Further resources

- [Error correction library concepts](https://docs.microsoft.com/quantum/libraries/standard/error-correction)
- [Pauli measurements](https://docs.microsoft.com/en-us/quantum/concepts/pauli-measurements)
7 changes: 7 additions & 0 deletions samples/error-correction/syndrome/Syndrome.csproj
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<Project Sdk="Microsoft.Quantum.Sdk/0.12.20072031">

<PropertyGroup>
<TargetFramework>netstandard2.1</TargetFramework>
</PropertyGroup>

</Project>
103 changes: 103 additions & 0 deletions samples/error-correction/syndrome/Syndrome.qs
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
namespace Microsoft.Quantum.Samples.ErrorCorrection.Syndrome {
open Microsoft.Quantum.Canon;
open Microsoft.Quantum.Intrinsic;
open Microsoft.Quantum.Preparation;
open Microsoft.Quantum.Measurement;
open Microsoft.Quantum.Arrays;
open Microsoft.Quantum.Diagnostics;
open Microsoft.Quantum.Convert;

/// # Summary
/// Measure qubit in a given basis and return the result
///
/// # Input
/// ## basis
/// Pauli basis in which to perform measurement
/// ## qubit
/// Qubit to measure
///
/// # Output
/// ## result
/// Measurement result
operation BasisMeasure(basis : Pauli, qubit : Qubit): Result {
let result = Measure([basis], [qubit]);
return result;
}

/// # Summary
/// Prepare qubit in a given basis. Optionally flip the qubit if the value
/// is True (One).
///
/// # Input
/// ## basis
/// Basis to prepare the qubit in
/// ## qubit
/// Qubit to prepare
/// ## value
/// Value to prepare the qubit in (True for One, False for Zero)
operation PrepareInBasis(basis : Pauli, qubit : Qubit, value : Bool): Unit {
if (value) {
X(qubit);
}
PrepareQubit(basis, qubit);
}

/// # Summary
/// Creates a Pseudo Syndrome by using an auxiliary qubit.
/// This algorithm relies on several controlled Pauli operations. When
/// there is no error introduced after state preparation, the circuit is
/// trivial and no change is measured on the auxiliary qubit. However, if
/// there are miscellaneous rotations on the data qubits due to noise, due
/// to phase kickback the auxiliary qubit will gain a small phase shift.
/// By measuring the auxiliary qubit in the X basis we then project that
/// phase difference onto the measurement basis.
///
/// # Input
/// ## inputValues
/// Array of Boolean input values for data qubits.
/// ## encodingBases
/// Array of Pauli bases to encode errors in for controlled Pauli operations on.
/// The length of this array needs to be the same as
/// inputValues.
/// ## qubitIndices
/// List of qubit indices on which to apply controlled Pauli operators.
/// This determines the order in which the controlled Pauli's are applied.
/// The length of this array needs to be the same as inputValues.
///
/// # Output
/// ## (auxiliaryResult, dataResult)
/// Tuple of the measurement results of the auxiliary qubit and data qubits.
operation SamplePseudoSyndrome (
Comment thread
guenp marked this conversation as resolved.
inputValues : Bool[],
encodingBases : Pauli[],
qubitIndices : Int[]
): ( Result, Result[] ) {
// Check that input lists are of equal length
if ((Length(inputValues) != Length(encodingBases))
or (Length(inputValues) != Length(qubitIndices))) {
fail $"Lengths of input values, encoding bases and qubitIndices must be
equal. Found lengths:
{Length(inputValues)}, {Length(encodingBases)}, {Length(qubitIndices)}";
}

using ((block, auxiliary) = (Qubit[Length(inputValues)], Qubit())) {
for ((qubit, value, basis) in Zip3(block, inputValues, encodingBases)) {
PrepareInBasis(basis, qubit, value);
}
H(auxiliary);
// Apply Controlled Pauli operations to data qubits, resulting in a phase kickback
/// on the auxiliary qubit
for ((index, basis) in Zip(qubitIndices, encodingBases)) {
Controlled ApplyPauli([auxiliary], ([basis], [block[index]]));
}
let auxiliaryResult = Measure([PauliX], [auxiliary]);
let dataResult = ForEach(BasisMeasure, Zip(encodingBases, block));
// Reset qubits - optional, only for QDK version < 0.12
ResetAll(block);
Reset(auxiliary);
return ( auxiliaryResult, dataResult );
}
}
}
43 changes: 43 additions & 0 deletions samples/error-correction/syndrome/syndrome.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Copyright (c) Microsoft Corporation.
# Licensed under the MIT License.
"""
Script for running Pseudo-syndrome example as defined in Syndrome.qs.
This script takes the number of data qubits as input.

Example usage:
python syndrome.py -q 5
"""

import numpy as np
import qsharp
import argparse

from Microsoft.Quantum.Samples.ErrorCorrection.Syndrome import SamplePseudoSyndrome

parser = argparse.ArgumentParser(
prog="PseudoSyndrome",
description="Program for running a PseudoSyndrome circuit that detects \
random errors on qubits in gate sequence."
)
parser.add_argument("-q", "--qubits", type=int, default=1)

if __name__ == "__main__":
args = parser.parse_args()
# To be refactored to qsharp.Pauli
# (See IQSharp ticket https://github.com/microsoft/iqsharp/issues/256)
paulis = ["PauliX", "PauliY", "PauliZ"]
Comment thread
guenp marked this conversation as resolved.
qubit_indices = list(range(args.qubits))
np.random.shuffle(qubit_indices)
input_values = [np.random.rand() > .5 for n in range(args.qubits)]
encoding_bases = [np.random.choice(paulis) for n in range(args.qubits)]
result = SamplePseudoSyndrome.simulate(
inputValues=input_values,
encodingBases=encoding_bases,
qubitIndices=qubit_indices)
auxiliary, data = result

print(f"Inputs: {[int(val) for val in input_values]}\
\nBases: {encoding_bases}\
\nQubit indices: {qubit_indices}")
print(f"Auxiliary: {auxiliary}")
print(f"Data qubits: {data}")