Loading...
Loading...
Decoding & Surface Codes
Quantum error correction algorithms protect fragile quantum information from decoherence and gate errors. Surface codes, color codes, and neural network decoders form the algorithmic backbone of fault-tolerant quantum computing.
Quantum states are extraordinarily fragile. Environmental noise, imperfect gates, and measurement errors destroy quantum information in microseconds. Without error correction, scaling beyond a few dozen qubits is impossible because errors accumulate faster than computation progresses.
Quantum error correction solves this by encoding one logical qubit across many physical qubits. By continuously measuring error syndromes and applying corrections, we can preserve quantum information arbitrarily long — provided the physical error rate is below a threshold.
The surface code is the leading candidate for fault-tolerant quantum computing. It arranges physical qubits on a 2D grid and measures stabilizers — operators that detect the presence of bit-flip (X) and phase-flip (Z) errors without directly measuring the encoded quantum state.
The surface code has a high error threshold (~1%) and requires only nearest-neighbor connectivity, making it compatible with superconducting and neutral atom architectures. The code distance d determines how many errors can be corrected: up to (d-1)/2 physical errors.
Stabilizer Condition
X-Stabilizer (Star)
Z-Stabilizer (Plaquette)
Surface Code Threshold
Decoding is the problem of identifying which errors occurred given a syndrome pattern. The Minimum Weight Perfect Matching (MWPM) decoder is exact but slow for large codes. Neural network decoders use machine learning to predict corrections in microseconds — critical for real-time error correction.
At Identity Lab, we research neural decoders optimized for neutral atom error models, including erasure errors (lost atoms) which have higher detection probabilities than depolarizing noise.
Runnable implementations you can copy and experiment with.
A 3-qubit bit-flip repetition code measuring stabilizers to detect single bit-flip errors.
from qiskit import QuantumCircuit
from qiskit_aer import AerSimulator
# 3-qubit repetition code with 2 ancilla stabilizers
qc = QuantumCircuit(5, 2)
# Encode |0> as |000>
# (identity, already |000>)
# Introduce a bit-flip error on qubit 1
qc.x(1)
# Measure X stabilizers: Z0 Z1 and Z1 Z2
# Z0 Z1: parity of qubit 0 and 1
qc.cx(0, 3)
qc.cx(1, 3)
# Z1 Z2: parity of qubit 1 and 2
qc.cx(1, 4)
qc.cx(2, 4)
# Measure ancillas
qc.measure([3, 4], [0, 1])
simulator = AerSimulator()
job = simulator.run(qc, shots=1024)
counts = job.result().get_counts()
print(counts)
# Syndrome '11' indicates error on middle qubit (qubit 1)A toy 3x3 surface code grid showing how X and Z stabilizers are measured on data qubits.
from qiskit import QuantumCircuit
# Toy 3x3 surface code (9 data qubits + 4 ancillas)
# Layout:
# D - A - D
# | | |
# A - D - A
# | | |
# D - A - D
data = [0, 2, 4, 6, 8] # corners + center
ancilla_x = [1, 7] # measure X stabilizers
ancilla_z = [3, 5] # measure Z stabilizers
qc = QuantumCircuit(9, 4)
# Initialize ancillas for X stabilizers in |+>
for a in ancilla_x:
qc.h(a)
# X-stabilizer: measure X_parities (using CNOT from ancilla to data)
for a in ancilla_x:
neighbors = []
if a == 1:
neighbors = [0, 2]
elif a == 7:
neighbors = [6, 8]
for d in neighbors:
qc.cx(a, d)
# Z-stabilizer: measure Z_parities (using CNOT from data to ancilla)
for a in ancilla_z:
neighbors = []
if a == 3:
neighbors = [0, 6]
elif a == 5:
neighbors = [2, 8]
for d in neighbors:
qc.cx(d, a)
# Finish X ancilla measurement
for a in ancilla_x:
qc.h(a)
# Measure all ancillas
all_ancillas = ancilla_x + ancilla_z
qc.measure(all_ancillas, range(4))
print(qc.draw(output='text'))A PennyLane implementation of a 3-qubit bit-flip repetition code measuring stabilizers to detect single bit-flip errors.
import pennylane as qml
dev = qml.device('default.qubit', wires=5)
@qml.qnode(dev)
def repetition_code():
# Introduce bit-flip error on qubit 1
qml.PauliX(wires=1)
# Z0 Z1 parity check
qml.CNOT(wires=[0, 3])
qml.CNOT(wires=[1, 3])
# Z1 Z2 parity check
qml.CNOT(wires=[1, 4])
qml.CNOT(wires=[2, 4])
return qml.sample(wires=[3, 4])
syndrome = repetition_code()
print("Syndrome:", syndrome)
# Expected: [1, 1] indicating error on qubit 1