Foundations of quantum error correction

How a noisy quantum computer can still compute: error-correcting codes, stabilizers, CSS, toric, surface and color codes, and fault tolerance up to the threshold theorem.

Quantum error correction

Quantum computers are highly susceptible to errors in two distinct ways.

  • Unwanted interactions with the environment. No physical system is perfectly isolated. A qubit interacts with its surroundings and can become entangled with them. When the qubit is considered on its own, its state is generally a mixed state rather than the state that was prepared. This loss of coherence is called decoherence.
  • Limited accuracy of operations. A quantum gate is an ideal unitary transformation in the mathematical model, but in hardware it is implemented by a physical control pulse with finite precision. The operation can therefore deviate slightly from the ideal gate. Over a long circuit, these small imperfections accumulate.

Classical error correction has many important applications, but it is generally unnecessary for classical computation itself. A classical bit is represented by one of two well-separated ranges of physical states, such as low and high voltage. Small deviations within one range are tolerated, and digital gates restore the signal toward one of the two valid levels.

A qubit has no comparable gap between valid states. Its state can vary continuously, and every nearby point represents a legitimate quantum state. A small error therefore does not automatically get corrected back to the intended state.

A classical bit

invalid state01

Only the two ends count as values. A voltage that has drifted within a band is read as that level and pushed back to it, every time it passes through a gate.

A qubit

|0⟩|1⟩intendedactual

Every point along the same continuum represents a valid state. A drift produces a different state, with no range that automatically restores it to the intended one.

For large-scale quantum computing, error correction is widely regarded as essential for containing errors as computations grow.

Classical repetition codes

Repetition codes are among the simplest error-correcting codes. The idea is straightforward: repeat each bit several times. For example, a three-bit repetition code can correct any single bit flip within the block. However if two bits flip, the majority is wrong and decoding produces the wrong bit.

EncodingDecoding
0↦0000 \mapsto 000abc↦majority⁡(a,b,c)abc \mapsto \operatorname{majority}(a, b, c)
1↦1111 \mapsto 111

Suppose each bit passes through a binary symmetric channel that flips it with probability pp, independently of the others. Decoding fails when two or all three bits flip, with probability . For p<1/2p < 1/2, this is smaller than pp, so the encoded block is less likely to fail than a single bit.

00111 − p = 0.851 − p = 0.85p = 0.15
0.15
0.00.51.03p² − 2p³0.51.0perror probability
Encoded
Received
???
Majority
?

The improvement comes at a cost: three physical bits are used to encode one logical bit. Longer repetition blocks push the failure probability lower, making errors rare enough for reliable computation, but never eliminating the possibility of failure.

Repetition code for qubits

The three-bit repetition code can also encode a qubit:

α∣0⟩+β∣1⟩  ↦  α∣000⟩+β∣111⟩\alpha|0\rangle + \beta|1\rangle \;\mapsto\; \alpha|000\rangle + \beta|111\rangle

Nothing here is being copied. The three qubits on the right are entangled with one another, rather than being three separate qubits in the state α∣0⟩+β∣1⟩\alpha|0\rangle + \beta|1\rangle, which cannot be produced by copying an unknown quantum state. The amplitudes α\alpha and β\beta belong to the block as a whole.

This circuit performs the encoding:

X
α∣0⟩+β∣1⟩\alpha|0\rangle + \beta|1\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
α∣010⟩+β∣101⟩\alpha|010\rangle + \beta|101\rangle

Qubit 2 has flipped

Correctable, recover the original state α|000⟩ + β|111⟩.

The classical approach for code recovery is to inspect the three bits and take the majority. That cannot be done here. Measuring the three qubits would collapse the superposition, producing 010010 or 101101 and destroying the information carried by α\alpha and β\beta. The state would be read at the cost of the state.

What is needed is the location of the flip, without learning anything about the encoded state. The two terms ∣010⟩|010\rangle and ∣101⟩|101\rangle have the same pattern of agreement and disagreement between neighbouring qubits: qubits 1 and 2 are different, and qubits 2 and 3 are different. These two comparisons are called parity checks. They give the same two-bit result for both terms, so the result reveals the location of the flip without revealing whether the state was ∣000⟩|000\rangle or ∣111⟩|111\rangle, and therefore without revealing α\alpha or β\beta.

Two extra qubits record these parity checks. Measuring them gives the two-bit syndrome.

X11XXX
α∣000⟩+β∣111⟩\alpha|000\rangle + \beta|111\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
α∣000⟩+β∣111⟩\alpha|000\rangle + \beta|111\rangle

Qubit 2 has flipped

Syndrome 11 identifies the error without touching the superposition, and X restores the qubit.

StateSyndromeCorrection
α∣000⟩+β∣111⟩\alpha|000\rangle + \beta|111\rangle00I⊗I⊗II \otimes I \otimes I
α∣100⟩+β∣011⟩\alpha|100\rangle + \beta|011\rangle10X⊗I⊗IX \otimes I \otimes I
α∣010⟩+β∣101⟩\alpha|010\rangle + \beta|101\rangle11I⊗X⊗II \otimes X \otimes I
α∣001⟩+β∣110⟩\alpha|001\rangle + \beta|110\rangle01I⊗I⊗XI \otimes I \otimes X

The code corrects a single XX error, but its protection is limited. Some error patterns produce a misleading syndrome and draw the wrong correction, and others produce no syndrome at all and pass through undetected. The classical repetition code has the same limit: a correction is only ever as good as the errors the code can tell apart.

Phase-flip errors

Bit flips are not the only errors a qubit can suffer. A phase-flip error is described by the ZZ gate: it leaves ∣0⟩|0\rangle unchanged but sends ∣1⟩|1\rangle to −∣1⟩-|1\rangle. The bit values stay the same, so the error is invisible in the computational basis. It becomes visible only when the two branches interfere.

Z
α∣0⟩+β∣1⟩\alpha|0\rangle + \beta|1\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
α∣000⟩−β∣111⟩\alpha|000\rangle - \beta|111\rangle

One phase flip

The block picks up a minus sign, while every qubit keeps its original bit value.

A ZZ error changes a phase and nothing else, leaving every qubit value exactly as it was. The parity checks compare values, so they read the same result before and after the error and report nothing.

Fortunately, a modified version of the repetition code can detect phase flips. The idea is to encode the logical qubit in the plus-minus basis, where a ZZ error acts like an ordinary bit flip, exchanging ∣+⟩|{+}\rangle and ∣−⟩|{-}\rangle.

HHHZ
α∣0⟩+β∣1⟩\alpha|0\rangle + \beta|1\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
α∣+−+⟩+β∣−+−⟩\alpha|{+}{-}{+}\rangle + \beta|{-}{+}{-}\rangle

Qubit 2 has flipped

In this basis, Z exchanges |+⟩ and |−⟩ on that qubit, so it acts as an ordinary flip.

The detection circuit is modified in the same way. Hadamards before and after the parity checks put the data qubits in the plus-minus basis, where a phase flip becomes an ordinary flip. The same syndrome can then locate it just as it locates a bit flip.

ZHHHHHH11ZZZ
α∣+++⟩+β∣−−−⟩\alpha|{+}{+}{+}\rangle + \beta|{-}{-}{-}\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
α∣+++⟩+β∣−−−⟩\alpha|{+}{+}{+}\rangle + \beta|{-}{-}{-}\rangle

Syndrome 11

The flip is located on qubit 2, and a Z on that qubit undoes it.

StateSyndromeCorrection
α∣+++⟩+β∣−−−⟩\alpha|{+}{+}{+}\rangle + \beta|{-}{-}{-}\rangle00I⊗I⊗II \otimes I \otimes I
α∣−++⟩+β∣+−−⟩\alpha|{-}{+}{+}\rangle + \beta|{+}{-}{-}\rangle10Z⊗I⊗IZ \otimes I \otimes I
α∣+−+⟩+β∣−+−⟩\alpha|{+}{-}{+}\rangle + \beta|{-}{+}{-}\rangle11I⊗Z⊗II \otimes Z \otimes I
α∣++−⟩+β∣−−+⟩\alpha|{+}{+}{-}\rangle + \beta|{-}{-}{+}\rangle01I⊗I⊗ZI \otimes I \otimes Z

The same measurement can be implemented with fewer Hadamard gates. Prepare the ancillas in ∣+⟩|{+}\rangle, control from them onto the data qubits, and measure the ancillas in the plus-minus basis.

HH
∣+⟩|+\rangle
∣+⟩|+\rangle

The code corrects a single ZZ error, but its protection is limited. Multiple phase flips can produce a misleading syndrome and lead to the wrong correction, while bit flips produce no phase-flip syndrome and pass through undetected. Each version of the repetition code can only correct the errors it can distinguish.

The nine-qubit Shor code

Neither repetition code is enough on its own: one corrects bit flips, the other phase flips. The nine-qubit Shor code combines both by concatenation. First, the logical qubit is encoded by the three-qubit phase-flip code. Then each of those three qubits is encoded again by the three-qubit bit-flip code, giving three blocks of three:

∣0⟩  ↦  122 (∣000⟩+∣111⟩)⊗(∣000⟩+∣111⟩)⊗(∣000⟩+∣111⟩)|0\rangle \;\mapsto\; \tfrac{1}{2\sqrt{2}}\,(|000\rangle + |111\rangle) \otimes (|000\rangle + |111\rangle) \otimes (|000\rangle + |111\rangle)
∣1⟩  ↦  122 (∣000⟩−∣111⟩)⊗(∣000⟩−∣111⟩)⊗(∣000⟩−∣111⟩)|1\rangle \;\mapsto\; \tfrac{1}{2\sqrt{2}}\,(|000\rangle - |111\rangle) \otimes (|000\rangle - |111\rangle) \otimes (|000\rangle - |111\rangle)
HHHXZX
X error
Z error
X correction
∣ψ⟩|\psi\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle

Block 1

Qubit 2 flipped

The inner code locates it and puts it back.

Block 2

No bit flip

Block 3

No bit flip

A Z in this block is invisible to the inner code and is left to the outer one.

sX=11 → q2
sX=00
sX=00

A qubit can have both errors at once: an XX and a ZZ can act on the same wire. Their order does not affect any observable outcome, since XZ=−ZXXZ = -ZX and the overall minus sign has no physical effect. The error can therefore be described simply as an XX and a ZZ acting on that qubit:

XZ=ZX

A bit flip has already been located and corrected within its block. A phase flip is different. It leaves every qubit’s computational-basis value unchanged, so none of the block’s parity checks change. The phase-flip component therefore remains undetected at this stage and must be handled by the outer code. To see what the outer code detects, it helps to see how a phase flip can be represented on the other side of a CNOT.

X and CNOT

X on targetX=XX on controlX=XX

Z and CNOT

Z on controlZ=ZZ on targetZ=ZZ

The key point is that a phase flip on any one of the three physical qubits in a block is equivalent to a phase flip on the block’s qubit before encoding. The CNOT identities establish this equivalence, as the demo shows explicitly. Thus, from the outer code’s perspective, a phase flip on any qubit in a block is simply a phase flip of that block.

HHHZ
inner encoding
Z error
∣ψ⟩|\psi\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
block 1
block 2
block 3

Everything to the right of the ≡\equiv is the three-qubit phase-flip code from the previous section. The equivalence means that the outer code can treat each three-qubit block as one qubit.

To correct the phase error, first undo the inner encoding so that each block becomes one qubit again. The outer syndrome can then be measured on those three qubits using the ∣+⟩|{+}\rangle ancilla circuit from the previous section. The syndrome identifies the block carrying the phase error, and once that block has been corrected the inner encoding is applied again.

HHHZHHZ
encode
decode
outer syndrome
re-encode
error
∣ψ⟩|\psi\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣+⟩|+\rangle
∣+⟩|+\rangle
00
11
block 1
block 2
block 3

There is no need to undo the inner encoding first. The outer syndrome can be measured directly on the nine physical qubits, using the same ∣+⟩|{+}\rangle ancilla circuit with each control fanned out over all three qubits of a block. Each ancilla then checks the phase parity between a pair of blocks, touching six qubits in all. The two measurement results identify which block carries the phase flip, and since a phase flip on any of its qubits has the same effect, applying ZZ to any one of the three corrects the error.

Also note that the two repairs are completely independent. The bit-flip correction reads only bit values and the phase-flip correction only relative phases, so neither is affected by the other. An XX leaves the phase syndrome unchanged, and a ZZ leaves the bit syndrome unchanged. If a qubit carries both errors, each correction removes its own part, and the two can be applied in either order.

HHHXZHHXZ
block phase checks
corrections
X errors
Z errors
∣ψ⟩|\psi\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
∣+⟩|+\rangle
∣+⟩|+\rangle
00
11
sX=11 → q2
sX=00
sX=00
block 1
block 2
block 3

A single-qubit error has only four relevant forms: no error, an XX, a ZZ, or both. Up to a global phase, the last case is the Pauli Y=iXZY = iXZ, so these are simply II, XX, YY, and ZZ. The two syndromes distinguish the four cases, while the two codes remove the bit-flip and phase-flip parts independently. That settles what the nine-qubit Shor code can correct. What remains is whether that protection is worth the cost when errors arrive at random, and what happens when an error falls outside these four cases.

Random errors

Start with the simplest noise model. Each of the nine qubits is struck independently with probability pp, and a struck qubit suffers an XX, a YY or a ZZ. Encoding, syndrome measurement and correction are taken to be perfect. The question is whether the protection pays for itself, since the encoded qubit has nine physical qubits exposed to errors, where a bare qubit has only one.

The nine-qubit Shor code is guaranteed to recover the encoded qubit when at most one of its nine qubits is struck:

Pr⁡(at most one qubit struck)=(1−p)9+9p(1−p)8\Pr(\text{at most one qubit struck}) = (1-p)^9 + 9p(1-p)^8

For simplicity, cases with two or more errors are not counted. Some happen to be harmless, such as two ZZ errors in the same block, but the nine-qubit code does not guarantee recovery in those cases. Leaving them out keeps the estimate conservative. A bare qubit comes through untouched with probability 1−p1-p, so the nine-qubit code comes out ahead when:

(1−p)9+9p(1−p)8>1−p(1-p)^9 + 9p(1-p)^8 > 1-p

At an error rate of p=1.5%p = 1.5\%, for example, the nine-qubit code guarantees recovery in 99.24% of rounds, compared with 98.50% for a bare qubit. That is a gain of only 0.74 percentage points.

1.50%
Guaranteed by the nine-qubit code99.24%
One bare qubit98.50%
80%90%100%0%3.2%10%error rate pprobability
Nine qubits after one round
?????????
Result
?

The two curves cross at p≈3.2%p \approx 3.2\%. Below that rate, the nine-qubit code is ahead. Above it, the extra exposure costs more than error correction wins back. Even at its best, however, the advantage is small. The code can correct one struck qubit out of nine, so the extra redundancy only pays off when physical errors are already sufficiently rare. Rounds with two or more errors are left out entirely, and in some of them the correction only makes things worse: two bit flips in one block lead it to flip the third qubit as well.

Moreover, the model is deliberately very tidy. Every error is one of the three Pauli operators, but real noise need not look like that. A qubit may undergo a small continuous rotation or lose energy to its surroundings. Yet correcting XX, YY, and ZZ is enough to handle those more general errors.

Unitary errors

The random-error model picks XX, YY, or ZZ at random. A coherent disturbance is different: a stray field applies one continuous rotation, so before syndrome measurement no Pauli error has been classically selected. Instead, the resulting state contains several Pauli-error components at once.

Up to an unobservable global phase, every one-qubit unitary is a rotation through an angle θ\theta about a unit axis n⃗=(nx,ny,nz)\vec n=(n_x,n_y,n_z), where nx2+ny2+nz2=1n_x^2+n_y^2+n_z^2=1. Define the Pauli operator in that direction by Pn⃗=nxX+nyY+nzZP_{\vec n}=n_xX+n_yY+n_zZ. Because Pn⃗2=IP_{\vec n}^2=I, its exponential separates into an identity part and a Pauli part:

