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