microsoft/qdk

Public

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

CodeCommitsIssuesPull requestsActionsInsightsSecurity
v1.6.0

Branches

Tags

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

Clone

HTTPS

Download ZIP

samples/algorithms/BitFlipCode.qs

135lines · 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.
21namespace Sample {
22 open Microsoft.Quantum.Math;
23 open Microsoft.Quantum.Random;
24 open Microsoft.Quantum.Arrays;
25 open Microsoft.Quantum.Diagnostics;
26 open Microsoft.Quantum.Measurement;
27
28 @EntryPoint()
29 operation Main() : Result {
30 use logicalQubit = Qubit[3];
31
32 // Set the initial state of the first physical qubit.
33 SetSampleState(logicalQubit[0]);
34
35 // Using two additional qubits, encode the first physical qubit into a
36 // logical qubit.
37 EncodeAsLogicalQubit(logicalQubit[0], logicalQubit[1...]);
38
39 // Induce a bit-flip error on a random qubit.
40 X(logicalQubit[DrawRandomInt(0, 2)]);
41
42 // Show the logical qubit with the error state.
43 DumpMachine();
44
45 // Find and correct the bit-flip error.
46 CorrectError(logicalQubit);
47
48 // Show the logical qubit with the corrected state.
49 DumpMachine();
50
51 // Decode the logical qubit back into a single physical qubit.
52 Adjoint EncodeAsLogicalQubit(logicalQubit[0], logicalQubit[1...]);
53
54 // Measure and reset the physical qubit before releasing it.
55 let result = M(logicalQubit[0]);
56 Reset(logicalQubit[0]);
57 return result;
58 }
59
60 /// # Summary
61 /// This operation sets the state of the given qubit such that
62 /// it will have a 20% likelihood of resulting in a `Zero` and
63 /// 80% likelihood of resulting in a `One` when measured in the
64 /// computational basis. The input qubit is expected to be in
65 /// the |0〉 state.
66 ///
67 /// # Input
68 /// ## q
69 /// The given qubit to be put into superposition. It is assumed that this
70 /// qubit is in its default |0〉 state.
71 operation SetSampleState(q : Qubit) : Unit {
72 let alpha = 0.20;
73 Ry(2.0 * ArcCos(Sqrt(alpha)), q);
74 }
75
76 /// # Summary
77 /// This operation takes the given `physicalQubit` state,
78 /// (α|0〉 + β|1〉) / √2, and encodes it in the `aux` qubits. This
79 /// encodes all the qubits into a single logical qubit whose state reflects
80 /// the state of the given `physicalQubit`: (α|000〉 + β|111〉) / √2.
81 ///
82 /// # Input
83 /// ## physicalQubit
84 /// The qubit whose state, (α|0〉 + β|1〉) / √2, is to be encoded in the
85 /// logical qubit.
86 ///
87 /// ## aux
88 /// The auxiliary qubits that will be used as part of the encoding. These
89 /// should be grouped with the `physicalQubit` to form the logical qubit.
90 operation EncodeAsLogicalQubit(physicalQubit : Qubit, aux : Qubit[]) : Unit is Adj {
91 ApplyToEachA(CNOT(physicalQubit, _), aux);
92 }
93
94 /// # Summary
95 /// This operation detects and corrects a single bit-flip error for a logical
96 /// qubit encoded as three physical qubits. When finished, the given register
97 /// of qubits will be in the state: (α|000〉 + β|111〉) / √2.
98 ///
99 /// # Input
100 /// ## logicalQubit
101 /// The given register of three physical qubits representing a single logical qubit
102 /// having superposition (α|0〉 + β|1〉) / √2.
103 /// This logical qubit can have up to one bit-flip error that will be corrected.
104 operation CorrectError(logicalQubit : Qubit[]) : Unit {
105 Fact(Length(logicalQubit) == 3, "`logicalQubit` must be length 3");
106
107 // Entangle the parity of the physical qubits into two auxiliary qubits.
108 use aux = Qubit[2];
109 CNOT(logicalQubit[0], aux[0]);
110 CNOT(logicalQubit[1], aux[0]);
111 CNOT(logicalQubit[1], aux[1]);
112 CNOT(logicalQubit[2], aux[1]);
113
114 // Measure the parity information from the auxiliary qubits.
115 let (parity01, parity12) = (M(aux[0]), M(aux[1]));
116 ResetAll(aux);
117
118 // Determine which of the three qubits has the error based on the
119 // parity measurements.
120 let indexOfError = if (parity01, parity12) == (One, Zero) {
121 0
122 } elif (parity01, parity12) == (One, One) {
123 1
124 } elif (parity01, parity12) == (Zero, One) {
125 2
126 } else {
127 -1
128 };
129
130 // If an error was detected, correct that qubit.
131 if indexOfError > -1 {
132 X(logicalQubit[indexOfError]);
133 }
134 }
135}
136