Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Stabilizer Formalism and the Steane Code

Tags: algorithm error-correction

In Introduction to Quantum Error Correction (the first part), we built the 3-qubit bit-flip and phase-flip codes and Shor’s 9-qubit code, and at the end gave the name “stabilizer” to the parity operators.

This second part treats stabilizers formally. We then implement the CSS construction, which systematically builds quantum codes from classical codes, and its flagship example, the Steane code. The Steane code achieves the same d=3d=3 as Shor’s code with seven qubits instead of nine.

What this article covers:

  1. Stabilizer formalism — formalize stabilizers, generators, and the syndrome.

  2. The CSS construction — build the Steane code’s stabilizers from a classical Hamming code.

  3. Implement encoding, syndrome measurement, and correction for the Steane code.

  4. Confirm that seven physical Hadamard gates act as a logical Hadamard.

Prerequisites: the content of the first part (syndrome measurement, Pauli errors, the term “stabilizer”).

1. Stabilizer Formalism

In the first part, we called parity operators such as Z0Z1Z_0Z_1 and X0X1X_0X_1 stabilizers. We first formalize this term.

1.1 What Is a Stabilizer

A stabilizer is a Pauli operator SS that leaves every state of the code space unchanged. For any codeword ∣ψ⟩\lvert\psi\rangle,

S∣ψ⟩=∣ψ⟩S\lvert\psi\rangle = \lvert\psi\rangle

holds. Equivalently, the code space is the +1 eigenspace of the stabilizer.

For example, the codewords of the bit-flip code are ∣000⟩\lvert000\rangle and ∣111⟩\lvert111\rangle. Applying Z0Z1Z_0Z_1 gives Z0Z1∣000⟩=∣000⟩Z_0Z_1\lvert000\rangle=\lvert000\rangle and Z0Z1∣111⟩=(−1)(−1)∣111⟩=∣111⟩Z_0Z_1\lvert111\rangle=(-1)(-1)\lvert111\rangle=\lvert111\rangle — neither changes. So Z0Z1Z_0Z_1 is a stabilizer of the bit-flip code.

1.2 Generators and the Syndrome

A code has many stabilizers, but we do not need to list them all. Choosing a few generators is enough; the rest are obtained as their products. For the bit-flip code, Z0Z1Z_0Z_1 and Z0Z2Z_0Z_2 are the two generators.

Measuring a stabilizer generator yields the eigenvalue +1 or -1.

  • With no error, the state is in the code space and every generator returns +1.

  • When an error EE occurs, the measured value of any generator that anticommutes with EE flips to -1.

This pattern of ±1\pm1 (written as 0/10/1 in bits) is the syndrome. The values we extracted into ancilla qubits in the first part were exactly the measurement results of stabilizer generators. Seeing which generators turned -1 tells us the location and type of the error.

1.3 The First Part’s Codes as Stabilizers

The three codes from the first part can all be described with stabilizer generators.

CodeStabilizer generators
3-qubit bit-flipZ0Z1, Z0Z2Z_0Z_1,\ Z_0Z_2
3-qubit phase-flipX0X1, X0X2X_0X_1,\ X_0X_2
Shor 9-qubitZ0Z1, Z0Z2, Z3Z4, Z3Z5, Z6Z7, Z6Z8, X0X1X2X3X4X5, X3X4X5X6X7X8Z_0Z_1,\ Z_0Z_2,\ Z_3Z_4,\ Z_3Z_5,\ Z_6Z_7,\ Z_6Z_8,\ X_0X_1X_2X_3X_4X_5,\ X_3X_4X_5X_6X_7X_8

The bit-flip code has only ZZ-type generators, and the phase-flip code only XX-type generators. Shor’s code has both, with the ZZ-type detecting XX errors and the XX-type detecting ZZ errors. This structure of “holding XX-type and ZZ-type generators separately” leads to the CSS construction in the next section.

1.4 [[n,k,d]][[n,k,d]] and the Code Distance