U(n⃗,θ)=e−iθPn⃗/2=cos⁡θ2 I−isin⁡θ2 (nxX+nyY+nzZ)\begin{aligned}U(\vec n,\theta)&=e^{-i\theta P_{\vec n}/2}\\[6pt]&=\cos\tfrac{\theta}{2}\,I-i\sin\tfrac{\theta}{2}\,\bigl(n_xX+n_yY+n_zZ\bigr)\end{aligned}

The same unitary is therefore a linear combination of the four Pauli operators:

U=αI+βX+γY+δZU=\alpha I+\beta X+\gamma Y+\delta Z

Comparing this expansion with the rotation formula identifies each coefficient:

α=cos⁡θ2β=−inxsin⁡θ2γ=−inysin⁡θ2δ=−inzsin⁡θ2\begin{aligned}\alpha&=\cos\tfrac{\theta}{2}\\[4pt]\beta&=-in_x\sin\tfrac{\theta}{2}\\[4pt]\gamma&=-in_y\sin\tfrac{\theta}{2}\\[4pt]\delta&=-in_z\sin\tfrac{\theta}{2}\end{aligned}

To test the Shor code’s single-qubit guarantee, suppose this rotation acts on physical qubit kk. Write UkU_k for UU in position kk and the identity on the other eight qubits. The tensor product is linear in each position, so the Pauli expansion carries over term by term:

Uk=I⊗(k−1)⊗U⊗I⊗(9−k)=α I⊗9+β Xk+γ Yk+δ Zk\begin{aligned}U_k&=I^{\otimes(k-1)}\otimes U\otimes I^{\otimes(9-k)}\\[6pt]&=\alpha\,I^{\otimes9}+\beta\,X_k+\gamma\,Y_k+\delta\,Z_k\end{aligned}

Applied to the encoded state ∣ψL⟩|\psi_L\rangle, it produces four states of the full nine-qubit code:

Uk∣ψL⟩=α ∣ψL⟩+β Xk∣ψL⟩+γ Yk∣ψL⟩+δ Zk∣ψL⟩U_k|\psi_L\rangle=\alpha\,|\psi_L\rangle+\beta\,X_k|\psi_L\rangle+\gamma\,Y_k|\psi_L\rangle+\delta\,Z_k|\psi_L\rangle

This is a superposition of four branches: the untouched codeword and the three single-qubit errors the Shor code already corrects. For this fixed qubit kk, the four branches belong to distinct syndrome subspaces and are orthogonal, so their squared magnitudes are the four syndrome probabilities:

pI=∣α∣2=cos⁡2θ2pX=∣β∣2=nx2sin⁡2θ2pY=∣γ∣2=ny2sin⁡2θ2pZ=∣δ∣2=nz2sin⁡2θ2pI+pX+pY+pZ=1\begin{aligned}p_I&=|\alpha|^2=\cos^2\tfrac{\theta}{2}\\[4pt]p_X&=|\beta|^2=n_x^2\sin^2\tfrac{\theta}{2}\\[4pt]p_Y&=|\gamma|^2=n_y^2\sin^2\tfrac{\theta}{2}\\[4pt]p_Z&=|\delta|^2=n_z^2\sin^2\tfrac{\theta}{2}\\[6pt]p_I+p_X+p_Y+p_Z&=1\end{aligned}

The angle sets the total error weight sin⁡2(θ/2)\sin^2(\theta/2), while the axis determines how that weight is split among XX, YY, and ZZ. In the demo, the buttons set n⃗\vec n and the slider sets θ\theta. The formula shows the resulting amplitudes, while the bars show the corresponding syndrome probabilities.

nθ|0⟩|1⟩|+⟩|−⟩|i⟩|−i⟩

axis nrotation θ

Rotation axis

72°
Uk∣ψL⟩=0.809 ∣ψL⟩−0.339i Xk∣ψL⟩−0.339i Yk∣ψL⟩−0.339i Zk∣ψL⟩U_k|\psi_L\rangle = 0.809\,|\psi_L\rangle - 0.339i\,X_k|\psi_L\rangle - 0.339i\,Y_k|\psi_L\rangle - 0.339i\,Z_k|\psi_L\rangle
BranchSyndromeProbabilityCorrection
∣ψL⟩|\psi_L\rangleNothing flagged
65.5%
II
Xk∣ψL⟩X_k|\psi_L\rangleBit check names qubit k
11.5%
XkX_k
Yk∣ψL⟩Y_k|\psi_L\rangleBit and phase checks both
11.5%
YkY_k
Zk∣ψL⟩Z_k|\psi_L\ranglePhase check names k’s block
11.5%
ZZon any qubit of that block

Measuring the syndrome projects the state onto one branch, with the probability shown.

The syndrome measurement projects the superposition onto one of the four error branches. Each branch has a distinct syndrome, so the measurement identifies which Pauli error branch was selected without revealing the encoded state ∣ψL⟩|\psi_L\rangle. The corresponding correction then restores the encoded state.

The code therefore never needs to estimate the continuous angle or axis. It only needs to distinguish the four Pauli error subspaces and apply the corresponding correction. This is the discretization of errors: the physical disturbance can vary continuously, but syndrome measurement reduces its effect to one of a discrete set of correctable outcomes.

It is good news that the nine-qubit Shor code can correct arbitrary one-qubit unitary errors, not just clean XX, YY, and ZZ errors. But this result still assumes that the syndrome measurements and correction operations are perfect. In a real device, those operations can be noisy too, and the code does not automatically protect them. Making error correction work in practice therefore requires protecting the error-correction process itself. How fun is that!

Arbitrary errors

A unitary error describes a disturbance that keeps the qubit’s state pure. Real noise can be more general. A qubit may lose energy to its surroundings or become entangled with them, leaving the qubit itself in a mixed state. When the surroundings are not observed, this evolution is described by a quantum channel Φ\Phi, represented by one or more Kraus operators AjA_j:

Φ(ρ)=∑jAjρAj†\Phi(\rho)=\sum_j A_j\rho A_j^{\dagger}

The index jj labels the different components of the noise process. These components arise from the possible states of the surroundings and do not represent a classical choice made before the error. For Φ\Phi to preserve total probability, its Kraus operators must satisfy:

∑jAj†Aj=I\sum_j A_j^{\dagger}A_j=I

Every AjA_j is a 2×22\times2 matrix, so the four Pauli operators form a basis for it just as they did for the unitary rotation:

Aj=αj I+βj X+γj Y+δj ZA_j=\alpha_j\,I+\beta_j\,X+\gamma_j\,Y+\delta_j\,Z

Suppose the channel acts on physical qubit kk. Each Kraus operator then becomes the same combination of II, XkX_k, YkY_k, and ZkZ_k, so the channel acts on the encoded state as:

Φk(∣ψL⟩⟨ψL∣)=∑j(αj I+βj Xk+γj Yk+δj Zk) ∣ψL⟩⟨ψL∣ (αj I+βj Xk+γj Yk+δj Zk)†\begin{aligned}&\Phi_k\bigl(|\psi_L\rangle\langle\psi_L|\bigr)\\[4pt]&\quad=\sum_j\bigl(\alpha_j\,I+\beta_j\,X_k+\gamma_j\,Y_k+\delta_j\,Z_k\bigr)\,|\psi_L\rangle\langle\psi_L|\,\bigl(\alpha_j\,I+\beta_j\,X_k+\gamma_j\,Y_k+\delta_j\,Z_k\bigr)^{\dagger}\end{aligned}

Every term is a superposition of the same four branches as a unitary error. Computing and measuring the syndrome, then correcting the Pauli error it names, therefore leaves the syndrome qubits and the data in the state:

ξ⊗∣ψL⟩⟨ψL∣ξ=∑j(∣αj∣2 ∣I syndrome⟩⟨I syndrome∣+∣βj∣2 ∣Xk syndrome⟩⟨Xk syndrome∣+∣γj∣2 ∣Yk syndrome⟩⟨Yk syndrome∣+∣δj∣2 ∣Zk syndrome⟩⟨Zk syndrome∣)\begin{gathered}\xi\otimes|\psi_L\rangle\langle\psi_L|\\[8pt]\begin{aligned}\xi=\sum_j\Bigl(&|\alpha_j|^2\,|I\text{ syndrome}\rangle\langle I\text{ syndrome}|\\[4pt]&+|\beta_j|^2\,|X_k\text{ syndrome}\rangle\langle X_k\text{ syndrome}|\\[4pt]&+|\gamma_j|^2\,|Y_k\text{ syndrome}\rangle\langle Y_k\text{ syndrome}|\\[4pt]&+|\delta_j|^2\,|Z_k\text{ syndrome}\rangle\langle Z_k\text{ syndrome}|\Bigr)\end{aligned}\end{gathered}

Whatever the channel, the data return to ∣ψL⟩⟨ψL∣|\psi_L\rangle\langle\psi_L|, and all of the noise is transferred to the syndrome qubits. The probability of each syndrome is the weight of the matching Pauli term, summed over all the Kraus operators:

pI=∑j∣αj∣2pX=∑j∣βj∣2pY=∑j∣γj∣2pZ=∑j∣δj∣2\begin{aligned}p_I&=\sum_j|\alpha_j|^2\\[6pt]p_X&=\sum_j|\beta_j|^2\\[6pt]p_Y&=\sum_j|\gamma_j|^2\\[6pt]p_Z&=\sum_j|\delta_j|^2\end{aligned}

These four probabilities always add to one, a consequence of the Kraus condition ∑jAj†Aj=I\sum_j A_j^{\dagger}A_j=I.

The demo applies three channels to qubit kk: random Pauli errors, phase flips, and amplitude damping.

Channel on qubit k

0.50
|0⟩|1⟩|+⟩|−⟩|i⟩|−i⟩

inputchannel output

The qubit leaks energy into its surroundings, so ∣1⟩|1\rangle relaxes to ∣0⟩|0\rangle with probability λ\lambda. This is neither a rotation nor a random Pauli error, yet both Kraus operators still break down into Paulis.

A0=(1001−λ)=1+1−λ2 I+1−1−λ2 ZA1=(0λ00)=λ2 (X+iY)\begin{aligned}A_0&=\begin{pmatrix}1&0\\0&\sqrt{1-\lambda}\end{pmatrix}=\frac{1+\sqrt{1-\lambda}}{2}\,I+\frac{1-\sqrt{1-\lambda}}{2}\,Z\\[10pt]A_1&=\begin{pmatrix}0&\sqrt{\lambda}\\0&0\end{pmatrix}=\frac{\sqrt{\lambda}}{2}\,\bigl(X+iY\bigr)\end{aligned}
Kraus operatorSame operator in the Pauli basis
A0=(1.000000.707)A_0 = \begin{pmatrix} 1.000 & 0 \\ 0 & 0.707 \end{pmatrix}0.854 I+0.146 Z0.854\,I + 0.146\,Z
A1=(00.70700)A_1 = \begin{pmatrix} 0 & 0.707 \\ 0 & 0 \end{pmatrix}0.354 X+0.354i Y0.354\,X + 0.354i\,Y
BranchSyndromeProbabilityCorrection
∣ψL⟩|\psi_L\rangleNothing flagged
72.9%
II
Xk∣ψL⟩X_k|\psi_L\rangleBit check names qubit k
12.5%
XkX_k
Yk∣ψL⟩Y_k|\psi_L\rangleBit and phase checks both
12.5%
YkY_k
Zk∣ψL⟩Z_k|\psi_L\ranglePhase check names k’s block
2.1%
ZZon any qubit of that block

Measuring the syndrome projects the state onto one branch, with the probability shown.

The recovery does not invert an entire Kraus operator. In amplitude damping, A1A_1 is not even invertible. Instead, decompose the Kraus operator into Pauli components. Each component acts like a particular Pauli error on the affected qubit, and the nine-qubit Shor code can correct each of those single-qubit Pauli errors separately. By linearity, correcting the individual components also corrects their superposition.

This works only for errors affecting one physical qubit at a time. An error process acting jointly on two qubits can contain products such as XrZsX_rZ_s, which act nontrivially on both qubits and are outside the Shor code’s correction guarantee. That is why the random-error estimate counted only cases with at most one error.

The price is steep: nine physical qubits for one logical qubit, with a break-even point near 3% in the simplified random-error model. Better error-correcting codes have been developed since, though none of them is perfect yet. The hope is that, together with less noisy hardware, they will eventually make large quantum computers reliable enough for long computations. The result the nine-qubit Shor code shows is more fundamental: a quantum error-correcting code can protect quantum information from noise without needing to know which error occurred.

The stabilizer formalism

The protects one logical qubit using nine physical qubits. Its circuits extract a syndrome by asking a small set of parity questions about the physical qubits, without measuring the logical state. So although technically only a small set of questions is asked, encoding just the basis state ∣0⟩|0\rangle already gives a superposition of eight nine-bit strings, and ∣1⟩|1\rangle gives eight more with minus signs:

∣0⟩  ↦  122 (∣000⟩+∣111⟩)⊗(∣000⟩+∣111⟩)⊗(∣000⟩+∣111⟩)|0\rangle\;\mapsto\;\dfrac{1}{2\sqrt2}\,\bigl(|000\rangle+|111\rangle\bigr)\otimes\bigl(|000\rangle+|111\rangle\bigr)\otimes\bigl(|000\rangle+|111\rangle\bigr)
∣1⟩  ↦  122 (∣000⟩−∣111⟩)⊗(∣000⟩−∣111⟩)⊗(∣000⟩−∣111⟩)|1\rangle\;\mapsto\;\dfrac{1}{2\sqrt2}\,\bigl(|000\rangle-|111\rangle\bigr)\otimes\bigl(|000\rangle-|111\rangle\bigr)\otimes\bigl(|000\rangle-|111\rangle\bigr)

Nine qubits are still manageable, but a state of nn qubits can need 2n2^n amplitudes, so writing out encoded states stops being practical for codes large enough to be useful. The stabilizer formalism provides a compact language for describing the parity questions a code asks and the states they test.

A stabilizer is an operator that describes a property shared by all valid encoded states. Measuring a set of stabilizers therefore provides a collection of checks on the physical qubits. If an error occurs, it can change the outcome of one or more checks. The resulting pattern tells the recovery procedure which error has occurred, or narrows it down enough to choose the appropriate correction, without revealing the logical state.

Pauli operations

The checks used by the stabilizer formalism are constructed from simple operators acting on individual qubits. The basic set consists of the identity II and the three XX, YY, and ZZ:

I=(1001)I=\begin{pmatrix}1&0\\0&1\end{pmatrix}X=(0110)X=\begin{pmatrix}0&1\\1&0\end{pmatrix}Y=(0−ii0)Y=\begin{pmatrix}0&-i\\i&0\end{pmatrix}Z=(100−1)Z=\begin{pmatrix}1&0\\0&-1\end{pmatrix}

A useful property of the Pauli operators is that any two different non-identity operators anticommute. Swapping their order therefore changes the sign of their product:

For the cyclic pairs XYXY, YZYZ, and ZXZX, the product gives the remaining Pauli operator multiplied by ii. Reversing the order changes ii to −i-i:

Each Pauli operator also squares to the identity:

An n-qubit Pauli string assigns one of II, XX, YY, or ZZ to each of the nn qubits and takes their tensor product. Its weight is the number of non-identity factors, that is, the number of qubits on which it acts nontrivially. The weight therefore counts how many qubits a Pauli operator acts on.

weight 6

Given nn-qubit Pauli strings P1,…,PrP_1,\dots,P_r, the set generated by them contains the identity and every product of the generators, with each generator used any number of times and in any order. It is written:

⟨P1,…,Pr⟩\langle P_1,\dots,P_r\rangle

