Skip to content

Commit 0c774d9

Browse files
committed
change structure and measurement to bit flip
1 parent 7023878 commit 0c774d9

File tree

1 file changed

+46
-70
lines changed

1 file changed

+46
-70
lines changed
Lines changed: 46 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -1,94 +1,70 @@
11
from qutip_qip.circuit import QubitCircuit
22

3-
43
class BitFlipCode:
54
"""
6-
Generalized implementation of the 3-qubit bit-flip code.
5+
Implementation of the 3-qubit bit-flip code using projective measurements
6+
and classically controlled gates for automatic correction.
7+
8+
The class represents the abstract structure of the bit-flip code.
9+
Qubit indices must be provided when generating the circuit.
710
8-
Parameters
9-
----------
10-
data_qubits : list of int
11-
The three physical qubits holding the logical qubit.
12-
syndrome_qubits : list of int, optional
13-
Two ancilla qubits used for syndrome extraction.
11+
Methods
12+
-------
13+
encode_circuit(data_qubits)
14+
Encode a logical qubit into three physical qubits.
15+
syndrome_and_correction_circuit(data_qubits, syndrome_qubits)
16+
Extract error syndrome and apply correction via classical control.
17+
decode_circuit(data_qubits)
18+
Decode the logical qubit back to a single physical qubit.
1419
"""
1520

16-
def __init__(self, data_qubits=[0, 1, 2], syndrome_qubits=[3, 4]):
17-
assert len(data_qubits) == 3, "Bit-flip code requires 3 data qubits."
18-
self.data_qubits = data_qubits
19-
self.syndrome_qubits = syndrome_qubits
20-
self.n_qubits = max(data_qubits + syndrome_qubits) + 1
21+
def __init__(self):
22+
self.n_data = 3
23+
self.n_syndrome = 2
2124

22-
def encode_circuit(self):
23-
"""
24-
Returns
25-
-------
26-
QubitCircuit
27-
Circuit encoding the logical qubit into 3 physical qubits.
28-
"""
29-
qc = QubitCircuit(self.n_qubits)
30-
control = self.data_qubits[0]
31-
for target in self.data_qubits[1:]:
25+
def encode_circuit(self, data_qubits):
26+
assert len(data_qubits) == self.n_data
27+
qc = QubitCircuit(max(data_qubits) + 1)
28+
control = data_qubits[0]
29+
for target in data_qubits[1:]:
3230
qc.add_gate("CNOT", controls=control, targets=target)
3331
return qc
3432

35-
def syndrome_measurement_circuit(self):
36-
"""
37-
Returns
38-
-------
39-
QubitCircuit
40-
Circuit to extract the error syndrome using ancilla qubits.
41-
"""
42-
qc = QubitCircuit(self.n_qubits)
43-
dq = self.data_qubits
44-
sq = self.syndrome_qubits
33+
def syndrome_and_correction_circuit(self, data_qubits, syndrome_qubits):
34+
assert len(data_qubits) == self.n_data
35+
assert len(syndrome_qubits) == self.n_syndrome
36+
37+
total_qubits = max(data_qubits + syndrome_qubits) + 1
38+
classical_bits = len(syndrome_qubits)
39+
qc = QubitCircuit(N=total_qubits, num_cbits=classical_bits)
40+
41+
dq = data_qubits
42+
sq = syndrome_qubits
4543

46-
# First syndrome bit: parity of dq[0] and dq[1]
44+
# Syndrome extraction
4745
qc.add_gate("CNOT", controls=dq[0], targets=sq[0])
4846
qc.add_gate("CNOT", controls=dq[1], targets=sq[0])
49-
50-
# Second syndrome bit: parity of dq[1] and dq[2]
5147
qc.add_gate("CNOT", controls=dq[1], targets=sq[1])
5248
qc.add_gate("CNOT", controls=dq[2], targets=sq[1])
5349

54-
return qc
55-
56-
def correction_circuit(self, syndrome):
57-
"""
58-
Parameters
59-
----------
60-
syndrome : tuple
61-
Two-bit syndrome measurement result (s1, s2).
50+
# Measurements into classical bits
51+
qc.add_measurement(sq[0], classical_store=0)
52+
qc.add_measurement(sq[1], classical_store=1)
6253

63-
Returns
64-
-------
65-
QubitCircuit
66-
Circuit applying the appropriate X gate based on syndrome.
67-
"""
68-
qc = QubitCircuit(self.n_qubits)
69-
s1, s2 = syndrome
54+
# Classically controlled correction
55+
qc.add_gate("X", targets=dq[0], classical_controls=[0, 1], classical_control_value=[1, 0])
56+
qc.add_gate("X", targets=dq[1], classical_controls=[0, 1], classical_control_value=[1, 1])
57+
qc.add_gate("X", targets=dq[2], classical_controls=[0, 1], classical_control_value=[0, 1])
7058

71-
if s1 == 1 and s2 == 0:
72-
qc.add_gate("X", targets=self.data_qubits[0])
73-
elif s1 == 1 and s2 == 1:
74-
qc.add_gate("X", targets=self.data_qubits[1])
75-
elif s1 == 0 and s2 == 1:
76-
qc.add_gate("X", targets=self.data_qubits[2])
77-
# No correction for (0,0)
7859
return qc
7960

80-
def decode_circuit(self):
81-
"""
82-
Returns
83-
-------
84-
QubitCircuit
85-
Circuit to decode the logical qubit back to original qubit.
86-
"""
87-
qc = QubitCircuit(self.n_qubits)
88-
control = self.data_qubits[0]
89-
for target in reversed(self.data_qubits[1:]):
61+
def decode_circuit(self, data_qubits):
62+
assert len(data_qubits) == self.n_data
63+
qc = QubitCircuit(max(data_qubits) + 1)
64+
control = data_qubits[0]
65+
for target in reversed(data_qubits[1:]):
9066
qc.add_gate("CNOT", controls=control, targets=target)
9167

92-
# Optional TOFFOLI to verify parity
93-
qc.add_gate("TOFFOLI", controls=self.data_qubits[1:], targets=control)
68+
# Optional parity verification
69+
qc.add_gate("TOFFOLI", controls=data_qubits[1:], targets=control)
9470
return qc

0 commit comments

Comments
 (0)