A stabilizer code is characterized by three numbers, [[n,k,d]][[n,k,d]].

  • nn: the number of physical qubits.

  • kk: the number of logical qubits protected. Each generator removes one degree of freedom, so k=n−(number of generators)k = n - (\text{number of generators}).

  • dd: the code distance. It is the minimum weight (the number of qubits acted on) among the Pauli operators that commute with every stabilizer but are not themselves stabilizers — these are called logical operators.

A code of distance dd can correct up to ⌊(d−1)/2⌋\lfloor(d-1)/2\rfloor errors. Correcting any single-qubit error requires d≥3d\ge3. The 3-qubit codes from the first part had d=1d=1 and Shor’s code had d=3d=3. The Steane code we are about to build is [[7,1,3]][[7,1,3]].

2. From Classical Hamming Codes to CSS Codes

A CSS code (Calderbank-Shor-Steane code) is a way to build quantum codes systematically from classical error-correcting codes. The Steane code is its flagship example, based on the classical Hamming code.

2.1 The Classical Hamming [7,4,3] Code

The classical Hamming [7,4,3] code protects 4 bits of information with 7 bits and can correct a single-bit error. It is defined by a parity-check matrix HH.

H=(000111101100111010101)H = \begin{pmatrix} 0 & 0 & 0 & 1 & 1 & 1 & 1 \\ 0 & 1 & 1 & 0 & 0 & 1 & 1 \\ 1 & 0 & 1 & 0 & 1 & 0 & 1 \end{pmatrix}

A 7-bit word cc is a codeword if and only if Hc=0Hc=0 (its parity with every row is even).

2.2 How the Columns Point to the Error Location

Look closely at the columns of HH: column jj is the binary representation of the number j+1j+1 (column 0 is 001, column 1 is 010, …, column 6 is 111).

When a single-bit error occurs at position jj, HcHc equals exactly column jj. So reading the three bits of HcHc as a binary number gives the error location directly. This is the mechanism by which the classical Hamming code pinpoints the error location in one shot.

2.3 The CSS Construction: XX-Type and ZZ-Type Stabilizers

The CSS construction builds two kinds of stabilizers from this parity-check matrix HH.

  • ZZ-type stabilizers: read each row of HH as an operator placing ZZ where the 1s are. Detects XX errors.

  • XX-type stabilizers: read the same rows as operators placing XX. Detects ZZ errors.

An XX error anticommutes with the ZZ-type stabilizers, and a ZZ error anticommutes with the XX-type stabilizers. So the ZZ-type locate the XX errors and the XX-type locate the ZZ errors, each in exactly the same way as the classical Hamming code. The “correct XX and ZZ independently” seen in Shor’s code in the first part comes out automatically from the classical code here.

2.4 The Six Generators of the Steane Code

From the three rows of the Hamming matrix HH we obtain three ZZ-type and three XX-type generators — six stabilizer generators in total.

TypeStabilizerDetects
XX typeX3X4X5X6X_3X_4X_5X_6ZZ
XX typeX1X2X5X6X_1X_2X_5X_6ZZ
XX typeX0X2X4X6X_0X_2X_4X_6ZZ
ZZ typeZ3Z4Z5Z6Z_3Z_4Z_5Z_6XX
ZZ typeZ1Z2Z5Z6Z_1Z_2Z_5Z_6XX
ZZ typeZ0Z2Z4Z6Z_0Z_2Z_4Z_6XX

With 7 physical qubits and 6 generators, the number of logical qubits protected is 7−6=17-6=1. This is the Steane [[7,1,3]][[7,1,3]] code.

Before getting into the implementation, we load Qamomile and the Qiskit integration and define helper functions. _bits7, _passes_hamming_checks, and _is_steane_zero_word are utilities that decide whether a measurement outcome is a Hamming codeword or a ∣0L⟩\lvert0_L\rangle codeword. They are not central to QEC, so feel free to skip them.