Multiplying Pauli strings can introduce a factor of ii, −1-1, or −i-i, so every element is one of the phases 1, i, −1, −i1,\,i,\,-1,\,-i times an nn-qubit Pauli string. There are only 4⋅4n4\cdot4^n such combinations, so the generated set is always finite. In the demo, each element appears with the shortest product of generators that gives it. After a few factors the products stop producing new elements, and the board marks which of the 4⋅4n4\cdot4^n combinations the set contains.

II
1i−1−i
XX
1i−1−i
YY
1i−1−i
ZZ
1i−1−i

8 of the 4⋅41=164\cdot4^{1}=16 possible elements

⟨X, Z⟩={I, X, Z, iY, −I, −X, −Z, −iY}\langle X,\,Z\rangle=\{I,\,X,\,Z,\,iY,\,-I,\,-X,\,-Z,\,-iY\}

Pauli observables

A Pauli operator can act as a gate, but it can also define a measurement. To see how its measurement outcomes arise, start with the action of ZZ on the two standard basis states:

The states ∣0⟩|0\rangle and ∣1⟩|1\rangle keep the same direction when ZZ acts on them, changing only by a factor of +1+1 or −1-1. They are eigenstates of ZZ, and these multiplying factors are their eigenvalues: +1+1 for ∣0⟩|0\rangle and −1-1 for ∣1⟩|1\rangle.

For XX, its spectral decomposition identifies two eigenstates, ∣+⟩|+\rangle and ∣−⟩|-\rangle, corresponding to the eigenvalues +1+1 and −1-1:

∣+⟩=12(∣0⟩+∣1⟩)∣−⟩=12(∣0⟩−∣1⟩)|+\rangle=\dfrac{1}{\sqrt2}\bigl(|0\rangle+|1\rangle\bigr)\qquad|-\rangle=\dfrac{1}{\sqrt2}\bigl(|0\rangle-|1\rangle\bigr)

For YY, the spectral decomposition gives two eigenstates that contain ii in their amplitudes, while their eigenvalues are again +1+1 and −1-1:

∣+i⟩=12(∣0⟩+i∣1⟩)∣−i⟩=12(∣0⟩−i∣1⟩)|{+i}\rangle=\dfrac{1}{\sqrt2}\bigl(|0\rangle+i|1\rangle\bigr)\qquad|{-i}\rangle=\dfrac{1}{\sqrt2}\bigl(|0\rangle-i|1\rangle\bigr)

All three operators have the same two eigenvalues, +1+1 and −1-1. Each Pauli operator satisfies P2=IP^2=I, so applying it twice must bring any state back to where it started. For an eigenstate, one application multiplies the state by its eigenvalue λ\lambda, so applying the operator twice multiplies it by λ2\lambda^2. Returning to the original state therefore requires λ2=1\lambda^2=1, giving λ=+1\lambda=+1 or −1-1.

The factors ii and −i-i appear in products of different Pauli operators, such as XY=iZXY=iZ and YX=−iZYX=-iZ. They are phases of those products, not eigenvalues of the individual operators XX, YY, and ZZ.

From operators to measurements

To turn a Pauli operator into a measurement, use its eigenstates as the possible states after measurement. For ZZ, the two outcomes correspond to the eigenstates ∣0⟩|0\rangle and ∣1⟩|1\rangle. A general state can be written as a combination of these eigenstates, and the measurement yields one of them with probabilities determined by the corresponding components of the original state. After the measurement, the state is projected onto the eigenspace associated with the observed outcome. The same construction applies to XX and YY, using their respective eigenstates.

Each outcome is represented by a projector onto its eigenspace:

In each case, the two projectors sum to the identity, defining a two-outcome with outcomes +1+1 and −1-1. The +1+1 outcome uses the projector onto the +1+1 eigenspace, and the −1-1 outcome uses the projector onto the −1-1 eigenspace.

Measuring through an ancilla

The projective measurement just described can be implemented by coupling the data to an ancilla and measuring the ancilla instead of the data qubits. This does not avoid the state update of a projective measurement: for a general data state, the measurement still projects it onto the eigenspace corresponding to the observed outcome. The advantage is that the data qubits are not directly measured, so a Pauli observable can be measured without revealing the individual data-qubit states.

Prepare the ancilla in ∣+⟩|+\rangle, apply a controlled-PP with the ancilla as the control, and finish with a Hadamard on the ancilla. For an XX measurement, the circuit is:

