3-Qubit Bit-Flip Code
What You'll Learn:
- How quantum error correction encodes logical qubits into physical qubits
- How syndrome measurement detects errors without collapsing the logical state
- How conditional correction gates fix identified errors
- Why redundancy protects quantum information (just like classical repetition codes)
Level: Intermediate | Time: 20 minutes | Qubits: 5 (3 data + 2 syndrome) | Framework: Qiskit
Prerequisites
- Bell State — CX entanglement
- GHZ State — multi-qubit entanglement
The Idea
Classical computers handle errors with redundancy: store 3 copies of each bit (000 or 111), and if one flips, majority vote recovers the original. Quantum computers face the same problem — qubits are noisy and decohere — but quantum mechanics forbids copying (no-cloning theorem).
The bit-flip code solves this by entangling 3 qubits into a logical state: |0⟩_L = |000⟩, |1⟩_L = |111⟩. If a single qubit flips, we detect which one by measuring the parity between pairs — without measuring the qubits themselves (which would collapse the superposition).
This is the simplest quantum error correcting code. It protects against bit-flip (X) errors only — not phase errors. But it introduces all the key concepts: encoding, syndrome extraction, and conditional correction.
How It Works
Step 1: Encoding
Spread the logical qubit across 3 physical qubits using CX gates:
CODE┌───┐ q_0: ┤ X ├──■────■── (logical |1⟩ → |111⟩) └───┘┌─┴─┐ │ q_1: ─────┤ X ├──┼── └───┘┌─┴─┐ q_2: ─────────┤ X ├── └───┘
| Logical state | Encoded state |
|---|---|
| |0⟩_L | |000⟩ |
| |1⟩_L | |111⟩ |
| α|0⟩ + β|1⟩ | α|000⟩ + β|111⟩ |
Step 2: Error (Noise)
A single X error flips one qubit:
| Error | State after error |
|---|---|
| None | |111⟩ |
| X on qubit 0 | |011⟩ |
| X on qubit 1 | |101⟩ |
| X on qubit 2 | |110⟩ |
Step 3: Syndrome Extraction
Two ancilla qubits measure parity between data qubit pairs — without disturbing the data:
CODEdata[0]: ──■─────────────── │ data[1]: ──┼────■────■───── │ │ │ data[2]: ──┼────┼────┼────■ ┌─┴─┐┌─┴─┐ │ │ syn[0]: ┤ X ├┤ X ├─┼────┼ → measures parity(q0, q1) └───┘└───┘┌┴─┐┌─┴─┐ syn[1]: ──────────┤ X├┤ X ├ → measures parity(q1, q2) └──┘└───┘
| Syndrome | Meaning | Correction |
|---|---|---|
| 00 | No error | None |
| 01 | Qubit 0 flipped | Apply X on qubit 0 |
| 11 | Qubit 1 flipped | Apply X on qubit 1 |
| 10 | Qubit 2 flipped | Apply X on qubit 2 |
Step 4: Conditional Correction
Based on the syndrome measurement result, apply X to the identified qubit.
PYTHONfrom circuit import run_circuit, verify_bit_flip_code # No error → perfect recovery result = run_circuit(error_qubit=None) print(f"Success: {result['success_rate']:.1%}") # ~100% # Error on qubit 1 → detected and corrected result = run_circuit(error_qubit=1) print(f"Success: {result['success_rate']:.1%}") # ~100%
The Math
Stabilizer Formalism
The bit-flip code is defined by two stabilizer generators:
CODES₁ = Z₀Z₁I₂ (parity of qubits 0 and 1) S₂ = I₀Z₁Z₂ (parity of qubits 1 and 2)
The codespace is the +1 eigenspace of both stabilizers:
- S₁|000⟩ = +|000⟩, S₁|111⟩ = +|111⟩ ✓
- S₁|011⟩ = -|011⟩ ✗ (error detected!)
Error Detection
An X error on qubit k anti-commutes with stabilizers that include Z on qubit k:
| Error | S₁ = Z₀Z₁ | S₂ = Z₁Z₂ | Syndrome (displayed) |
|---|---|---|---|
| I | +1 | +1 | 00 |
| X₀ | -1 | +1 | 01 |
| X₁ | -1 | -1 | 11 |
| X₂ | +1 | -1 | 10 |
Each single-qubit error gives a unique syndrome → correctable.
Expected Output
| Scenario | Success Rate |
|---|---|
| No error | ~100% |
| X error on qubit 0 | ~100% |
| X error on qubit 1 | ~100% |
| X error on qubit 2 | ~100% |
| Two simultaneous errors | ~0% (uncorrectable) |
Running the Circuit
PYTHONfrom circuit import run_circuit, verify_bit_flip_code # Test each error scenario for eq in [None, 0, 1, 2]: result = run_circuit(error_qubit=eq) label = f"Error on qubit {eq}" if eq is not None else "No error" print(f"{label}: {result['success_rate']:.1%}") # Full verification v = verify_bit_flip_code() for check in v["checks"]: print(f"[{'PASS' if check['passed'] else 'FAIL'}] {check['name']}")
Try It Yourself
-
Encode |0⟩ instead of |1⟩: Run with
logical_state=0. Verify the code still works — the syndrome doesn't depend on the logical value. -
Two errors: Apply X on qubits 0 AND 1 simultaneously. What syndrome do you get? Can the code correct it? (Hint: it can't — the syndrome matches a single error on qubit 2.)
-
Phase error: Replace
qc.x(data[error_qubit])withqc.z(data[error_qubit]). Does the code detect the error? (It shouldn't — bit-flip code only handles X errors.) -
Larger code: Extend to a 5-qubit repetition code. How many syndrome qubits do you need?
What's Next
- Phase-Flip Code — The dual code that corrects Z errors using Hadamard basis
- Shor Code — Combine bit-flip + phase-flip to correct any single error
- Steane Code — A more efficient 7-qubit CSS code
References
- Shor, P.W. (1995). "Scheme for reducing decoherence in quantum computer memory." Physical Review A 52, R2493. DOI: 10.1103/PhysRevA.52.R2493
- Nielsen, M.A. & Chuang, I.L. Quantum Computation and Quantum Information, Section 10.1.
- Devitt, S.J. et al. (2013). "Quantum error correction for beginners." Reports on Progress in Physics 76, 076001. DOI: 10.1088/0034-4885/76/7/076001