3. Encoding the Logical ∣0L⟩\lvert0_L\rangle

3.1 The Logical Zero Is a Superposition of Even-Weight Hamming Codewords

The logical ∣0L⟩\lvert0_L\rangle of the Steane code is the superposition of all even-weight Hamming codewords.

∣0L⟩=122∑c∈C, w(c) even∣c⟩\lvert0_L\rangle = \frac{1}{2\sqrt2}\sum_{c\in C,\ w(c)\,\text{even}} \lvert c\rangle

Here CC is the set of Hamming codewords and w(c)w(c) is the weight. There are 8 even-weight Hamming codewords, so this is an 8-term superposition.

3.2 The Encoding Circuit

The following circuit builds ∣0L⟩\lvert0_L\rangle from ∣0⟩⊗7\lvert0\rangle^{\otimes7}. It writes in the three XX-type stabilizer patterns (X3X4X5X6X_3X_4X_5X_6, X1X2X5X6X_1X_2X_5X_6, X0X2X4X6X_0X_2X_4X_6) one by one with Hadamard and CNOT gates.

3.3 Checking the Encoding

We measure the encoder’s output and check that every observed bitstring is an even-weight Hamming codeword (a ∣0L⟩\lvert0_L\rangle codeword).

Encode and measure |0_L>
  |0_L> codeword ratio: 1.000
  distinct codewords observed: 8

4. Syndrome Measurement and Correction

4.1 Decoding XX and ZZ Independently

The advantage of a CSS code is that XX errors and ZZ errors can be handled completely independently.

  • Measuring the ZZ-type stabilizers gives the syndrome for XX errors.

  • Measuring the XX-type stabilizers gives the syndrome for ZZ errors.

Each is a 3-bit syndrome, and the column mechanism of the Hamming matrix seen in 2.2 applies directly.

4.2 The Syndrome Table

The 3-bit syndrome (s2,s1,s0)(s_2,s_1,s_0) represents the error location directly in binary.

Error locationSyndrome (s2,s1,s0)(s_2,s_1,s_0)
none(0,0,0)(0,0,0)
q0q_0(0,0,1)(0,0,1)
q1q_1(0,1,0)(0,1,0)
q2q_2(0,1,1)(0,1,1)
q3q_3(1,0,0)(1,0,0)
q4q_4(1,0,1)(1,0,1)
q5q_5(1,1,0)(1,1,0)
q6q_6(1,1,1)(1,1,1)

The (s2,s1,s0)(s_2,s_1,s_0) obtained from the ZZ-type stabilizers points to the XX error location, and the one from the XX-type points to the ZZ error location.

4.3 Implementation

error_type is 1=X, 2=Y, 3=Z, and error_pos is the qubit index 0..6 to inject the error into.

4.4 Verification: All 21 Single Errors

We try all 21 single errors — XX, YY, ZZ on each of the seven qubits. After correction, every measured bitstring should return to a ∣0L⟩\lvert0_L\rangle codeword.

Steane code: correct X/Y/Z on all 7 locations
  err  | pos   | |0_L> codeword
  -----+-------+---------------
  X    | q[0]  | 1.000
  X    | q[1]  | 1.000
  X    | q[2]  | 1.000
  X    | q[3]  | 1.000
  X    | q[4]  | 1.000
  X    | q[5]  | 1.000
  X    | q[6]  | 1.000
  Y    | q[0]  | 1.000
  Y    | q[1]  | 1.000
  Y    | q[2]  | 1.000
  Y    | q[3]  | 1.000
  Y    | q[4]  | 1.000
  Y    | q[5]  | 1.000
  Y    | q[6]  | 1.000
  Z    | q[0]  | 1.000
  Z    | q[1]  | 1.000
  Z    | q[2]  | 1.000
  Z    | q[3]  | 1.000
  Z    | q[4]  | 1.000
  Z    | q[5]  | 1.000
  Z    | q[6]  | 1.000

