Hands-On Examples for the X-Cube Fracton Decoder
Four interactive demos you can poke at — the geometry, the decode pipeline, the scoreboard, and the noise sweep
Companion to the tutorial and to the paper “Structure-Aware Neural Decoding for the X-Cube Fracton Code” (B. Guarraci, Galatheus).
The tutorial explains why fracton decoding is hard and what the paper claims; this page lets you see it. Every widget below runs entirely offline with hand-written canvas + JavaScript — no libraries. The geometry in Widget 1 is derived directly from the edge→cube incidence in internal/fracton/xcube_code.py (the offset table is machine-checked against make_xcube for every edge); Widget 2 is a schematic of the decode path described in the tutorial §3.2–3.3; and all numbers in Widgets 3–4 (and the ablation figures in Widget 2) are taken verbatim from the data/ JSON files. Nothing is invented.
The one idea to hold onto
In the surface code an error is a string that lights two defects you can pair up. In the X-cube code an error lights four defects at once, arranged as a rigid 2×2 block, and they are immobile — there is no string to follow. That single fact breaks matching decoders and is what the learned line-aware decoder is built to handle. Widget 1 lets you create those four-at-a-time defects yourself.
1. Errors make fractons (and why matching fails)
Contrast with the surface code
A surface-code error string lights two endpoint defects, and a minimum-weight matching pairs them with the cheapest connecting path — the whole algorithm relies on “defects come in pairs joined by a string.” Here a single error gives four defects at the corners of a flat region, none of them connected by a 1D string. There is no pairing to do, so MWPM has nothing to match. This is exactly why the paper turns to a learned decoder.
What the cancellation shows (toggle two adjacent parallel edges)
Two parallel edges sitting side by side in the transverse plane share two of their cube checks. Those shared checks see two flips — an even number — so they go quiet, and defects survive only at the two outer ends. Extend a whole row of parallel edges and the interior defects all cancel; a full periodic row leaves zero defects (it is a logical/stabilizer line). That is the long line/membrane structure where the X-cube hides its logical information, and the AxisLineonHead pools along exactly these axes to read it.
2. How the decoder reads the lattice — the AxisLineonHead pipeline
The coset-classification reframing (why it is a classifier at all)
For any syndrome \(s\) you can fix some error \(R(s)\) consistent with it (a “pure error,” pure linear algebra from \(H_Z\)). The true error differs from \(R(s)\) only by which logical coset it lives in — exactly the \(6L-3\) parity bits. So decoding = predict \(6L-3\) bits, then apply \(R(s)\) plus the predicted logical representative. A per-sector error is just one wrong bit — and those bits are precisely the head's per-sector logits.
Why the ablation is the proof (toggle the head above)
Swap the line-aggregation head for a global average pool and the network collapses the whole lattice to one vector — it can no longer tell where evidence sits, so it can only emit the global prior. Its block failure is 0.7342, identical to the trivial floor 0.7342: it learns nothing. The AxisLineonHead (and a coordinate-conv variant) instead score 0.303 / 0.302. Same body, same data, same capacity — the only change is whether the head preserves the line structure. That is the inventive step, made falsifiable.
3. Decoder scoreboard
Why per-sector LER is the honest metric
Block failure asks for all \(6L-3\) logical sectors correct at once, so it is brutal for every decoder at large \(L\) — one slip ruins the block. Per-sector LER is the per-logical-qubit rate, and it is where the scaling story lives: a fixed-capacity local rule (or a lookup table) cannot improve with size, but the learned decoder does, because it reads non-local line structure.
4. Noise slider
Bounded operating range (paper's own limitation)
The learned per-sector advantage over trivial decays smoothly: a clear win at \(p=0.05\) (0.110 vs 0.172), narrowing to 0.198 vs 0.227 at \(p=0.07\) and 0.267 vs 0.274 at \(p=0.09\), then closing to a statistical tie by \(p\approx0.11\)–0.13. This puts the useful range up near the \(\approx7.5\%\) optimal threshold — honest, and exactly what the paper reports.
Companion to the tutorial and main.tex. Widget 1 geometry is derived from internal/fracton/xcube_code.py (offset table machine-verified against make_xcube for every edge and axis). Widget 2 is a schematic of the decode pipeline (§3.2–3.3 of the tutorial); its ablation figures (0.7342 / 0.303 / 0.302) come from data/xcube_L346_gen.json → sections.ablation. Widget 3–4 numbers are taken verbatim from data/xcube_L346_gen.json, data/xcube_L810_gen.json, data/xcube_L4_psweep.json, and data/xcube_bw_baseline.json per REPRODUCIBILITY.md. No results were invented.