Real qubits do not fail with neat, symmetric depolarizing noise. They dephase far more than they bit-flip (biased noise), and some platforms can detect when a qubit is lost and flag it (heralded erasure). This repo models both on the toric code and shows how the noise profile changes what the error-correcting code can tolerate -- decoding biased Pauli noise with weighted minimum-weight matching and heralded erasure with a from-scratch peeling decoder.
This is repo 9 of a ten-part QEC research portfolio.
Code-capacity logical error rate on a distance-8 toric code. Heralded erasure (green, decoded by peeling) stays correctable up to a physical rate near 0.5, roughly three times the depolarizing threshold. Biased noise at η = 30 (orange) is slightly worse than depolarizing (blue) in terms of total physical error rate, because the un-tailored toric code dumps almost all the error onto a single decoding graph -- bias only helps when the code is designed to exploit it.
Erasure threshold sweep. The distance-4, 6 and 8 curves cross at p ≈ 0.5 -- the bond-percolation threshold -- which is the analytically known erasure threshold of the toric code and a direct validation of the from-scratch peeling decoder.
Depolarizing threshold sweep. The curves cross near p ≈ 0.16, consistent with the toric-code depolarizing threshold under independent X/Z matching.
- An erasure decoder from scratch. The peeling decoder (Delfosse and Zémor, 2020) grows a spanning forest of the erased subgraph and peels pendant edges in linear time. Reproducing the analytic 0.5 threshold validates the implementation.
- Bias-aware weighted matching. Per-qubit flip probabilities become PyMatching edge weights, the production-standard decoder for surface-code-like codes.
- Finding. Concentrating noise on one Pauli type does not automatically help an un-tailored code; in total-p terms it can hurt. The threshold gain comes from erasure conversion, not from bias alone.
- Biased Pauli: total rate
pand Z-biaseta = p_z / (p_x + p_y).eta = 0.5is depolarizing;eta -> infinityis pure dephasing. - Heralded erasure: each qubit is erased with probability
pand replaced by a uniformly random Pauli, but the decoder is told which qubits were erased.
pip install -e ".[dev]"pytest
python examples/run_noise_study.py # writes the three figures in docs/qecnoise estimate --distance 6 --kind erasure --p 0.45 --shots 3000
qecnoise estimate --distance 6 --kind pauli --eta 100 --p 0.10
qecnoise threshold --kind erasure --distances 4,6,8 --p 0.42,0.46,0.50,0.54 --output outputs/erasure.jsonfrom qecnoise import build_toric_code, estimate_logical_error_rate, NoiseProfile
code = build_toric_code(8)
erasure = estimate_logical_error_rate(code, NoiseProfile(kind="erasure"), p=0.45, shots=3000)
biased = estimate_logical_error_rate(code, NoiseProfile(kind="pauli", eta=100), p=0.10, shots=3000)
print(erasure.logical_error_rate, biased.logical_error_rate)The default sampler is hand-written, but qecnoise.stim_backend expresses the same code-capacity
experiment natively in Stim: a single-qubit Pauli channel on
every data qubit, all stabilizers read out with one MPP measurement, and detectors derived
automatically. It is used to cross-check the hand-written sampler.
This is a code-capacity study (independent errors, perfect syndrome extraction). It is meant to make the qualitative differences between noise profiles reproducible, not to quote circuit-level thresholds. The 0.5 erasure and ≈0.16 depolarizing thresholds are well-established analytic/numerical values for this setting; reproducing them validates the decoders. A circuit-level treatment (measurement errors, a syndrome-extraction schedule, bias-tailored codes such as XZZX) is the natural next step and is deliberately out of scope here.
src/qecnoise/code.py— toric code as two column-weight-2 check matricessrc/qecnoise/noise.py— biased-Pauli rates and erasure samplingsrc/qecnoise/decoders/—matching(weighted PyMatching),peeling(from-scratch erasure)src/qecnoise/simulation.py,experiments/threshold.pysrc/qecnoise/stim_backend.py,viz/plots.py,linalg.py,metrics.py,types.pyexamples/run_noise_study.py
- Delfosse N, Zémor G. Linear-time maximum likelihood decoding of surface codes over the quantum erasure channel. Physical Review Research 2020; 2:033042.
- Gidney C. Stim: a fast stabilizer circuit simulator. Quantum 2021; 5:497.
- Higgott O, Gidney C. Sparse Blossom: correcting a million errors per core second with minimum-weight matching. arXiv 2023; 2303.15933.
- Stace TM, Barrett SD. Error correction and degeneracy in surface codes suffering loss. Physical Review A 2010; 81:022317.
- Tuckett DK, Bartlett SD, Flammia ST. Ultrahigh error threshold for surface codes with biased noise. Physical Review Letters 2018; 120:050505.
MIT — see LICENSE.