A ratio of 1.000 means the state returned to the ∣0L⟩\lvert0_L\rangle code space for that single Pauli error. A Y=iXZY=iXZ error triggers both the XX-component and the ZZ-component correction, but in a CSS code these two are independent, so it is corrected as is.

5. The Transversal Hadamard Gate

5.1 What Is a Transversal Gate

When applying a logical gate to a logical qubit, if it suffices to apply a physical gate independently to each physical qubit, that gate is called transversal.

Transversal gates are important in fault-tolerant quantum computation. Because the physical gates are independent of one another, a failure in one physical gate does not spread the error across multiple qubits within a block.

A major feature of the Steane code is that the logical Hadamard Hˉ\bar H is transversal. Applying HH to each of the seven physical qubits is itself the logical Hadamard.

Hˉ=H⊗7\bar H = H^{\otimes 7}

This follows from the XX-type and ZZ-type stabilizers of the Steane code having the same Hamming pattern — from the CSS construction using the same matrix HH.

5.2 Verifying the Logical Hadamard

We verify Hˉ=H⊗7\bar H = H^{\otimes7} through two properties.

Property 1: Hˉ\bar H maps ∣0L⟩\lvert0_L\rangle to ∣+L⟩\lvert+_L\rangle. ∣+L⟩\lvert+_L\rangle is a superposition of ∣0L⟩\lvert0_L\rangle and ∣1L⟩\lvert1_L\rangle. While ∣0L⟩\lvert0_L\rangle consists of even-weight Hamming codewords, ∣1L⟩\lvert1_L\rangle consists of odd-weight Hamming codewords. So measuring ∣+L⟩\lvert+_L\rangle produces Hamming codewords of both even and odd weight (whereas ∣0L⟩\lvert0_L\rangle produces only even-weight ones).

Transversal H: |0_L> -> |+_L>
  Hamming codeword ratio: 1.000
  odd-weight (|1_L>) fraction: 0.518

The Hamming codeword ratio is 1.000, and odd-weight codewords appear about half the time. Unlike ∣0L⟩\lvert0_L\rangle, which produces only even-weight codewords, this confirms the state has moved to ∣+L⟩\lvert+_L\rangle.

Property 2: applying Hˉ\bar H twice returns to the identity (Hˉ2=I\bar H^2 = I). Applying H⊗7H^{\otimes7} twice to ∣0L⟩\lvert0_L\rangle should return to ∣0L⟩\lvert0_L\rangle.

Transversal H round trip: |0_L> -> H -> H -> |0_L>
  |0_L> codeword ratio: 1.000

The ratio is 1.000 — two transversal Hadamards return to ∣0L⟩\lvert0_L\rangle. The seven physical HH gates indeed act as the logical Hˉ\bar H.

6. Summary

In this article we covered the stabilizer formalism and the Steane [[7,1,3]][[7,1,3]] code.

  • Stabilizer formalism — we viewed the code space as the +1 eigenspace of Pauli operators (stabilizers) and defined the syndrome as the measurement values of the generators.

  • The CSS construction — we built XX-type and ZZ-type stabilizers from the parity-check matrix of the classical Hamming [7,4,3] code.

  • The Steane code — we implemented the encoding of ∣0L⟩\lvert0_L\rangle, syndrome measurement with the six stabilizers, and correction of all 21 single Pauli errors.

  • The transversal Hadamard — we confirmed that seven physical HH gates act as the logical Hˉ\bar H.

The Steane code achieves the same d=3d=3 as Shor’s code with seven qubits instead of nine, and is a clean example of the CSS construction and transversal Clifford gates.

Beyond

  • The surface code — a code whose stabilizers are local operators on a 2D lattice. It is the leading approach to error correction on today’s superconducting quantum computers, with repeated syndrome measurement as a new ingredient.

  • Fault-tolerant quantum computation — a framework for running logical gates while staying encoded and advancing the computation without amplifying errors. Transversal gates are its starting point.