∣ψ⟩|\psi\rangle
controlled-P\text{controlled-}P
∣+⟩|+\rangle
{0+1 eigenvalue1−1 eigenvalue\begin{cases}0 & {+1}\text{ eigenvalue}\\ 1 & {-1}\text{ eigenvalue}\end{cases}

This is a single-qubit instance of phase estimation, using to distinguish the two eigenspaces of a Pauli operator. The ancilla encodes which eigenvalue was obtained, so measuring the ancilla reveals the measurement outcome without directly measuring the data qubits.

For a data state that is not an eigenstate, let Π+\Pi_{\small+} and Π−\Pi_{\small-} be the projectors onto the +1+1 and −1-1 eigenspaces of PP, so that P=Π+−Π−P=\Pi_{\small+}-\Pi_{\small-} and I=Π++Π−I=\Pi_{\small+}+\Pi_{\small-}. The circuit acts on ∣ψ⟩∣+⟩|\psi\rangle|+\rangle as

After the controlled-PP and the final Hadamard, the joint state is Π+∣ψ⟩∣0⟩+Π−∣ψ⟩∣1⟩\Pi_{\small+}|\psi\rangle|0\rangle+\Pi_{\small-}|\psi\rangle|1\rangle. Measuring the ancilla selects one of these two orthogonal branches:

  • Outcome 00 occurs with probability ∥Π+∣ψ⟩∥2\lVert\Pi_{\small+}|\psi\rangle\rVert^2. The data state becomes the normalized state Π+∣ψ⟩\Pi_{\small+}|\psi\rangle, which lies in the +1+1 eigenspace.
  • Outcome 11 occurs with probability ∥Π−∣ψ⟩∥2\lVert\Pi_{\small-}|\psi\rangle\rVert^2. The data state becomes the normalized state Π−∣ψ⟩\Pi_{\small-}|\psi\rangle, which lies in the −1-1 eigenspace.

Measuring PP directly, as the {Π+,Π−}\{\Pi_{\small+},\Pi_{\small-}\}, gives the same result. The outcome is +1+1 with probability Pr(+1)=∥Π+∣ψ⟩∥2\mathrm{Pr}(+1)=\lVert\Pi_{\small+}|\psi\rangle\rVert^2 and −1-1 with probability Pr(−1)=∥Π−∣ψ⟩∥2\mathrm{Pr}(-1)=\lVert\Pi_{\small-}|\psi\rangle\rVert^2, and the data is left in the normalized Π+∣ψ⟩\Pi_{\small+}|\psi\rangle or Π−∣ψ⟩\Pi_{\small-}|\psi\rangle respectively. The ancilla circuit therefore matches a direct measurement of PP in both its outcome statistics and its , without ever measuring the data qubits.

Pauli operations on nn qubits

The same construction extends to nn-qubit Pauli operators, formed as tensor products of single-qubit Pauli matrices and identities, such as Z⊗ZZ\otimes Z or X⊗I⊗YX\otimes I\otimes Y. Each such operator squares to the identity, so its only eigenvalues are +1+1 and −1-1, giving a two-outcome projective measurement. For Z⊗ZZ\otimes Z,

Z⊗Z=(∣0⟩⟨0∣−∣1⟩⟨1∣)⊗(∣0⟩⟨0∣−∣1⟩⟨1∣)=∣00⟩⟨00∣−∣01⟩⟨01∣−∣10⟩⟨10∣+∣11⟩⟨11∣=(∣00⟩⟨00∣+∣11⟩⟨11∣)−(∣01⟩⟨01∣+∣10⟩⟨10∣).\begin{aligned}Z\otimes Z&=\bigl(|0\rangle\langle0|-|1\rangle\langle1|\bigr)\otimes\bigl(|0\rangle\langle0|-|1\rangle\langle1|\bigr)\\[4pt]&=\textcolor{#2563eb}{|00\rangle\langle00|}\textcolor{#b45309}{{}-|01\rangle\langle01|-|10\rangle\langle10|}\textcolor{#2563eb}{{}+|11\rangle\langle11|}\\[4pt]&=\textcolor{#2563eb}{\bigl(|00\rangle\langle00|+|11\rangle\langle11|\bigr)}-\textcolor{#b45309}{\bigl(|01\rangle\langle01|+|10\rangle\langle10|\bigr)}.\end{aligned}

Each outcome has its own projector:

  • Outcome +1\textcolor{#2563eb}{+1}, the two bits have the same value: Π+=∣00⟩⟨00∣+∣11⟩⟨11∣\textcolor{#2563eb}{\Pi_{\small+}=|00\rangle\langle00|+|11\rangle\langle11|}
  • Outcome −1\textcolor{#b45309}{-1}, the two bits have different values: Π−=∣01⟩⟨01∣+∣10⟩⟨10∣\textcolor{#b45309}{\Pi_{\small-}=|01\rangle\langle01|+|10\rangle\langle10|}

The measurement therefore determines their parity without determining either bit individually. This is not the same as measuring both qubits in the standard basis. Measuring each qubit reveals both bits, so a state such as α∣00⟩+β∣11⟩\alpha|00\rangle+\beta|11\rangle collapses to ∣00⟩|00\rangle or ∣11⟩|11\rangle. The Z⊗ZZ\otimes Z measurement reveals only the parity, and since both terms have even parity, it leaves the superposition intact. This is what lets a parity check detect errors without disturbing the encoded state.

The parity-check circuit

The same ancilla-based construction also applies to multi-qubit Pauli measurements. Instead of measuring a single-qubit Pauli such as ZZ, the operator PP can be a tensor product such as Z⊗ZZ\otimes Z. The ancilla then records the eigenvalue of the joint operator, allowing a property of several qubits to be measured without measuring them individually.

For Z⊗ZZ\otimes Z, that property is the parity of the two data bits. The parity of bits b1b_1 and b2b_2 is b1⊕b2b_1\oplus b_2, their sum modulo 2, which is 0\textcolor{#2563eb}{0} when the bits agree and 1\textcolor{#b45309}{1} when they differ. It matches the eigenvalues of Z⊗ZZ\otimes Z: ∣00⟩|00\rangle and ∣11⟩|11\rangle have parity 0\textcolor{#2563eb}{0} and lie in the +1\textcolor{#2563eb}{+1} eigenspace, while ∣01⟩|01\rangle and ∣10⟩|10\rangle have parity 1\textcolor{#b45309}{1} and lie in the −1\textcolor{#b45309}{-1} eigenspace. The ancilla outcome is therefore the parity bit.

The controlled operation applies Z⊗ZZ\otimes Z to the data when the ancilla is in the ∣1⟩|1\rangle branch. This can be implemented using two controlled-ZZ gates, both controlled by the same ancilla:

∣ψ⟩∣0⟩  ⟼  ∣ψ⟩∣0⟩∣ψ⟩∣1⟩  ⟼  (Z⊗Z)∣ψ⟩∣1⟩|\psi\rangle|0\rangle\;\longmapsto\;|\psi\rangle|0\rangle\qquad\qquad|\psi\rangle|1\rangle\;\longmapsto\;(Z\otimes Z)|\psi\rangle|1\rangle

On the ∣1⟩|1\rangle branch, the first controlled-ZZ applies ZZ to the first data qubit and the second applies ZZ to the second data qubit. Together, their action is exactly Z⊗ZZ\otimes Z, and the final Hadamard then sorts the data terms by parity:

Measuring the ancilla keeps either the even-parity or odd-parity part of the data, while preserving the superposition within that parity sector. For Z⊗ZZ\otimes Z, outcome 0\textcolor{#2563eb}{0} keeps the ∣00⟩|00\rangle and ∣11⟩|11\rangle components, while outcome 1\textcolor{#b45309}{1} keeps the ∣01⟩|01\rangle and ∣10⟩|10\rangle components. Thus, an outcome of 1\textcolor{#b45309}{1} does not distinguish ∣01⟩|01\rangle from ∣10⟩|10\rangle. It only tells that the two bits are different.

A Z⊗ZZ\otimes Z measurement of two qubits is therefore a measurement of their parity. The complete circuit is:

∣ψ⟩|\psi\rangle
∣+⟩|+\rangle
controlled-(Z⊗Z)\text{controlled-}(Z\otimes Z)
{0+1 eigenvalue1−1 eigenvalue\begin{cases}0 & {+1}\text{ eigenvalue}\\ 1 & {-1}\text{ eigenvalue}\end{cases}

An equivalent circuit replaces the two controlled-ZZ gates with two CNOTs that target the ancilla. The ancilla then starts in ∣0⟩|0\rangle and needs no Hadamard:

∣ψ⟩|\psi\rangle
∣0⟩|0\rangle
{0+1 eigenvalue1−1 eigenvalue\begin{cases}0 & {+1}\text{ eigenvalue}\\ 1 & {-1}\text{ eigenvalue}\end{cases}

So, a Z⊗ZZ\otimes Z measurement can be implemented as a parity check using two CNOTs. The same construction measures X⊗XX\otimes X, with controlled-XX gates in place of controlled-ZZ gates.

Stabilizers in the Repetition Code

The stores one input qubit in the span of ∣000⟩|000\rangle and ∣111⟩|111\rangle. The encoded amplitudes are unknown, so error detection must preserve both basis states and any superposition of them:

α∣0⟩+β∣1⟩  ⟼  ∣ψL⟩=α∣000⟩+β∣111⟩\alpha|0\rangle+\beta|1\rangle\;\longmapsto\;|\psi_L\rangle=\alpha|000\rangle+\beta|111\rangle

A check should therefore distinguish whether neighboring qubits have the same value without distinguishing ∣000⟩|000\rangle from ∣111⟩|111\rangle. This can be done with the multi-qubit Pauli operators Z⊗Z⊗IZ\otimes Z\otimes I and I⊗Z⊗ZI\otimes Z\otimes Z, which check qubits 1–2 and 2–3 respectively. Since the checked qubits have the same value in both ∣000⟩|000\rangle and ∣111⟩|111\rangle, both checks return +1+1 on every encoded state:

A Pauli operator that leaves every encoded state unchanged is called a stabilizer of the code. The two parity checks are independent stabilizers, chosen as generators of the stabilizer group. Multiplying them gives another stabilizer, (Z⊗Z⊗I)(I⊗Z⊗Z)=Z⊗I⊗Z(Z\otimes Z\otimes I)(I\otimes Z\otimes Z)=Z\otimes I\otimes Z, because Z2=IZ^2=I on the middle qubit. This third stabilizer is therefore already generated by the first two. Together with the identity, the stabilizers form the stabilizer group:

⟨Z⊗Z⊗I,  I⊗Z⊗Z⟩={I⊗I⊗I,  Z⊗Z⊗I,  I⊗Z⊗Z,  Z⊗I⊗Z}\langle Z\otimes Z\otimes I,\;I\otimes Z\otimes Z\rangle=\{I\otimes I\otimes I,\;Z\otimes Z\otimes I,\;I\otimes Z\otimes Z,\;Z\otimes I\otimes Z\}

Each generator is measured with its own ancilla, using the parity-measurement circuit on the two qubits it involves:

−1+1X
∣ψL⟩|\psi_L\rangle
(X⊗I⊗I)∣ψL⟩(X\otimes I\otimes I)|\psi_L\rangle

Bit flip on qubit 1

The signs (−1, +1) single out this qubit.

∣0⟩|0\rangle
∣0⟩|0\rangle
Z⊗Z⊗IZ\otimes Z\otimes I
I⊗Z⊗ZI\otimes Z\otimes Z

A bit flip moves the encoded state out of the +1+1 eigenspace of the stabilizers that cover the flipped qubit. The resulting change in signs reveals which checks detect the error and therefore which qubit was flipped.

To see where these signs come from, apply a check to the errored state and commute the check operator past the error operator until it acts directly on ∣ψL⟩|\psi_L\rangle. Since the check leaves ∣ψL⟩|\psi_L\rangle unchanged, the remaining sign is the measurement outcome:

(Z⊗Z⊗I)(X⊗I⊗I)∣ψL⟩=−(X⊗I⊗I)(Z⊗Z⊗I)∣ψL⟩=−(X⊗I⊗I)∣ψL⟩(I⊗Z⊗Z)(X⊗I⊗I)∣ψL⟩=(X⊗I⊗I)(I⊗Z⊗Z)∣ψL⟩=(X⊗I⊗I)∣ψL⟩\begin{aligned}\textcolor{#0284c7}{(Z\otimes Z\otimes I)}\textcolor{#e11d48}{(X\otimes I\otimes I)}|\psi_L\rangle&=-\textcolor{#e11d48}{(X\otimes I\otimes I)}\textcolor{#0284c7}{(Z\otimes Z\otimes I)}|\psi_L\rangle=-\textcolor{#e11d48}{(X\otimes I\otimes I)}\textcolor{#084e79}{|\psi_L\rangle}\\[4pt]\textcolor{#0284c7}{(I\otimes Z\otimes Z)}\textcolor{#e11d48}{(X\otimes I\otimes I)}|\psi_L\rangle&=\textcolor{#e11d48}{(X\otimes I\otimes I)}\textcolor{#0284c7}{(I\otimes Z\otimes Z)}|\psi_L\rangle=\textcolor{#e11d48}{(X\otimes I\otimes I)}\textcolor{#084e79}{|\psi_L\rangle}\end{aligned}

The sign appears when the check and error are swapped. Because both operators are tensor products, they can be compared one qubit at a time. A Z\textcolor{#0284c7}{Z} in the check contributes a factor of −1-1 when it meets an X\textcolor{#e11d48}{X} in the error, since ZX=−XZ\textcolor{#0284c7}{Z}\textcolor{#e11d48}{X}=-\textcolor{#e11d48}{X}\textcolor{#0284c7}{Z}. If either operator has II on that qubit, they commute and contribute +1+1. The overall eigenvalue is therefore determined by the parity of the overlap: a check returns −1-1 when it covers an odd number of flipped qubits and +1+1 when it covers an even number.

The two measured signs form the syndrome. For a single bit flip, each qubit produces a distinct pair of signs, allowing the flipped qubit to be identified:

ErrorZ⊗Z⊗IZ\otimes Z\otimes II⊗Z⊗ZI\otimes Z\otimes ZReading
I⊗I⊗II\otimes I\otimes I+1+1No bit flip
X⊗I⊗IX\otimes I\otimes I−1+1Qubit 1
I⊗X⊗II\otimes X\otimes I−1−1Qubit 2
I⊗I⊗XI\otimes I\otimes X+1−1Qubit 3

For multiple bit flips, the same parity rule applies: each check returns −1-1 for an odd number of overlapping flips and +1+1 for an even number. These two checks therefore distinguish all single-bit errors, but they cannot uniquely distinguish every possible multiple-bit-flip pattern.

The two signs split the 8-dimensional space of three qubits into four 2-dimensional subspaces, one for each syndrome, with the code space as the (+1,+1)(+1,+1) subspace. The Pauli operations split the same way: ignoring phases, the 64 three-qubit Pauli operations fall into four collections of 16, so that, for example, I⊗I⊗ZI\otimes I\otimes Z, Z⊗Z⊗ZZ\otimes Z\otimes Z, and X⊗X⊗XX\otimes X\otimes X all give (+1,+1)(+1,+1).

I⊗Z⊗ZI\otimes Z\otimes Z
+1+1−1-1
Z⊗Z⊗IZ\otimes Z\otimes I+1+1
∣000⟩|000\rangle
∣111⟩|111\rangle
∣001⟩|001\rangle
∣110⟩|110\rangle
−1-1
∣100⟩|100\rangle
∣011⟩|011\rangle
∣010⟩|010\rangle
∣101⟩|101\rangle

The ZZ in a check specifies the Pauli observable being measured. It does not indicate a ZZ error. These ZZ-type checks detect XX bit flips because ZZ and XX anticommute. A phase flip ZZ, by contrast, commutes with both checks and therefore produces no change in the syndrome. The extends this construction with additional checks that can detect phase flips as well.

Stabilizer codes

The is a simple example of a more general way to construct quantum error-correcting codes: specify a code space through a set of Pauli checks rather than listing its basis states explicitly. This idea extends naturally from the three-qubit repetition code to arbitrary numbers of qubits.

For an nn-qubit system, let P1,…,PrP_1,\ldots,P_r be the Pauli checks. These operators are called stabilizer generators, and together they define a stabilizer code when they satisfy three conditions:

  1. 1.

    The generators commute with one another.

    PjPk=PkPjfor all j,k∈{1,…,r}.P_jP_k=P_kP_j\qquad\text{for all }j,k\in\{1,\ldots,r\}.

    This ensures that the generators can have common eigenstates and therefore define a shared code space. The repetition code satisfies this condition because its two generators are both ZZ-type operators and therefore commute.

  2. 2.

    The generators form a minimal generating set.

    No generator can be written as a product of the others:

    Pk∉⟨P1,…,Pk−1,Pk+1,…,Pr⟩for each k∈{1,…,r}.P_k\notin\langle P_1,\ldots,P_{k-1},P_{k+1},\ldots,P_r\rangle\qquad\text{for each }k\in\{1,\ldots,r\}.

    The right-hand side is the group generated by every generator except PkP_k. If PkP_k belonged to it, every state fixed by the other generators would already be fixed by PkP_k, so its check would add no new constraint.

    The repetition code's generators Z⊗Z⊗IZ\otimes Z\otimes I and I⊗Z⊗ZI\otimes Z\otimes Z form a minimal set, since neither is a product of the other. Adding Z⊗I⊗ZZ\otimes I\otimes Z as a third generator would break the condition, because it is already their product:

    Its check would only repeat information: its sign is always the product of the other two signs.

  3. 3.

    At least one nonzero vector is fixed by every generator.

    This ensures that the code space is not trivial. For commuting generators, the condition can be expressed equivalently as

    −I⊗n∉⟨P1,…,Pr⟩.-I^{\otimes n}\notin\langle P_1,\ldots,P_r\rangle.

    Every element of the generated group is a product of the generators, so any state fixed by all generators is also fixed by every element of the group. If the group contained −I⊗n-I^{\otimes n}, a common +1+1 eigenstate would have to satisfy −I⊗n∣ψ⟩=∣ψ⟩-I^{\otimes n}|\psi\rangle=|\psi\rangle, which is possible only for ∣ψ⟩=0|\psi\rangle=0.

    The repetition code satisfies this condition: its stabilizer group {I⊗I⊗I,  Z⊗Z⊗I,  I⊗Z⊗Z,  Z⊗I⊗Z}\{I\otimes I\otimes I,\;Z\otimes Z\otimes I,\;I\otimes Z\otimes Z,\;Z\otimes I\otimes Z\} does not contain −I⊗I⊗I-I\otimes I\otimes I, and ∣000⟩|000\rangle is a common +1+1 eigenstate of its generators. Commutation alone is not enough, however. X⊗XX\otimes X, Y⊗YY\otimes Y, and Z⊗ZZ\otimes Z commute pairwise, but their product is −I⊗I-I\otimes I, so no nonzero state is fixed by all three:

The code space is the set of all vectors fixed by every generator:

C={∣ψ⟩:P1∣ψ⟩=⋯=Pr∣ψ⟩=∣ψ⟩}.\mathcal C=\bigl\{|\psi\rangle:P_1|\psi\rangle=\cdots=P_r|\psi\rangle=|\psi\rangle\bigr\}.

Because a vector fixed by every generator is also fixed by every product of them, the same space is the set of vectors fixed by the entire stabilizer group ⟨P1,…,Pr⟩\langle P_1,\ldots,P_r\rangle. For the repetition code, this space is

C=span⁡{∣000⟩,∣111⟩}.\mathcal C=\operatorname{span}\{|000\rangle,|111\rangle\}.

Overall, a small set of independent, commuting Pauli generators specifies both the code space and the checks used to detect errors. Measuring these generators produces the syndrome, with the resulting signs indicating how an error has changed the stabilizer eigenvalues.

Examples of stabilizer codes

Stabilizer codes range from small textbook examples to large families such as surface codes, each specified by its set of generators. A few classic examples are shown below as grids, with one row for each check and one column for each qubit.

q1q2q3
Error
S1S_{1}ZZI−1
S2S_{2}IZZ−1

Error detected

S1S_{1} and S2S_{2} return −1.

The bit-flip code encodes one qubit into three, as α∣000⟩+β∣111⟩\alpha|000\rangle+\beta|111\rangle. It protects against an XX bit flip on any one qubit, but not against ZZ phase flips.

Code space dimension

The stabilizer generators do more than identify errors: they also determine how much quantum information the code can store. Starting with nn physical qubits gives a 2n2^n-dimensional state space. Each independent stabilizer condition restricts the allowed states to a +1+1 eigenspace and halves that dimension. With rr independent generators, the code space therefore has dimension

dim⁡C=2 n−r.\dim\mathcal C=2^{\,n-r}.

A 2n−r2^{n-r}-dimensional code space can store n−rn-r logical qubits, so n−rn-r is the number of qubits encoded by the code. This gives a useful way to read the structure of a stabilizer code: nn tells how many physical qubits are used, while rr tells how many independent constraints are imposed.

For the example codes:

Codenn qubitsrr generatorsEncoded qubits n−rn-r
3-qubit repetition code (bit flips)323−2=13-2=1
3-qubit repetition code (phase flips)323−2=13-2=1
9-qubit Shor code989−8=19-8=1
7-qubit Steane code767−6=17-6=1
5-qubit code545−4=15-4=1
E-bit code222−2=02-2=0
GHZ code333−3=03-3=0

When n−r=0n-r=0, the code space is one-dimensional. It contains only a single state up to an overall scalar, so it does not encode an unknown qubit. This is the case for the e-bit and GHZ codes, whose stabilizers fix the Bell and GHZ states.

The projector view of dim⁡C=2 n−r\dim\mathcal C=2^{\,n-r}

The previous dimension count started from the 2n2^n-dimensional state space of the nn physical qubits and asked how many independent conditions the stabilizer generators impose. Each independent condition halves the dimension of the allowed subspace.

The same result can be obtained by constructing a projector onto the code space. Each stabilizer check acts like a filter: it keeps the states that satisfy the check, with eigenvalue +1+1, and removes the states that fail it, with eigenvalue −1-1. For one generator PkP_k, define the projector for this check as

Πk=I⊗n+Pk2.\displaystyle \Pi_k=\frac{I^{\otimes n}+P_k}{2}.

Here I⊗nI^{\otimes n} is the identity on all nn qubits, formed by the tensor product of nn copies of the single-qubit identity II. It leaves every state unchanged, I⊗n∣ψ⟩=∣ψ⟩I^{\otimes n}|\psi\rangle=|\psi\rangle, and it is what turns PkP_k into a filter.

On its own, PkP_k only multiplies an eigenstate by +1+1 or −1-1, so a state with eigenvalue −1-1 survives the operation, but with its sign flipped. Adding I⊗nI^{\otimes n} changes these two possible eigenvalues to 1+1=21+1=2 and 1−1=01-1=0, and dividing by 22 then gives 11 and 00. Thus, the projector keeps a state that passes the check unchanged and sends a state that fails the check to 00.

To see this explicitly, suppose ∣ψ⟩|\psi\rangle is an eigenvector of PkP_k, then PkP_k acts on ∣ψ⟩|\psi\rangle in a particularly simple way: the result is the same state ∣ψ⟩|\psi\rangle, multiplied by an eigenvalue:

StatePkP_k eigenvalueApplying Πk\Pi_kAfter the filter Πk\Pi_k
passes the check+1+1Πk∣ψ⟩=I⊗n∣ψ⟩+Pk∣ψ⟩2=∣ψ⟩+∣ψ⟩2=∣ψ⟩\displaystyle \Pi_k|\psi\rangle=\frac{I^{\otimes n}|\psi\rangle+P_k|\psi\rangle}{2}=\frac{|\psi\rangle+|\psi\rangle}{2}=|\psi\ranglekept
fails the check−1-1Πk∣ψ⟩=I⊗n∣ψ⟩+Pk∣ψ⟩2=∣ψ⟩−∣ψ⟩2=0\displaystyle \Pi_k|\psi\rangle=\frac{I^{\otimes n}|\psi\rangle+P_k|\psi\rangle}{2}=\frac{|\psi\rangle-|\psi\rangle}{2}=0removed

Because the stabilizer generators commute, the filters commute too, and the order in which they are applied does not matter. Stacking all rr filters keeps exactly the states that pass every check, which gives the code-space projector

ΠC=Π1Π2⋯Πr=I⊗n+P12⋅I⊗n+P22⋯I⊗n+Pr2=∏k=1rI⊗n+Pk2.\displaystyle \Pi_{\mathcal C}=\Pi_1\Pi_2\cdots\Pi_r=\frac{I^{\otimes n}+P_1}{2}\cdot\frac{I^{\otimes n}+P_2}{2}\cdots\frac{I^{\otimes n}+P_r}{2}=\prod_{k=1}^{r}\frac{I^{\otimes n}+P_k}{2}.

Now expand this product. For each generator PkP_k, the product contains a choice between I⊗nI^{\otimes n} and PkP_k. For example, when r=2r=2,

ΠC=I⊗n+P12⋅I⊗n+P22=14(I⊗n+P1)(I⊗n+P2)=14(I⊗nI⊗n+I⊗nP2+P1I⊗n+P1P2)=14(I⊗n+P1+P2+P1P2).\displaystyle \begin{aligned}\Pi_{\mathcal C}&=\frac{I^{\otimes n}+P_1}{2}\cdot\frac{I^{\otimes n}+P_2}{2}\\[4pt]&=\frac14\bigl(I^{\otimes n}+P_1\bigr)\bigl(I^{\otimes n}+P_2\bigr)\\[4pt]&=\frac14\bigl(I^{\otimes n}I^{\otimes n}+I^{\otimes n}P_2+P_1I^{\otimes n}+P_1P_2\bigr)\\[4pt]&=\frac14\bigl(I^{\otimes n}+P_1+P_2+P_1P_2\bigr).\end{aligned}

For general rr, the same expansion gives 2r2^r terms, because each of the rr factors contributes either I⊗nI^{\otimes n} or its generator PkP_k:

ΠC=12r∑a1,…,ar∈{0,1}P1a1P2a2⋯Prar.\displaystyle \Pi_{\mathcal C}=\frac{1}{2^r}\sum_{a_1,\ldots,a_r\in\{0,1\}}P_1^{a_1}P_2^{a_2}\cdots P_r^{a_r}.

Here, each aka_k is either 00 or 11. If ak=0a_k=0, the factor is I⊗nI^{\otimes n}. If ak=1a_k=1, it is PkP_k.

Thus there are 2r2^r terms, one for each choice of including or excluding each generator. These terms are exactly the elements of the stabilizer group S=⟨P1,…,Pr⟩S=\langle P_1,\ldots,P_r\rangle, each appearing once. Two different choices cannot give the same product, because that would make one generator a product of the others, contradicting their independence.

The projector ΠC\Pi_{\mathcal C} keeps exactly the states in the code space and sends all other states to 00. Therefore, in a basis that separates the code space from its orthogonal complement, ΠC\Pi_{\mathcal C} has 11 on the code-space dimensions and 00 elsewhere. The trace of ΠC\Pi_{\mathcal C} counts these 11s, giving

Tr(ΠC)=dim⁡C.\mathrm{Tr}\bigl(\Pi_{\mathcal C}\bigr)=\dim\mathcal C.

Because the trace is linear, the trace of the expanded projector can now be taken term by term:

dim⁡C=Tr(ΠC)=12r∑a1,…,ar∈{0,1}Tr(P1a1P2a2⋯Prar).\displaystyle \dim\mathcal C=\mathrm{Tr}\bigl(\Pi_{\mathcal C}\bigr)=\frac{1}{2^r}\sum_{a_1,\ldots,a_r\in\{0,1\}}\mathrm{Tr}\bigl(P_1^{a_1}P_2^{a_2}\cdots P_r^{a_r}\bigr).

Only the term with every ak=0a_k=0 contributes to the trace. That term is the identity I⊗nI^{\otimes n}, a 2n×2n2^n\times 2^n matrix with every diagonal entry equal to 11. Its trace adds up those 2n2^n ones, which is easy to see for one and two qubits and holds the same way for any nn:

Tr(I)=Tr(1001)=2,Tr(I⊗I)=Tr(1000010000100001)=4=22,Tr(I⊗n)=1+1+⋯+1⏟2n=2n.\displaystyle \begin{aligned}\mathrm{Tr}(I)&=\mathrm{Tr}\begin{pmatrix}1&0\\0&1\end{pmatrix}=2,\\[6pt]\mathrm{Tr}(I\otimes I)&=\mathrm{Tr}\begin{pmatrix}1&0&0&0\\0&1&0&0\\0&0&1&0\\0&0&0&1\end{pmatrix}=4=2^2,\\[6pt]\mathrm{Tr}\bigl(I^{\otimes n}\bigr)&=\underbrace{1+1+\cdots+1}_{2^n}=2^n.\end{aligned}

Every other term includes at least one generator, so it is a Pauli string with a sign ±1\pm1 in front. It cannot be I⊗nI^{\otimes n}, because that is already the term with no generators chosen, and by the third stabilizer condition it cannot be −I⊗n-I^{\otimes n}. So at least one of its factors is XX, YY or ZZ. The trace of a tensor product is the product of the traces of its factors, and Tr(X)=Tr(Y)=Tr(Z)=0\mathrm{Tr}(X)=\mathrm{Tr}(Y)=\mathrm{Tr}(Z)=0, so a single such factor makes the whole trace 00. For example,

Tr(X⊗Z⊗I)=Tr(X) Tr(Z) Tr(I)=0⋅0⋅2=0.\mathrm{Tr}(X\otimes Z\otimes I)=\mathrm{Tr}(X)\,\mathrm{Tr}(Z)\,\mathrm{Tr}(I)=0\cdot0\cdot2=0.

Only the identity term survives, so

dim⁡C=Tr(ΠC)=12r(2n+0+⋯+0)=2n2r=2 n−r.\displaystyle \dim\mathcal C=\mathrm{Tr}\bigl(\Pi_{\mathcal C}\bigr)=\frac{1}{2^r}\bigl(2^n+0+\cdots+0\bigr)=\frac{2^n}{2^r}=\boxed{2^{\,n-r}}.
∣x⟩|x\rangleI⊗3I^{\otimes 3}IIIP1P_{1}ZZIP2P_{2}IZZP1P2P_{1}P_{2}ZIZΠC\Pi_{\mathcal C}
∣000⟩|000\rangle+1+1+1+111
∣001⟩|001\rangle+1+1−1−100
∣010⟩|010\rangle+1−1−1+100
∣011⟩|011\rangle+1−1+1−100
∣100⟩|100\rangle+1−1+1−100
∣101⟩|101\rangle+1−1−1+100
∣110⟩|110\rangle+1+1−1−100
∣111⟩|111\rangle+1+1+1+111
Tr\mathrm{Tr}80002

Down the columns: Tr(ΠC)=14(8+0+0+0)=2\mathrm{Tr}\bigl(\Pi_{\mathcal C}\bigr)=\tfrac{1}{4}\bigl(8+0+0+0\bigr)=2

Across the rows: Tr(ΠC)=1+1=2\mathrm{Tr}\bigl(\Pi_{\mathcal C}\bigr)=1+1=2

Counting independent conditions and taking the trace of the projector give the same dimension, 2n−r2^{n-r}, so a stabilizer code on nn physical qubits with rr independent generators encodes n−rn-r logical qubits. This is the central trade-off of a stabilizer code: each of the rr checks uses up one of the nn physical qubits’ degrees of freedom, and the remaining n−rn-r carry the logical information.

Clifford circuits and encodings

A stabilizer code is defined by its Pauli checks, but a quantum code is useful only if operations can also be performed on its states. What is needed are quantum gates that manipulate encoded states while the code can still be tracked with the same stabilizer description.

Clifford operations have exactly this property. When a Clifford operation is applied, every Pauli check is transformed into another Pauli operation. So the stabilizers remain Pauli checks after the operation, rather than becoming more complicated operators. This makes Clifford circuits especially convenient for preparing encoded states, manipulating them, and performing error correction.

A Clifford operation is a unitary operation that can be implemented by a circuit built from three types of gates: Hadamard gates, SS gates, and CNOT gates.

Clifford operations can also be described by how they act on Pauli operations. Up to a global phase, an nn-qubit unitary UU is a Clifford operation if and only if conjugation by UU — the map sending PP to UPU†UPU^{\dagger} — sends every nn-qubit Pauli operation to another nn-qubit Pauli operation. This is exactly the property that keeps Pauli checks Pauli after the operation.

Formally, for every P1,…,Pn∈{I,X,Y,Z}P_1,\ldots,P_n\in\{I,X,Y,Z\} there exist Q1,…,Qn∈{I,X,Y,Z}Q_1,\ldots,Q_n\in\{I,X,Y,Z\} such that

U (P1⊗⋯⊗Pn) U†=± Q1⊗⋯⊗Qn.U\,(P_1\otimes\cdots\otimes P_n)\,U^{\dagger}=\pm\,Q_1\otimes\cdots\otimes Q_n.

Conjugation is useful here because it describes how an operator changes when a unitary operation is applied to a state. A stabilizer is such an operator: it is a Pauli operation that leaves the state unchanged. If PP stabilizes ∣ψ⟩|\psi\rangle, then after applying UU, the corresponding stabilizer is UPU†UPU^{\dagger}:

(UPU†) U∣ψ⟩=UP(U†U)∣ψ⟩=UP∣ψ⟩=U∣ψ⟩.\bigl(UPU^{\dagger}\bigr)\,U|\psi\rangle=UP\bigl(U^{\dagger}U\bigr)|\psi\rangle=UP|\psi\rangle=U|\psi\rangle.

Thus, UPU†UPU^{\dagger} stabilizes the transformed state U∣ψ⟩U|\psi\rangle. This is why the Clifford property is important for stabilizer codes: because UPU†UPU^{\dagger} is again a Pauli operation, the transformed state can still be described using Pauli stabilizers.

Clifford operations are not for quantum computation. There are only finitely many nn-qubit Clifford operations, and by the Gottesman–Knill theorem their action on standard basis states can be simulated efficiently on a classical computer.

Conveniently, stabilizer codes can always be encoded using Clifford operations, with at most O(n2/log⁡n)O(n^2/\log n) gates. Such encoders were constructed by Cleve and Gottesman, and the gate count holds because every Clifford operation on nn qubits can be implemented with that many gates.

ZZZZZ
α∣0⟩+β∣1⟩\alpha|0\rangle+\beta|1\rangle
∣0⟩|0\rangle
∣0⟩|0\rangle
UU
S1=Z1Z2S_{1}=Z_{1}Z_{2}S2=Z2Z3S_{2}=Z_{2}Z_{3}

The result of the encoder is an entangled state that spreads the logical information across all three physical qubits. Starting from α∣0⟩+β∣1⟩\alpha|0\rangle+\beta|1\rangle, the bit-flip encoder produces

U((α∣0⟩+β∣1⟩)⊗∣00⟩)=α∣000⟩+β∣111⟩.U\bigl((\alpha|0\rangle+\beta|1\rangle)\otimes |00\rangle\bigr)=\alpha|000\rangle+\beta|111\rangle.

This is the three-qubit repetition code. The logical qubit is no longer stored in the first qubit alone. It is a joint property of all three.

The checks followed through the encoder are the tools for finding errors. An error on one qubit changes the state and reverses the sign of every check it anticommutes with. An XX on q1q_{1} reverses S1S_{1}, an XX on q2q_{2} reverses S1S_{1} and S2S_{2}, and an XX on q3q_{3} reverses S2S_{2}. Measuring the checks reads this pattern, the , without measuring α\alpha or β\beta. Once the error is identified, applying the same Pauli operation again undoes it and restores the encoded state.

A Clifford encoder makes this possible because Clifford gates send Pauli checks to Pauli checks. The simple checks of the ancillas become the code’s checks, Z2↦S1Z_{2}\mapsto S_{1} and Z3↦S2Z_{3}\mapsto S_{2}, and those are the checks that later detect errors. The encoder turns the original qubit into a protected logical qubit.

Detecting errors

Stabilizer checks act like parity checks. An encoded state is a +1+1 eigenvector of every check, so measuring a check returns +1+1 with certainty and leaves the encoded state unchanged. An error can flip some of these outcomes to −1-1. The pattern of flips is called the syndrome.

Let P1,…,PrP_1,\ldots,P_r be the stabilizer generators of an nn-qubit code, and let the nn-qubit Pauli operation EE represent an error acting on a code state ∣ψ⟩|\psi\rangle. Two Pauli operations either commute or anticommute.

  • If EE anticommutes with PkP_k, then

    Pk E∣ψ⟩=−E Pk∣ψ⟩=−E∣ψ⟩.P_k\,E|\psi\rangle=-E\,P_k|\psi\rangle=-E|\psi\rangle.

    The last equality follows because PkP_k leaves the original code state ∣ψ⟩|\psi\rangle unchanged. Measuring PkP_k on the state after the error therefore returns −1-1.

  • If EE commutes with PkP_k, the same calculation has no sign change, so measuring PkP_k on the state after the error returns +1+1.

Measuring all rr generators gives a list of signs: the syndrome. The syndrome depends only on which generators anticommute with EE and reveals nothing about the encoded state ∣ψ⟩|\psi\rangle. Measuring the generators therefore leaves the encoded information intact.

Every error falls into one of three cases:

CaseErrorSyndromeEffect on the code
1 · harmlessE=αQE=\alpha Q for some Q∈⟨P1,…,Pr⟩Q\in\langle P_1,\ldots,P_r\rangleall +1+1Leaves every code state unchanged apart from the factor α\alpha: E∣ψ⟩=α∣ψ⟩E|\psi\rangle=\alpha|\psi\rangle
2 · dangerousEPk=PkEEP_k=P_kE for every kk, but EE is not a case-1 errorall +1+1Acts as a logical operation that the checks do not detect
3 · detectedPkE=−EPkP_kE=-EP_k for at least one kksome −1-1Moves the state out of the code space

Only case 2 is dangerous. Its syndrome is all +1+1, as in case 1, but the error acts as a logical operation, such as flipping the encoded qubit, and no check notices.

Errors below the code’s distance cannot fall into case 2. The distance dd of a code is the minimum weight of a case-2 error: the smallest number of physical qubits that an undetected logical error must act on. Every error of smaller weight either leaves the encoded state unchanged or is detected. A code that encodes mm qubits into nn qubits with distance dd is called an [[n,m,d]][[n,m,d]] code.

[[n,m,d]]=[[3,1,1]][[n,m,\textcolor{#e11d48}{d}]]=[[3,1,\textcolor{#e11d48}{1}]]
ErrorWeightS1S_{1}S2S_{2}Effect
1 · harmless · every check +1, the state is unchanged
2+1+1unchanged
2+1+1unchanged
2 · dangerous · every check +1, yet the state changes
1= d+1+1α∣0‾⟩−β∣1‾⟩\alpha|\overline{0}\rangle-\beta|\overline{1}\rangle
3+1+1α∣1‾⟩+β∣0‾⟩\alpha|\overline{1}\rangle+\beta|\overline{0}\rangle
3 · detected · some check reads −1
1−1+1leaves the code space
1−1−1leaves the code space
1+1−1leaves the code space
q1q2q3sign
EEX
S1S_{1}ZZI−1
S2S_{2}IZZ+1

Together, these ideas describe how a stabilizer code works. A set of commuting Pauli checks defines the code space, and a Clifford encoder places any state in that space. Measuring the checks gives an error’s signature, the syndrome, without revealing the encoded data. Errors that are products of checks leave the encoded state unchanged, and errors that anticommute with at least one check appear in the syndrome. Only errors that commute with every check but are not products of checks as in case 1 can change the encoded qubit without being detected. The distance dd is the smallest weight of such an error, so every error on fewer than dd qubits is either detected or harmless.

Knowing that an error happened is not yet enough to undo the error, though. For correction, the syndrome must point to the error.

Correcting errors

To correct an error, a decoder must choose an operation that restores the encoded state. The difficulty is that the syndrome does not identify exactly which error occurred: many different errors produce the same syndrome. With rr generators on nn qubits, there are 2r2^r syndromes and 4n4^n Pauli operations, ignoring phases. Each syndrome is associated with 4n/2r4^n/2^r of these operations.

Some errors with the same syndrome also have the same effect on code states. If SS is a stabilizer element, then EE and ESES are equivalent, since every code state ∣ψ⟩|\psi\rangle satisfies

ES∣ψ⟩=E(S∣ψ⟩)=E∣ψ⟩.ES|\psi\rangle=E\bigl(S|\psi\rangle\bigr)=E|\psi\rangle.

Even after grouping equivalent errors, for each syndrome there remain 4n−r4^{n-r} classes that act differently on the code space, and a single correction can undo errors in at most one of them. Thus, unless r=nr=n, in which case the code space is one-dimensional, no procedure can correct every error, and a decoder must choose which class to correct.

Still, the syndrome provides information for error correction: it indicates which stabilizer checks are nontrivial, but it does not identify the exact error that occurred. A natural decoding rule is therefore: for each syndrome ss, choose a lowest-weight Pauli operation CC that produces ss, and apply CC as the correction. For a code of distance dd, this rule corrects every error of weight less than d/2d/2.

To see why, suppose the actual error EE has weight less than d/2d/2. Since EE produces the measured syndrome, the chosen correction CC produces the same syndrome. After the correction, the residual operation CECE remains, and three facts about it follow.

  • CC is no heavier than EE. CC has the lowest weight among operations with this syndrome, and EE is one of them, so wt⁡(C)≤wt⁡(E)\operatorname{wt}(C)\le\operatorname{wt}(E).
  • CECE is lighter than the distance. Its weight is at most the sum of the two weights, so

    wt⁡(CE)≤wt⁡(C)+wt⁡(E)≤2wt⁡(E)<d.\operatorname{wt}(CE)\le\operatorname{wt}(C)+\operatorname{wt}(E)\le2\operatorname{wt}(E)<d.
  • CECE passes every check. CC and EE flip the same check outcomes, so in the product CECE the flips cancel.

By definition of the code distance, any operation that passes every check but changes the encoded state must have weight at least dd. But CECE passes every check and has weight less than dd. Therefore, CECE cannot change the encoded state. It has no logical effect, so the correction CC successfully cancels the error EE.

If the error is larger, the argument above no longer works. The lowest-weight operation with the same syndrome may be quite different from EE, so CECE can have weight dd or more. In that case, CECE may change the encoded state instead of simply canceling the error.

This means that every error affecting fewer than d/2d/2 qubits can be corrected. Equivalently, a code of distance dd can correct errors on up to ⌊(d−1)/2⌋\lfloor (d-1)/2\rfloor qubits. The Shor, Steane, and five-qubit codes all have distance 33, so they can each correct any single-qubit error.

[[n,m,d]]=[[7,1,3]]⌊d−12⌋=1[[n,m,\textcolor{#e11d48}{d}]]=[[7,1,\textcolor{#e11d48}{3}]]\qquad \left\lfloor\tfrac{\textcolor{#e11d48}{d}-1}{2}\right\rfloor=1

corrected · CECE is a product of checks, so CC undoes EE on every code state

logical error · CECE passes every check but is not a product of checks, so it changes the encoded state

q1q2q3q4q5q6q7
EEXIIIIII
CCXIIIIII
CECEIIIIIII
syndrome
−−−+++
lightest C
X1X_{1}
weight of CE
0<d0<d
result
restored

The remaining challenge is finding the correction CC, and unfortunately, for a given choice of generators and a syndrome, finding a lowest-weight Pauli operation that produces that syndrome is computationally difficult in general. Finding codes that allow a lowest-weight correction to be chosen efficiently is part of the art of code design.

Quantum code constructions

With the stabilizer formalism in place, the next step is to construct codes with useful properties. The goal is to protect quantum information from errors while keeping the checks simple, local, and scalable as the code grows.

Classical linear codes

Let Σ={0,1}\Sigma=\{0,1\} be the binary alphabet. A classical linear code is a nonempty set of binary strings C⊆Σn\mathcal C\subseteq\Sigma^n that is closed under bitwise addition modulo 2:

u,v∈C  ⟹  u⊕v∈C.u,v\in\mathcal C\;\Longrightarrow\;u\oplus v\in\mathcal C.

Bitwise addition treats a string as a list of separate bits, not as a binary number. Position ii of u⊕vu\oplus v is computed from position ii of uu and vv alone, and the sum is taken modulo 2:

As a result, nothing carries. In a binary number, the positions stand for 11, 22, 44, and so on, so a sum of 22 in one position equals a 11 in the next position and has to move there. In a string, each position is an independent bit, so a sum of 22 is replaced by its remainder 00 modulo 2 and the other positions are left alone. The same two strings, added bitwise and as the numbers 33 and 11, give different results:

The {000,111}\{000,111\} is a linear code, since every sum of two codewords is again 000000 or 111111:

Not every set of strings is closed. The set {000,100,111}\{000,100,111\}, the repetition code with 100100 added, is not a linear code, because one of its sums falls outside it:

A richer example is the Hamming code, a set of sixteen codewords:

C=\mathcal C=
00000000000000110000111000011010010101001001100110110011011010001101001010101101010111001101100110000011100001111111000111100000110010011001010101001010101001011100101110011001001100010110101011010011110001111011111111111111

Codes like this are labelled [n,m,d][n,m,d]. The codewords have nn bits, there are 2m2^m of them, so the code carries mm bits of information, and any two codewords differ in at least dd positions. The Hamming code is a [7,4,3][7,4,3] code: sixteen codewords of seven bits, pairwise at least three bits apart. A single flipped bit therefore leaves a word closer to its own codeword than to any other, and can be undone. And the 3-bit repetition code {000,111}\{000,111\} is a [3,1,3][3,1,3] code.

The has the same three roles, nn qubits, mm encoded qubits and distance dd, and the double brackets mark it as quantum. The numbers do not carry over from a classical code to a quantum one, though. The is built from the Hamming code, yet it is a [[7,1,3]][[7,1,3]] code.

Two ways to describe a linear code

A linear code can be specified in two equivalent ways: by describing how to construct its codewords, or by specifying conditions that a string must satisfy to be a codeword.

The first uses generators. A set of generators u1,…,umu_1,\ldots,u_m is chosen so that every codeword can be formed by adding some of them. For each generator, αk=1\alpha_k=1 means that it is included in the sum and αk=0\alpha_k=0 means that it is not:

C={α1u1⊕⋯⊕αmum  :  α1,…,αm∈{0,1}}.\mathcal C=\bigl\{\alpha_1u_1\oplus\cdots\oplus\alpha_mu_m\;:\;\alpha_1,\ldots,\alpha_m\in\{0,1\}\bigr\}.

The second uses parity checks. A set of checks v1,…,vrv_1,\ldots,v_r is chosen so that a string is a codeword exactly when it passes every check. A string uu passes a check vv when their binary dot product u⋅vu\cdot v is 0:

C={u∈Σn  :  u⋅v1=⋯=u⋅vr=0}.\mathcal C=\bigl\{u\in\Sigma^n\;:\;u\cdot v_1=\cdots=u\cdot v_r=0\bigr\}.

Generators

αk\alpha_k
u1u_{1}

Parity checks

u⋅vku\cdot v_k
uu
v1v_{1}1101
v2v_{2}0111

Not a codeword

u⋅v1=u⋅v2=1u\cdot v_{1}=u\cdot v_{2}=1, so no choice of αk\alpha_k builds uu.

The 3-bit repetition code is a [3,1,3][3,1,3] code with a single generator, so its two codewords are the sums with α1=0\alpha_1=0 and α1=1\alpha_1=1, namely 000000 and 111111. Its checks 110110 and 011011 ask that the first two bits agree and that the last two agree.

Linear codes therefore provide two complementary descriptions of the same structure: generators specify how codewords are built, while parity checks specify the conditions they must satisfy. Together, these give both a way to construct the code and a way to detect errors.

CSS codes

A provides two kinds of structure: generators and parity checks. In a quantum code, the parity-check idea can be applied in two different bases: the computational basis {∣0⟩,∣1⟩}\{|0\rangle,|1\rangle\} and the plus/minus basis {∣+⟩,∣−⟩}\{|+\rangle,|-\rangle\}. A CSS code uses both kinds of quantum parity checks as : one set in each basis. This lets it detect XX errors and ZZ errors separately.

On the classical side, a string uu passes a parity check vv when u⋅v=0u\cdot v=0, and the code C\mathcal C consists of the strings that pass every check. In the quantum version, the same check is represented by a Pauli ZZ operation. For a binary string vv, define ZvZ^v as the operation that applies ZZ to each qubit where vv has a 1 and II where vv has a 0:

Zv=Zv1⊗Zv2⊗⋯⊗Zvn.Z^{v}=Z^{v_1}\otimes Z^{v_2}\otimes\cdots\otimes Z^{v_n}.

On a computational-basis state ∣u⟩|u\rangle, the operation ZvZ^v contributes a factor of −1-1 for every position where both uu and vv have a 1:

Zv∣u⟩=(−1)u⋅v∣u⟩.Z^{v}|u\rangle=(-1)^{u\cdot v}|u\rangle.

The eigenvalue is +1+1 exactly when u⋅v=0u\cdot v=0. Thus, ∣u⟩|u\rangle satisfies the checks Zv1,…,ZvrZ^{v_1},\ldots,Z^{v_r} exactly when uu satisfies the corresponding classical checks v1,…,vrv_1,\ldots,v_r, that is, when u∈Cu\in\mathcal C.

A classical parity check therefore becomes a Z-type stabilizer generator, containing only ZZ and II. For example, the 3-bit repetition code’s checks 110110 and 011011 become ZZIZZI and IZZIZZ. The Hamming code’s checks become ZZZZIIIZZZZIII, ZZIIZZIZZIIZZI, and ZIZIZIZZIZIZIZ.

The same parity check can be expressed in the plus/minus basis. Define Xv=Xv1⊗⋯⊗XvnX^v=X^{v_1}\otimes\cdots\otimes X^{v_n} in the same way, and let H⊗n∣u⟩H^{\otimes n}|u\rangle denote the state with ∣+⟩|+\rangle where uu has a 00 and ∣−⟩|-\rangle where it has a 11. Since X∣±⟩=±∣±⟩X|\pm\rangle=\pm|\pm\rangle, the corresponding calculation is:

XvH⊗n∣u⟩=(−1)u⋅vH⊗n∣u⟩.X^{v}H^{\otimes n}|u\rangle=(-1)^{u\cdot v}H^{\otimes n}|u\rangle.

Thus the same parity check becomes an X-type stabilizer generator, with XX replacing ZZ and the plus/minus basis replacing the computational basis. For the Hamming code, the checks 11110001111000, 11001101100110, and 10101011010101 become XXXXIIIXXXXIII, XXIIXXIXXIIXXI, and XIXIXIXXIXIXIX. Their common +1+1 eigenspace contains the sixteen basis states corresponding to the Hamming codewords, with 00 represented by ∣+⟩|+\rangle and 11 by ∣−⟩|-\rangle. For example, the codeword 01101000110100 gives ∣+−−+−++⟩|{+}{-}{-}{+}{-}{+}{+}\rangle.

The central idea is simple: a classical parity check has a quantum version in either basis. ZZ-type stabilizers impose the checks in the computational basis, while XX-type stabilizers impose the same checks in the plus/minus basis. Using both gives a CSS code two complementary sets of checks: ZZ-type stabilizers detect XX errors, while XX-type stabilizers detect ZZ errors.

Z stabilizer generators

∣u⟩|u\rangle
Zv1Z^{v_{1}}ZZZZIII+1
Zv2Z^{v_{2}}ZZIIZZI+1
Zv3Z^{v_{3}}ZIZIZIZ−1

X stabilizer generators

H⊗n∣u⟩H^{\otimes n}|u\rangle
Xv1X^{v_{1}}XXXXIII+1
Xv2X^{v_{2}}XXIIXXI+1
Xv3X^{v_{3}}XIXIXIX−1

Not a codeword

u⋅v3=1u\cdot v_{3}=1, so that check returns −1-1 in both bases.

There is one more requirement: the ZZ-type and XX-type stabilizers must be able to hold simultaneously. A code state must satisfy S∣ψ⟩=∣ψ⟩S|\psi\rangle=|\psi\rangle for every stabilizer SS. Now suppose two stabilizers SS and TT anticommute, so ST=−TSST=-TS. If both are to leave the same state ∣ψ⟩|\psi\rangle unchanged, then S∣ψ⟩=T∣ψ⟩=∣ψ⟩S|\psi\rangle=T|\psi\rangle=|\psi\rangle, and therefore

∣ψ⟩=ST∣ψ⟩=−TS∣ψ⟩=−∣ψ⟩.|\psi\rangle=ST|\psi\rangle=-TS|\psi\rangle=-|\psi\rangle.

This can only be true for ∣ψ⟩=0|\psi\rangle=0, which is not a valid quantum state. Thus, stabilizers that anticommute cannot belong to the same stabilizer code: all stabilizers must commute. In particular, every XX-type stabilizer must commute with every ZZ-type stabilizer.

Whether an XX-type and a ZZ-type stabilizer commute depends only on how many qubits they act on simultaneously. On a qubit where one stabilizer has II, the two operators commute automatically. On a qubit where both act, one has XX and the other has ZZ, and swapping their order introduces a minus sign because XZ=−ZXXZ=-ZX. Thus, each qubit where both stabilizers act contributes one minus sign. For strings xx and zz, this gives

XxZz=(−1)x⋅zZzXx.X^{x}Z^{z}=(-1)^{x\cdot z}Z^{z}X^{x}.
2 shared qubits: (−1)(−1)=+1(-1)(-1)=+1commute
1 shared qubit: −1-1anticommute

An even overlap gives an even number of minus signs, which cancel, while an odd overlap leaves one minus sign. For example, XXIXXI and ZZIZZI overlap on two qubits, so they commute, whereas XXIXXI and IZZIZZ overlap on one qubit, so they anticommute. Therefore, if z1,…,zs∈Σnz_1,\ldots,z_s\in\Sigma^n are the parity checks for the ZZ-type stabilizers and x1,…,xt∈Σnx_1,\ldots,x_t\in\Sigma^n are those for the XX-type stabilizers, every XX-type stabilizer must overlap every ZZ-type stabilizer on an even number of qubits, which means xi⋅zj=0x_i\cdot z_j=0 for every ii and jj.

Error detection and correction

The CSS construction separates XX and ZZ errors into two independent parts. A ZZ error commutes with every ZZ-type stabilizer, so it does not change their outcomes, while an XX error commutes with every XX-type stabilizer for the same reason. Thus, the ZZ-type checks detect only the XX part of an error, and the XX-type checks detect only its ZZ part. Since every Pauli error can be written, up to a phase, as an XX part times a ZZ part, with YY contributing to both, decoding reduces to two separate classical decoding problems.

Suppose the ZZ-type stabilizers can correct up to jj XX errors, while the XX-type stabilizers can correct up to kk ZZ errors. Then the CSS code can correct any Pauli error acting on at most min⁡{j,k}\min\{j,k\} qubits. Such an error has at most min⁡{j,k}\min\{j,k\} qubits in each of its XX and ZZ parts, so both parts can be decoded successfully.

In the Steane code both halves are the , which correct one bit flip, so j=k=1j=k=1. Any single-qubit error is corrected, and so is an XX on one qubit together with a ZZ on another:

q1q2q3q4q5q6q7beforeafter
EE
Zv1Z^{v_{1}}ZZZZIII−1+1
Zv2Z^{v_{2}}ZZIIZZI−1+1
Zv3Z^{v_{3}}ZIZIZIZ+1+1
Xv1X^{v_{1}}XXXXIII+1+1
Xv2X^{v_{2}}XXIIXXI−1+1
Xv3X^{v_{3}}XIXIXIX−1+1
RRIXIIZII
REREIIIIIII

Corrected

R undoes every error in E, so the encoded state is back where it started.

Stronger error correction comes at a cost. Each independent stabilizer halves the code space, so a CSS code on nn qubits with ss independent ZZ-type and tt independent XX-type stabilizers encodes n−s−tn-s-t logical qubits. Adding more checks can detect and correct more errors, but it also reduces the number of qubits available to store information.

Code spaces of CSS codes

The stabilizers of a code say which states are allowed, but not what those states look like. For a CSS code the answer is concrete — every code state is a superposition of classical codewords, and the two kinds of checks decide which codewords appear and with what amplitudes.

Write a state in the computational basis as a superposition of strings ww. A ZZ-type check ZzZ^z multiplies each term by (−1)w⋅z(-1)^{w\cdot z}. For the state to stay unchanged, every term must get the sign +1+1, so only strings that pass all ZZ-type checks may appear.

An XX-type check XxX^x does not change signs. It flips bits, sending each term ∣w⟩|w\rangle to ∣w⊕x⟩|w\oplus x\rangle. For the state to stay unchanged, the string w⊕xw\oplus x must appear whenever ww does, with the same amplitude. Applying several XX-type checks adds their sum, so together with ww the state must contain ww plus every sum of XX-type checks, all with equal amplitudes.

Two are therefore involved: CZ\mathcal C_Z, the strings that pass every ZZ-type check z1,…,zsz_1,\ldots,z_s, and DX\mathcal D_X, the sums of the XX-type checks x1,…,xtx_1,\ldots,x_t:

CZ={u∈Σn  :  u⋅z1=⋯=u⋅zs=0},DX={α1x1⊕⋯⊕αtxt  :  α1,…,αt∈{0,1}}.\begin{aligned}\mathcal C_Z&=\bigl\{u\in\Sigma^n\;:\;u\cdot z_1=\cdots=u\cdot z_s=0\bigr\},\\[4pt]\mathcal D_X&=\bigl\{\alpha_1x_1\oplus\cdots\oplus\alpha_tx_t\;:\;\alpha_1,\ldots,\alpha_t\in\{0,1\}\bigr\}.\end{aligned}

A code state is then built in one step. Start from any string u∈CZu\in\mathcal C_Z, collect everything reachable from it by adding a sum of XX-type checks, written u⊕DXu\oplus\mathcal D_X, and take the equal superposition:

∣u⊕DX⟩=12t∑v∈DX∣u⊕v⟩.\displaystyle|u\oplus\mathcal D_X\rangle=\frac{1}{\sqrt{2^t}}\sum_{v\in\mathcal D_X}|u\oplus v\rangle.

Adding XX-type checks never leads out of CZ\mathcal C_Z. Every XX-type check overlaps every ZZ-type check evenly, so it passes all of them, and so does every sum of them. In symbols, DX⊆CZ\mathcal D_X\subseteq\mathcal C_Z. Every term of the superposition therefore passes the ZZ-type checks, and an XX-type check only shuffles the terms among themselves. Both requirements hold.

The same construction works with the roles of the two bases swapped. Let CX\mathcal C_X be the strings that pass every XX-type check and DZ\mathcal D_Z the sums of the ZZ-type checks:

CX={u∈Σn  :  u⋅x1=⋯=u⋅xt=0},DZ={α1z1⊕⋯⊕αszs  :  α1,…,αs∈{0,1}}.\begin{aligned}\mathcal C_X&=\bigl\{u\in\Sigma^n\;:\;u\cdot x_1=\cdots=u\cdot x_t=0\bigr\},\\[4pt]\mathcal D_Z&=\bigl\{\alpha_1z_1\oplus\cdots\oplus\alpha_sz_s\;:\;\alpha_1,\ldots,\alpha_s\in\{0,1\}\bigr\}.\end{aligned}

Building the superpositions in the plus/minus basis instead, one for each u∈CXu\in\mathcal C_X, describes the same code space:

H⊗n∣u⊕DZ⟩=12s∑v∈DZH⊗n∣u⊕v⟩.\displaystyle H^{\otimes n}|u\oplus\mathcal D_Z\rangle=\frac{1}{\sqrt{2^s}}\sum_{v\in\mathcal D_Z}H^{\otimes n}|u\oplus v\rangle.

All 128 strings ww of 7 bits, each standing for the state ∣w⟩|w\rangle. A code state is a superposition of such states that every check leaves unchanged.

Zz1Z^{z_{1}}ZZZZIII
Zz2Z^{z_{2}}ZZIIZZI
Zz3Z^{z_{3}}ZIZIZIZ
Xx1X^{x_{1}}XXXXIII
Xx2X^{x_{2}}XXIIXXI
Xx3X^{x_{3}}XIXIXIX

The two types of checks do different jobs:

  • Z checks: choose which computational-basis strings may appear.
  • X checks: impose equality relations among the amplitudes of those strings.

Together they define the code space: allowed strings are selected by the Z checks, and their amplitudes are constrained by the X checks. Different X-check orbits can still have independent amplitudes.

A CSS code uses many physical qubits to protect a smaller number of logical qubits. Its stabilizer checks reduce the full state space of nn physical qubits from dimension 2n2^n to a much smaller code space of dimension 2n−s−t2^{n-s-t}.

For example, the Steane code uses 7 physical qubits but encodes only one logical qubit. Its 128 possible physical strings are reduced to 16 by the ZZ-type checks, then to two logical basis states by the XX-type checks. Each logical state is represented by a superposition of 8 physical strings, providing the redundancy needed to detect and correct errors.

The central idea is a trade-off: more physical qubits are used to represent fewer logical qubits, gaining protection against errors in return.

Toric code

CSS codes use sets of commuting checks to restrict the physical qubits to a smaller code space, protecting a few logical qubits from errors. But increasing the number of physical qubits does not automatically give better protection. To make a larger code correct more errors, its checks may also need to involve more qubits, connecting larger parts of the code. Such checks are harder to measure reliably and require more complex hardware. The challenge is therefore to increase protection while keeping the checks small and local.

The toric code achieves this by keeping every check local: each check touches only four neighboring qubits, regardless of the size of the code. At the same time, the smallest logical operation grows with the lattice, making logical errors increasingly difficult to create.

The toric code arranges its qubits on a repeating square lattice with no boundaries. Opposite sides are identified, so moving across one edge of the lattice brings you back from the opposite side. This turns the flat grid into a torus, where paths can wrap around in two independent directions.

L = 5

Every edge of the lattice holds one physical qubit. Each of the L×LL\times L cells contributes two edges, its top and its left side, because its bottom and right sides are the top and left sides of the neighboring cells. The dotted copies on the right and bottom of the lattice are these shared edges seen a second time. The total number of physical qubits is therefore n=2L2n=2L^2.

The checks are attached to the tiles and vertices of the lattice. A tile carries a ZZ check on its four edges, while a vertex carries an XX check on the four edges that meet there. When errors occur, they change the outcomes of nearby checks, producing a syndrome that reveals where the error chain begins and ends. A decoder uses this syndrome to choose a correction. All of these steps take place on the same lattice.

Every edge belongs to exactly two tiles, so the product of all tile checks is the identity. The same is true for the vertex checks. Each type therefore has L2−1L^2-1 independent checks. With 2L22L^2 physical qubits, the number of logical qubits the code encodes is (yes, only two logical qubits):

k=2L2−2(L2−1)=2.k=2L^2-2(L^2-1)=2.

An XX error on an edge flips the outcomes of the two neighboring ZZ checks. When several XX errors form a chain, the checks along the middle of the chain are flipped twice and return to +1+1. Only the two ends remain visible in the syndrome.

If the chain closes, it has no ends and passes every check. Such a closed chain is a loop. A loop around an ordinary region is a product of vertex checks, so it is a stabilizer and leaves the encoded state unchanged. A loop that winds around the torus cannot be produced by local checks, so it acts as a logical operator.

There are two independent ways to wind around the torus, giving two logical XX operations. The corresponding ZZ loops run in the other directions and form the logical ZZ operations.

The shortest winding loop runs straight along one row or column and contains LL qubits. A logical error therefore needs at least LL single-qubit errors, so the distance is d=Ld=L and grows with the lattice. Together with n=2L2n=2L^2 and k=2k=2, this gives the parameters of the toric code:

[[2L2,2,L]].[[2L^2,2,L]].

For decoding, the syndrome gives the endpoints of the error chains but not their paths. The decoder therefore connects the endpoints with the shortest overall set of paths, using minimum-weight perfect matching. The correction succeeds when its paths reproduce the error chains up to stabilizers. If the chosen paths differ from the actual errors by a winding loop, the correction instead produces a logical error. For an isolated chain shorter than L/2L/2, the original path is the shorter route between its endpoints and is therefore recovered correctly.

For independent errors with the same small probability, shorter chains are more likely, so matching looks for the most likely error consistent with the syndrome. Real noise is more complicated: error rates can vary, errors can be correlated, YY errors affect both check types, and measurements can also fail. More advanced decoders account for these effects and for the fact that errors related by stabilizers are physically equivalent, trading accuracy against computational cost.

ZZZZXXXX

The toric code has two kinds of local check. A blue tile check applies ZZ to the four qubits around a square, while a violet vertex check applies XX to the four qubits meeting at a vertex:

Zt=Z1Z2Z3Z4,Xv=X1X2X3X4.Z_t=Z_1Z_2Z_3Z_4,\qquad X_v=X_1X_2X_3X_4.

A check measurement returns +1+1 or −1-1. In the absence of errors, every check returns +1+1.

The two checks either share no qubits or share two. Whenever XX and ZZ act on the same qubit, swapping their order introduces a minus sign. Two shared qubits therefore introduce two minus signs, which cancel. Thus every tile check commutes with every vertex check, so all checks can be measured together, regardless of the lattice size:

ZtXv=(−1)2XvZt=XvZt.Z_tX_v=(-1)^2X_vZ_t=X_vZ_t.

The toric code shows how quantum information can be stored in the global structure of a space, rather than in any particular group of qubits. Its local checks remain small as the lattice grows, while its protection comes from the topology of the code.

Surface codes

A toric code is defined on a torus, which is awkward for a planar device because opposite edges must be connected. The code does not actually need this wraparound. Cutting the torus open produces a flat patch called a surface code, using only nearest-neighbor qubits in a plane.

In a planar surface code, interior stabilizers still act on four qubits. At the boundary, some of the qubits that would have continued beyond the edge are absent, so the affected stabilizers have weight three. ZZ-type stabilizers are truncated at the top and bottom boundaries, while XX-type stabilizers are truncated at the left and right boundaries.

XXZZXXZZZXZZXX

The boundaries also determine which error chains can become logical operations. An XX chain can connect the left and right boundaries, while a ZZ chain can connect the top and bottom boundaries. Such a chain produces no syndrome, so it acts as a logical operator. The shortest chain contains LL qubits, giving the code parameters [[[[L2+(L−1)2L^2+(L-1)^2, ,\,11, L]],\,L]].

Rotated surface code

The rotated surface code rearranges the same surface-code construction into a checkerboard layout. The rotation preserves the code distance and syndrome structure while using fewer physical qubits: d2d^2 instead of d2+(d−1)2d^2+(d-1)^2. A distance-5 code, for example, needs 25 qubits instead of 41.

The d2d^2 data qubits form the corners of the checkerboard. Full squares carry four-qubit stabilizers, while boundary plaquettes carry two-qubit stabilizers. XX- and ZZ-type stabilizers alternate across the patch, with their boundary types arranged to support the same logical operators as the planar code. The patch encodes one logical qubit, giving [[d2, 1, d]][[d^2,\,1,\,d]].

The error picture is the same. An error chain normally produces syndrome at its endpoints, while a closed chain produces none. At a boundary, a chain can end without producing a −1-1 outcome.

For example, an XX chain connecting the top and bottom boundaries acts as a logical XX. Its shortest path contains dd qubits, so the code distance is dd.

Planar code

The rotated code comes from the planar code in three moves, shown here for d=7d=7.

1. Draw the checks through their qubits. Each planar-code check acts on the qubits around a tile or vertex. Drawn as the polygon connecting those qubits, each check becomes a diamond: blue for ZZ checks and violet for XX checks. Together, the diamonds form a checkerboard across the patch. Checks cut by the boundary become triangles.

2. Turn the lattice by 45°. The diamonds become upright squares, with a qubit at every corner.

3. Keep only the central d×dd\times d qubits. Checks entirely inside the square keep all four qubits. A check crossing the boundary keeps two. Only one check type is kept on each side: XX on the top and bottom, ZZ on the left and right. This avoids having neighboring checks of different types share a single qubit, which would make them anticommute.

A logical chain from top to bottom still needs one qubit in each of the dd rows, so the distance remains dd. But the number of physical qubits drops:

d2+(d−1)2=85  ⟶  d2=49.d^2+(d-1)^2=85\;\longrightarrow\;d^2=49.

The surface code therefore keeps the key protection of the toric code without requiring a torus. Its stabilizers involve only nearby qubits on a flat surface, matching the geometry of physical quantum hardware. The rotated layout goes one step further by reducing the number of physical qubits needed for the same code distance.

The advantage is therefore not stronger error correction than the toric code. Both have the same basic topological protection. The surface code is more practical because its geometry fits a planar device, and the rotated version reduces its qubit overhead further.

Color codes

Surface codes are well suited to protecting information on a plane, but their logical gates are less convenient to implement. Color codes use a different lattice structure that makes more logical gates transversal: the gate can be applied independently to each physical qubit, so an error on one qubit does not spread to another.

The key idea is simple. Every face carries both an XX-type and a ZZ-type stabilizer:

Zf=∏q∈fZqXf=∏q∈fXq.\begin{aligned}Z_f&=\prod_{q\in f}Z_q\\[4pt]X_f&=\prod_{q\in f}X_q.\end{aligned}

The faces are colored so that neighboring faces have different colors. This three-coloring is what gives color codes their name, while the underlying geometry ensures that different faces share either no qubits or two. An XX and ZZ check therefore anticommute twice when they overlap, so the two minus signs cancel and all checks commute.

Because every face has both an XX check and a ZZ check, swapping XX and ZZ leaves the code unchanged. Applying HH to every physical qubit performs exactly this swap, so the code space is preserved and the logical qubit undergoes an HH gate. Since each HH acts on one qubit independently, an error on one qubit cannot spread to another during the operation. This is the transversal property: in two-dimensional color codes, every Clifford gate can be implemented by gates that never couple two qubits of the same code block.

The smallest example of a color code is the : seven qubits arranged as a triangle with three faces. Each face carries one XX and one ZZ check, giving the six stabilizer generators. Larger color codes use the same construction on larger lattices, such as triangles tiled with hexagons. Their distance increases with the lattice size while preserving the same transversal-gate structure. As with the surface code, the whole lattice still encodes only one logical qubit, however large it grows.

d = 7, 37 qubits

A color code places qubits at the corners of a honeycomb lattice cut into a triangle. Along the three sides, the boundary cuts the hexagons down to four-qubit faces.

For distance dd, the triangle has n=(3d2+1)/4n=(3d^2+1)/4 qubits and (n−1)/2(n-1)/2 faces. Each face gives one XX and one ZZ check, so there are n−1n-1 independent checks, leaving one logical qubit:

k=n−(n−1)=37−36=1.k=n-(n-1)=37-36=1.

provide the basic structure for detecting errors. use two such structures to build a quantum code, with one detecting bit flips and the other detecting phase flips. The arranges these checks on a lattice wrapped around a torus, so that each one acts only on nearby qubits. cut the torus open into a flat patch, and the rotated layout reaches the same distance with fewer qubits. keep the checks local on a three-colored lattice, with both an XX check and a ZZ check on every face.

These codes share a cost. A standard surface-code patch of distance dd stores one logical qubit, so storing more logical qubits requires more patches, while the number of physical qubits per patch grows roughly as d2d^2. Much of current research therefore looks for codes that store many logical qubits in a single code while keeping each check small:

  • The gross code is a [[144,12,12]][[144,12,12]] code from the bivariate bicycle family. It stores twelve logical qubits in 144 physical ones, needs another 144 qubits for syndrome measurements, and can be laid out on two planar layers of connections (Bravyi et al., 2023).
  • Quantum LDPC codes keep every check on only a few qubits without requiring a flat lattice. Some families can grow both the number of logical qubits and the distance with the size of the code (Panteleev and Kalachev, 2021).
  • Floquet codes have no fixed set of stabilizers. Instead, their logical information is protected by a repeating sequence of two-qubit measurements (Hastings and Haah, 2021).
  • Subsystem codes such as the Bacon–Shor code leave some degrees of freedom unprotected, allowing the remaining checks to be simpler to measure (Bacon, 2005).
  • Bosonic codes such as the GKP code store a qubit in the continuous states of a single oscillator instead of distributing it across many two-level systems (Gottesman, Kitaev and Preskill, 2000).

The original papers behind these codes develop their ideas in full:

The Error Correction Zoo catalogs hundreds of codes, their parameters, and the relationships between them. It is a useful reference when encountering a code elsewhere.

Fault-tolerant quantum computing

A quantum computer cannot simply encode information and assume the rest of the computation is reliable. Its qubits must be prepared, manipulated, and measured, while the error-correction process itself is also imperfect. Fault-tolerant quantum computing is the set of techniques that makes these operations reliable despite those faults.

The key is to design the computation so that errors remain controlled and can be detected and corrected before they accumulate. This leads to the threshold theorem: below a certain physical error rate, increasing the amount of error correction can make an arbitrarily long quantum computation arbitrarily reliable.

Faults and the noise model

A fault-tolerance analysis starts with the circuit to be implemented and asks where it can fail. Classical computation is assumed to be perfect, but anything involving quantum information may be faulty: preparing a qubit, applying a gate, measuring a qubit, and even storing a qubit while it waits.

The standard starting point is the independent stochastic noise model. In this model, faults are assumed to be uncorrelated and to occur independently at each possible fault location with a given probability. Real devices are likely to exhibit some correlations between errors, so this model is only a first approximation to them.

|ψ⟩|0⟩|0⟩HHXZ|ψ⟩

The example is the circuit for . A Hadamard and a CNOT turn two qubits in ∣0⟩|0\rangle into an entangled pair. Two measurements and two corrections controlled by their outcomes then move the state ∣ψ⟩|\psi\rangle from the first qubit to the third.

The circuit is small but uses every kind of operation: a state preparation, one- and two-qubit gates, measurements, and gates controlled by classical bits. On real hardware, each of them can go wrong.

Fault-tolerant quantum circuits

A logical circuit is implemented fault-tolerantly by encoding each logical qubit into a quantum error-correcting code and replacing each logical operation with a fault-tolerant gadget. A gadget is a small physical circuit that performs the desired logical operation on one or more encoded qubits while limiting how a physical fault can spread through the code block. It may include physical gates, extra ancillas, measurements, and intermediate error-correction steps.

Error correction is performed throughout the computation rather than only at the end. The goal is not to prevent every physical fault, but to ensure that a small number of faults produces only a small number of errors in the encoded qubits, so that later correction can remove them.

|ψ⟩|0⟩|0⟩HHXZ|ψ⟩

A fault-tolerant implementation starts with a logical circuit: the computation to be performed, before choosing how to protect it against faults.

Here, the logical circuit is the teleportation circuit, with one wire representing each logical qubit.

Each round of error correction is a substantial circuit. It measures the code's stabilizers using extra ancilla qubits, many two-qubit gates, and measurements, then uses a classical decoder to choose the correction. A round runs on every block after each gadget, so a single logical gate can require hundreds of physical operations, while each logical qubit occupies many physical qubits.

With this much overhead, it is not obvious that encoding helps at all. If the physical operations are too noisy, the additional faults introduced by the larger circuit outweigh the errors that correction removes. The encoded circuit can then fail more often than the corresponding unencoded circuit.

Error propagation

Two-qubit gates can spread errors, even when the gates are perfect. A CNOT propagates an XX error from its control to its target and a ZZ error from its target to its control. Thus, an error on one qubit can become a correlated error on both:

CNOT (X⊗I)=(X⊗X) CNOTCNOT (I⊗Z)=(Z⊗Z) CNOT.\begin{aligned}\mathrm{CNOT}\,(X\otimes I)&=(X\otimes X)\,\mathrm{CNOT}\\[4pt]\mathrm{CNOT}\,(I\otimes Z)&=(Z\otimes Z)\,\mathrm{CNOT}.\end{aligned}

Repeated gates can spread a single error to many qubits, so a single fault may produce more errors within a block than the code can correct. Fault-tolerant gadgets must therefore prevent errors from spreading within a block.

=XXXXX
Pauli errorError before the gates: XX, ZZ, YY or none

Some codes allow transversal implementations of certain gates. A transversal gate acts independently on corresponding qubit positions, without coupling two qubits within the same block.

For example, a transversal CNOT applies a CNOT between each qubit of one block and the corresponding qubit of another block. A single fault can therefore affect at most one qubit in each block, rather than spreading across a block.

AB=XXX

Block A: 1 error · Block B: 1 error

Pauli errorError before the gates: XX, ZZ, YY or noneCode block of three qubits

Different code families support different sets of transversal gates. All stabilizer codes have transversal Pauli gates, while all CSS codes have a transversal CNOT. Some codes support larger sets: the Steane code, for example, supports all Clifford gates transversally.

X=q11Xq12q13q21Xq22q23q31Xq32q33Z=q11Zq12Zq13Zq21q22q23q31q32q33

Transversal gates are an important building block of fault-tolerant computation. They prevent a single fault from spreading to multiple qubits within a code block, allowing error correction to remove the resulting errors. They cannot, however, provide a universal gate set. By the Eastin–Knill theorem, any quantum error-correcting code with distance at least 2 has only a non-universal set of logical gates that can be implemented transversally.

Magic states

Transversal gates provide a fault-tolerant way to implement many logical operations, but they cannot form a universal gate set on their own. The gate that is usually missing is the non-Clifford TT gate, and since Clifford gates together with TT form a , a fault-tolerant computer needs another way to implement it.

The key idea is magic-state injection — instead of implementing TT directly as a transversal gate, prepare a special ancillary state, the magic state, and use it with Clifford gates and measurements:

T∣+⟩=12(∣0⟩+eiπ/4∣1⟩).T|+\rangle=\frac{1}{\sqrt2}\bigl(|0\rangle+e^{i\pi/4}|1\rangle\bigr).

Let the data qubit hold ∣ψ⟩=α∣0⟩+β∣1⟩|\psi\rangle=\alpha|0\rangle+\beta|1\rangle and let a second qubit hold the magic state. A CNOT with the data qubit as control and the magic qubit as target flips the magic qubit in every term where the data qubit is ∣1⟩|1\rangle. Collecting the terms by the value of the magic qubit splits the state into two branches, T∣ψ⟩T|\psi\rangle and, after factoring out eiπ/4e^{i\pi/4}, T†∣ψ⟩T^{\dagger}|\psi\rangle:

CNOT(∣ψ⟩⊗T∣+⟩)=12 CNOT((α∣0⟩+β∣1⟩)⊗(∣0⟩+eiπ/4∣1⟩))=12(α∣00⟩+eiπ/4α∣01⟩+β∣11⟩+eiπ/4β∣10⟩)=12((α∣0⟩+eiπ/4β∣1⟩)⊗∣0⟩+(eiπ/4α∣0⟩+β∣1⟩)⊗∣1⟩)=12((α∣0⟩+eiπ/4β∣1⟩)⏟T∣ψ⟩⊗∣0⟩+eiπ/4(α∣0⟩+e−iπ/4β∣1⟩)⏟T†∣ψ⟩⊗∣1⟩)=12 T∣ψ⟩⊗∣0⟩+eiπ/42 T†∣ψ⟩⊗∣1⟩.\begin{aligned}\mathrm{CNOT}\bigl(\textcolor{#0369a1}{|\psi\rangle}\otimes \textcolor{#a21caf}{T|+\rangle}\bigr)&=\frac{1}{\sqrt2}\,\mathrm{CNOT}\Bigl(\bigl(\textcolor{#0369a1}{\alpha}|0\rangle+\textcolor{#0369a1}{\beta}|1\rangle\bigr)\otimes\textcolor{#a21caf}{\bigl(|0\rangle+e^{i\pi/4}|1\rangle\bigr)}\Bigr)\\[4pt]&=\frac{1}{\sqrt2}\Bigl(\textcolor{#0369a1}{\alpha}|0\textcolor{#a21caf}{0}\rangle+e^{i\pi/4}\textcolor{#0369a1}{\alpha}|0\textcolor{#a21caf}{1}\rangle+\textcolor{#0369a1}{\beta}|1\textcolor{#a21caf}{1}\rangle+e^{i\pi/4}\textcolor{#0369a1}{\beta}|1\textcolor{#a21caf}{0}\rangle\Bigr)\\[4pt]&=\frac{1}{\sqrt2}\Bigl(\bigl(\textcolor{#0369a1}{\alpha}|0\rangle+e^{i\pi/4}\textcolor{#0369a1}{\beta}|1\rangle\bigr)\otimes\textcolor{#a21caf}{|0\rangle}+\bigl(e^{i\pi/4}\textcolor{#0369a1}{\alpha}|0\rangle+\textcolor{#0369a1}{\beta}|1\rangle\bigr)\otimes\textcolor{#a21caf}{|1\rangle}\Bigr)\\[4pt]&=\frac{1}{\sqrt2}\Bigl(\underbrace{\bigl(\textcolor{#0369a1}{\alpha}|0\rangle+e^{i\pi/4}\textcolor{#0369a1}{\beta}|1\rangle\bigr)}_{T\textcolor{#0369a1}{|\psi\rangle}}\otimes\textcolor{#a21caf}{|0\rangle}+e^{i\pi/4}\underbrace{\bigl(\textcolor{#0369a1}{\alpha}|0\rangle+e^{-i\pi/4}\textcolor{#0369a1}{\beta}|1\rangle\bigr)}_{T^{\dagger}\textcolor{#0369a1}{|\psi\rangle}}\otimes\textcolor{#a21caf}{|1\rangle}\Bigr)\\[4pt]&=\frac{1}{\sqrt2}\,T\textcolor{#0369a1}{|\psi\rangle}\otimes\textcolor{#a21caf}{|0\rangle}+\frac{e^{i\pi/4}}{\sqrt2}\,T^{\dagger}\textcolor{#0369a1}{|\psi\rangle}\otimes\textcolor{#a21caf}{|1\rangle}.\end{aligned}

Both branches have weight 1/21/2, so measuring the magic qubit gives 00 or 11 with probability 1/21/2 each, independently of ∣ψ⟩|\psi\rangle. Outcome 00 leaves T∣ψ⟩T|\psi\rangle on the data qubit and needs no correction. Outcome 11 leaves T†∣ψ⟩T^{\dagger}|\psi\rangle up to a global phase, and applying SS turns it into T∣ψ⟩T|\psi\rangle:

ST†=(100i)(100e−iπ/4)=(100eiπ/4)=T.ST^{\dagger}=\begin{pmatrix}1&0\\0&i\end{pmatrix}\begin{pmatrix}1&0\\0&e^{-i\pi/4}\end{pmatrix}=\begin{pmatrix}1&0\\0&e^{i\pi/4}\end{pmatrix}=T.

With this measurement-dependent correction, the circuit applies TT to ∣ψ⟩|\psi\rangle on every run and consumes one magic state. The same idea implements SS using the state S∣+⟩=∣+i⟩S|+\rangle=|{+i}\rangle, with ZZ as the correction. The circuit also works on encoded qubits. With fault-tolerant gadgets and an encoded magic state, it implements a fault-tolerant TT gate.

S|ψ⟩T|+⟩T|ψ⟩
Input
Outcome
After the measurement
T†∣ψ⟩=0.6∣0⟩+(0.566−0.566i)∣1⟩T^{\dagger}|\psi\rangle=0.6|0\rangle+(0.566-0.566i)|1\rangle
After S
0.6∣0⟩+(0.566+0.566i)∣1⟩0.6|0\rangle+(0.566+0.566i)|1\rangle
Equals T|ψ⟩
T∣ψ⟩=0.6∣0⟩+(0.566+0.566i)∣1⟩T|\psi\rangle=0.6|0\rangle+(0.566+0.566i)|1\rangle

Encoded magic states can be prepared through a probabilistic process that does not have to succeed on every attempt. In magic state distillation, several noisy magic states are fed into a distillation circuit, which produces one candidate output while measuring the others. If all measurements give 00, the output is accepted as a less noisy magic state. If any measurement gives 11, the attempt is discarded and repeated with a fresh set of noisy states. Repeating the process produces a supply of high-quality magic states from many successful attempts.

Distiller0000Noisymagic statesLess-noisymagic state

Magic-state injection and distillation provide a general way to implement the non-Clifford gates needed for a universal fault-tolerant gate set. Other approaches to fault-tolerant gate implementation include code deformation and code switching.

Fault-tolerant error correction

Error correction is a circuit too, and, as you might expect, straightforward syndrome measurement is not fault-tolerant either. To measure a generator such as Z⊗Z⊗ZZ\otimes Z\otimes Z, one ancilla qubit in ∣+⟩|+\rangle interacts with each data qubit in turn and is then measured in the ±\pm basis. A single fault on the ancilla can spread to multiple data qubits, producing an error within the code block that is too large for the code to correct.

There are several ways to avoid this:

  • Shor error correction measures each generator using a cat state (∣000⟩+∣111⟩)/2\bigl(|000\rangle+|111\rangle\bigr)/\sqrt2, with one ancilla qubit for each data qubit. The syndrome is then computed from the measurement results.
  • Steane error correction, which works only for CSS codes, uses an encoded state such as ∣+⟩L|+\rangle_L as the ancilla. A transversal CNOT transfers the relevant data information to the encoded ancilla, which is then measured. The syndrome is again extracted classically from the measurement results.

In both schemes, each ancilla qubit interacts with at most one data qubit, so a single fault can cause at most one data-qubit error. Later rounds of error correction can remove such errors. A fault can still corrupt a syndrome bit, so in practice the syndrome is measured multiple times before applying the correction.

data|+⟩ZZZHXZZ

1 fault → 2 data errors, too many for the code to correct

FaultWhere the error spreadsData error after the gatesPlace for a fault

Phew! At this point the whole thing can start to look like an endless loop. Protecting the data takes extra ancilla qubits, gates, and measurements, and each of them is one more place where a fault can occur. Protecting those takes even more qubits, which bring faults of their own, which need protecting too… Whether this chase ever ends depends on how noisy the physical components are.

Threshold theorem

Informally, the threshold theorem says that a quantum circuit with NN gates can be implemented with arbitrarily high accuracy using noisy gates, as long as the error probability at each physical location is below a fixed, nonzero threshold pth>0p_{\mathrm{th}}>0. The resulting noisy circuit needs only O(Nlog⁡cN)O(N\log^c N) locations, for some positive constant cc.

The idea can already be seen with, for example, the , whose error correction removes any single error in a block. A logical location then fails only if at least two faults occur within its fault-tolerant gadget. The probability of this is at most Cp2Cp^2, where CC is a constant that counts the relevant pairs of locations. If p<1/C=pthp<1/C=p_{\mathrm{th}}, this is smaller than pp: the logical error rate is reduced from pp to at most (Cp)p(Cp)p.

The key step is concatenation: treat the first-level fault-tolerant circuit as a logical circuit and encode it again. Each gadget and each round of error correction then becomes a fault-tolerant circuit at the next level.

H

Error rate per location: pp

Each level squares the ratio of the error rate to the threshold, so the logical error rate falls rapidly with every level:

p  ↦  Cp2=(Cp) p  ↦  C((Cp) p)2=(Cp)3 p  ↦  C((Cp)3p)2=(Cp)7 p  ↦  ⋯  ↦  (Cp)2k−1 p.\begin{aligned}p&\;\mapsto\;Cp^2=(Cp)\,p\\[2pt]&\;\mapsto\;C\bigl((Cp)\,p\bigr)^2=(Cp)^3\,p\\[2pt]&\;\mapsto\;C\bigl((Cp)^3p\bigr)^2=(Cp)^7\,p\\[2pt]&\;\mapsto\;\cdots\;\mapsto\;(Cp)^{2^k-1}\,p.\end{aligned}

Gadget constant CC

0.0032

Below the threshold pth=1/Cp_{\mathrm{th}}=1/C

no encoding0.0032
1 level1.0×10⁻³
2 levels1.0×10⁻⁴
3 levels1.0×10⁻⁶
4 levels1.0×10⁻¹⁰
10⁻⁴10⁻³10⁻²10⁻¹110⁻¹²10⁻⁹10⁻⁶10⁻³1physical error rate plogical error ratepth

To make the whole circuit succeed with high probability, the logical error rate must become much smaller than 1/N1/N, since the circuit has NN locations. Below the threshold, error correction can reduce the logical error rate rapidly enough that only about log⁡log⁡N\log\log N levels of error correction are needed. Each level increases the circuit size by only a constant factor, so the total overhead is polylogarithmic in NN, giving the O(Nlog⁡cN)O(N\log^c N) circuit size stated by the theorem.

Congratulations on making it this far!

The road was long: from bits and qubits through measurements, entanglement and quantum algorithms, to channels, error correction and fault tolerance. If something along the way did not make sense, feel free to message me at hello@annaburd.me. I spent a long time working through this material myself.

So what is the takeaway? Quantum computing has another problem beyond the algorithms themselves: making a real quantum computer useful. The hardware is expensive, the qubits are fragile, and useful computations require keeping errors under control. A logical qubit requires many physical qubits, a logical gate requires many physical operations and error-correction steps, and none of this works unless the physical error rate is below the threshold.

So when you see a headline about a quantum computer with thousands of qubits, ask:

  • Are they physical or logical qubits?
  • What are the gate and measurement error rates, and are they below the code's threshold?
  • How many logical qubits does the machine actually provide, and for how long can they run reliably?

A thousand noisy physical qubits may amount to only a handful of logical qubits. If the physical error rate is above the threshold, they may not provide any reliable logical qubits at all.