microsoft/qdk

Public

mirrored fromhttps://github.com/microsoft/qdkAvailable

CodeCommitsIssuesPull requestsActionsInsightsSecurity
minestarks/circuit-magic

Branches

Tags

  • No tags available.
0Branches0Tags
Go to file
Add file
Code

Clone

HTTPS

Download ZIP

samples/algorithms/BitFlipCode.qs

132lines · modecode

1/// # Sample
2/// Bit-Flip Code
3///
4/// # Description
5/// This sample demonstrates the three-qubit bit-flip code. This code is a
6/// simple quantum error correction strategy for protecting against a single
7/// bit-flip error by encoding a logical qubit into three physical qubits. A
8/// single bit-flip error is when one of the three physical qubits has its
9/// state changed erroneously in a way that is equivalent to applying the X
10/// gate to it.
11///
12/// The bit-flip correction code works by checking the parity of the physical
13/// qubits. By measuring only their parity, the quantum superposition of the
14/// qubits is preserved. Because all the physical qubits are supposed to have
15/// the same state, when the parity checks detect a difference in state, the
16/// erroneous qubit can be identified and corrected.
17///
18/// This Q# program prepares a logical qubit encoded as three physical qubits
19/// with one of the qubits being bit-flipped. It then identifies and corrects
20/// the flipped qubit.
21import Std.Math.*;
22import Std.Random.*;
23import Std.Arrays.*;
24import Std.Diagnostics.*;
25import Std.Measurement.*;
26
27operation Main() : Result {
28 use logicalQubit = Qubit[3];
29
30 // Set the initial state of the first physical qubit.
31 SetSampleState(logicalQubit[0]);
32
33 // Using two additional qubits, encode the first physical qubit into a
34 // logical qubit.
35 EncodeAsLogicalQubit(logicalQubit[0], logicalQubit[1...]);
36
37 // Induce a bit-flip error on a random qubit.
38 X(logicalQubit[DrawRandomInt(0, 2)]);
39
40 // Show the logical qubit with the error state.
41 DumpMachine();
42
43 // Find and correct the bit-flip error.
44 CorrectError(logicalQubit);
45
46 // Show the logical qubit with the corrected state.
47 DumpMachine();
48
49 // Decode the logical qubit back into a single physical qubit.
50 Adjoint EncodeAsLogicalQubit(logicalQubit[0], logicalQubit[1...]);
51
52 // Measure and reset the physical qubit before releasing it.
53 let result = M(logicalQubit[0]);
54 Reset(logicalQubit[0]);
55 return result;
56}
57
58/// # Summary
59/// This operation sets the state of the given qubit such that
60/// it will have a 20% likelihood of resulting in a `Zero` and
61/// 80% likelihood of resulting in a `One` when measured in the
62/// computational basis. The input qubit is expected to be in
63/// the |0〉 state.
64///
65/// # Input
66/// ## q
67/// The given qubit to be put into superposition. It is assumed that this
68/// qubit is in its default |0〉 state.
69operation SetSampleState(q : Qubit) : Unit {
70 let alpha = 0.20;
71 Ry(2.0 * ArcCos(Sqrt(alpha)), q);
72}
73
74/// # Summary
75/// This operation takes the given `physicalQubit` state,
76/// (α|0〉 + β|1〉) / √2, and encodes it in the `aux` qubits. This
77/// encodes all the qubits into a single logical qubit whose state reflects
78/// the state of the given `physicalQubit`: (α|000〉 + β|111〉) / √2.
79///
80/// # Input
81/// ## physicalQubit
82/// The qubit whose state, (α|0〉 + β|1〉) / √2, is to be encoded in the
83/// logical qubit.
84///
85/// ## aux
86/// The auxiliary qubits that will be used as part of the encoding. These
87/// should be grouped with the `physicalQubit` to form the logical qubit.
88operation EncodeAsLogicalQubit(physicalQubit : Qubit, aux : Qubit[]) : Unit is Adj {
89 ApplyToEachA(CNOT(physicalQubit, _), aux);
90}
91
92/// # Summary
93/// This operation detects and corrects a single bit-flip error for a logical
94/// qubit encoded as three physical qubits. When finished, the given register
95/// of qubits will be in the state: (α|000〉 + β|111〉) / √2.
96///
97/// # Input
98/// ## logicalQubit
99/// The given register of three physical qubits representing a single logical qubit
100/// having superposition (α|0〉 + β|1〉) / √2.
101/// This logical qubit can have up to one bit-flip error that will be corrected.
102operation CorrectError(logicalQubit : Qubit[]) : Unit {
103 Fact(Length(logicalQubit) == 3, "`logicalQubit` must be length 3");
104
105 // Entangle the parity of the physical qubits into two auxiliary qubits.
106 use aux = Qubit[2];
107 CNOT(logicalQubit[0], aux[0]);
108 CNOT(logicalQubit[1], aux[0]);
109 CNOT(logicalQubit[1], aux[1]);
110 CNOT(logicalQubit[2], aux[1]);
111
112 // Measure the parity information from the auxiliary qubits.
113 let (parity01, parity12) = (M(aux[0]), M(aux[1]));
114 ResetAll(aux);
115
116 // Determine which of the three qubits has the error based on the
117 // parity measurements.
118 let indexOfError = if (parity01, parity12) == (One, Zero) {
119 0
120 } elif (parity01, parity12) == (One, One) {
121 1
122 } elif (parity01, parity12) == (Zero, One) {
123 2
124 } else {
125 -1
126 };
127
128 // If an error was detected, correct that qubit.
129 if indexOfError > -1 {
130 X(logicalQubit[indexOfError]);
131 }
132}
133