Quantum Computation & Cryptography · Lecture 19

Lecture 19
Noise on Real Hardware and Error Mitigation

Week 10  |  what a calibration table says, what the compiler does to your circuit, and how to get better numbers out of noisy runs without error correction  |  Lab 5 launches today  |  reading: IBM Quantum Learning, Quantum Computing in Practice (selected lessons)

Cartoon: extrapolating past the noiseA stick figure stands beside a chart with three dots that drift downward as a dial labelled noise is turned up from 1 to 3 to 5. A dashed line runs from the dots back to the left edge, where the noise would be zero. A speech bubble says: I can't turn the noise down, but I can turn it up, and work backwards. 135noise I can't turn the noisedown, but I can turn itup, and work backwards
error mitigation does not remove errors; it estimates what an error-free run would have given, and pays for it in shots
In this lecture
  1. Relaxation and dephasing: T1 and T2
  2. The other errors, and reading a calibration table
  3. Transpilation: what the compiler does to your circuit
  4. Readout-error mitigation
  5. Zero-noise extrapolation
  6. Twirling: making errors simple
  7. Mitigation versus correction, and the "utility" experiments
  8. Try it in code
  9. Summary, exercises and Lab 5

Lecture 18 gave us the language of noise: density matrices and channels. Today we use it on real devices. By the end you should be able to read a device's calibration data and turn \(T_1\), \(T_2\) and gate errors into rough success probabilities; explain what transpilation does and why it adds gates; correct measured probabilities for readout error, and say when that goes wrong; carry out zero-noise extrapolation by hand and say what it costs; and explain why none of this replaces error correction.

1 — Relaxation and dephasing: T1 and T2

A superconducting qubit is a tiny electrical circuit at about 10 millikelvin, and \(|1\rangle\) is its excited state. Left alone it loses energy to its surroundings and drops to \(|0\rangle\); and even when it keeps its energy, slow fluctuations in its frequency scramble the relative phase between \(|0\rangle\) and \(|1\rangle\). The two processes are measured separately.

definition 19.1 — T1 and T2

The relaxation time \(T_1\) and the dephasing time \(T_2\) are the time constants in

$$P\big(\text{still }|1\rangle\text{ after time }t\big)=e^{-t/T_1},\qquad |\rho_{01}(t)|=|\rho_{01}(0)|\,e^{-t/T_2}.$$

The first is amplitude damping (Lecture 18) with \(\gamma(t)=1-e^{-t/T_1}\). The second is the decay of the coherence, the off-diagonal entry; its size \(|\rho_{01}|\) is half the length of the Bloch vector's \(xy\) part.

A qubit has \(T_1=80\) μs and \(T_2=50\) μs. After it waits 40 μs, what fraction of its \(|1\rangle\) population survives, and what fraction of its coherence \(|\rho_{01}|\)?

Each quantity decays with its own time constant: \(e^{-t/T_1}\) for the population, \(e^{-t/T_2}\) for the coherence.
\(e^{-40/80}\approx0.607\) and \(e^{-40/50}\approx0.449\). With \(T_2\lt T_1\), the coherence goes first.

Relaxation destroys coherence too: a qubit that has decayed to \(|0\rangle\) has no relative phase left. Separating the two effects gives

$$\frac1{T_2}=\frac1{2T_1}+\frac1{T_\varphi},$$

where \(T_\varphi\) is the time constant of pure dephasing (frequency noise). Since \(1/T_\varphi\ge0\), always \(T_2\le2T_1\). The factor 2 is because coherence is an amplitude (it decays like \(\sqrt{e^{-t/T_1}}\)) while \(T_1\) describes a probability.

Suppose a qubit has no pure dephasing at all (\(1/T_\varphi=0\)), so relaxation is the only source of decoherence. Then \(T_2=\) .

Set \(1/T_\varphi=0\) in \(1/T_2=1/(2T_1)+1/T_\varphi\).
\(1/T_2=1/(2T_1)\), so \(T_2=2T_1\): the upper limit. Any frequency noise only makes \(T_2\) shorter.

These are exponential decay models of exactly the kind fitted in an introductory statistics course: an experiment prepares \(|1\rangle\), waits \(t\), measures, repeats a few thousand times for each of 30 or so values of \(t\), and fits \(e^{-t/T_1}\) to the fraction still in \(|1\rangle\). \(T_2\) is measured the same way with a superposition (a Ramsey experiment, which measures a slightly shorter \(T_2^*\), or an echo experiment, which measures \(T_2\); calibration tables report the echo value).

Relaxation and dephasing of one qubitTwo decaying exponential curves against time in microseconds from 0 to 400. The sky curve is the probability that a qubit prepared in |1> is still in |1>, exp(-t/T1) with T1 = 150 microseconds. The amber curve is the size of the coherence of a |+> state, exp(-t/T2) with T2 = 90 microseconds, which decays faster. Markers at t = 10 microseconds show 0.936 and 0.895; dotted verticals mark t = T2 and t = T1, where each curve has fallen to 1/e, about 0.37.0.000.250.500.751.000100200300400time t (microseconds)remainingT1T2markers at t = 10 us: 0.936 and 0.895population of |1>: exp(-t/T1)coherence of |+>: exp(-t/T2)T1 = 150 us, T2 = 90 us
Relaxation and dephasing for \(T_1=150\) μs and \(T_2=90\) μs, close to the medians of the 2025 ibm_fez snapshot in Section 2 (newer chips do better: IBM reports a median \(T_1\) near 350 μs for its 2026 Nighthawk processor). Each curve falls to \(1/e\approx0.37\) at its own time constant. Coherence is the more fragile resource.
example 19.1 — how long is long?

A qubit has \(T_1=150\) μs and \(T_2=90\) μs. (a) A circuit keeps it waiting for 10 μs. What fraction of its \(|1\rangle\) population and of its coherence survives? (b) What is \(T_\varphi\)? (c) Two-qubit gates take about 84 ns and single-qubit gates about 24 ns on the device of Section 2. How many layers of "one two-qubit gate plus one single-qubit gate" fit in 10 μs?

(a) \(e^{-10/150}\approx0.936\) and \(e^{-10/90}\approx0.895\): about 6% of the population and 11% of the coherence are lost. (b) \(1/T_\varphi=1/90-1/300\), so \(T_\varphi\approx128.6\) μs. (c) One layer takes \(84+24=108\) ns, so 10 μs is about 92 layers, and 100 layers take 10.8 μs. A circuit of depth 100 already loses about a tenth of its coherence to idling alone, before counting any gate errors.

2 — The other errors, and reading a calibration table

Decay during idling is only part of the story. A device's calibration data, refreshed every day or so, lists for each qubit and each coupled pair:

The code in Section 8 prints part of the calibration snapshot that Qiskit ships for the 156-qubit IBM device ibm_fez: median \(T_1\approx145\) μs, median \(T_2\approx88\) μs, median readout error about 0.76%, and median two-qubit (CZ) error about 0.39%, with a wide spread between qubits (qubit 0 has \(T_1\) under 50 μs; seven couplers are marked unusable with error 1). These are a snapshot from February 2025, not current values; in class we pull the live numbers instead, and they will be different.

A crude but useful rule: if a circuit has \(G\) two-qubit gates of error \(\varepsilon\), the probability that none of them fails is about \((1-\varepsilon)^G\approx e^{-\varepsilon G}\). At \(\varepsilon=0.004\) that is 67% for 100 gates and 2% for 1,000. Everything in the rest of this lecture is about doing better than this rule suggests without full error correction.

A circuit has 500 two-qubit gates, each with error \(\varepsilon=0.003\). Estimate the probability that none of them fails.

\((1-\varepsilon)^G\approx e^{-\varepsilon G}\), and \(\varepsilon G\) here is 1.5.
\(e^{-1.5}\approx0.22\) (and \(0.997^{500}\approx0.223\)): most runs of this circuit contain at least one gate error.

3 — Transpilation: what the compiler does to your circuit

The circuits we wrote in Blocks I and II used any gate on any pair of qubits. Hardware offers a small basis of native gates (on IBM's Heron devices: \(R_Z(\theta)\), \(\sqrt X\), \(X\), and \(CZ\), plus optional fractional two-qubit gates) and a fixed coupling map, the graph of pairs that can interact. On IBM's Heron devices it is a heavy-hex lattice, in which every qubit has at most three neighbours (IBM's newer Nighthawk chips use a square lattice with four). Transpilation turns an abstract circuit into one the device can run, in stages:

  1. Layout: choose which physical qubit holds each circuit qubit, preferring well-calibrated qubits that are close together.
  2. Routing: when a two-qubit gate acts on qubits that are not neighbours, insert SWAPs to bring them together. Each SWAP costs three CNOTs (Lecture 7).
  3. Translation: rewrite every gate in the basis (for example \(\text{CNOT}=(I\otimes H)\,CZ\,(I\otimes H)\), and \(H\) into \(R_Z\) and \(\sqrt X\)).
  4. Optimization: cancel and merge gates; higher optimization_level works harder.
Routing a CNOT between distant qubitsTop row: five qubits q0 to q4 in a line, each joined only to its neighbours. A dashed arc from q0 to q4 is labelled: CNOT(0,4) wanted, not native. Below, three rows show the routed version: SWAP q0 and q1, then q1 and q2, then q2 and q3, carrying the control's state one step right each time, until it sits on q3 next to q4, where the CNOT is applied. Each SWAP costs three CNOTs, so the total is 3 times 3 plus 1, ten CNOTs, which is what Qiskit's transpiler produces.q0q1q2q3q4wantCNOT(0,4): not an edge of the graphq0q1q2q3q4SWAP 1q0q1q2q3q4SWAP 2q0q1q2q3q4SWAP 3then CNOT(3,4)3 SWAPs x 3 CNOTs+ 1 CNOT= 10 CNOTsshaded: where the control'sstate now lives
Routing on a line. A CNOT between qubits 0 and 4 is carried out by swapping the control's state along the line until it sits next to the target. Qiskit's transpiler, run on this circuit with a fixed layout, produces exactly 10 CNOTs (verify_L19.py). At a two-qubit error of 0.0039, the success estimate drops from 0.996 for one CNOT to \(0.9961^{10}\approx0.962\).

Routing is why a good layout matters, and why algorithms whose interactions are local in space (like the surface code of Lecture 23) suit this hardware. It also means that a circuit's depth and gate count on paper are lower bounds: always report the counts after transpilation.

Six qubits sit on a line, 0–1–2–3–4–5. A circuit asks for one CNOT with control 0 and target 5. If the router moves the control along the line until it is next to the target, how many CNOTs does the routed circuit contain?

The control must move from position 0 to position 4, one SWAP per step, and each SWAP costs three CNOTs. Then add the CNOT itself.
Four SWAPs, \(4\cdot3=12\) CNOTs, plus the original one: 13. One gate on paper, thirteen on the device.

4 — Readout-error mitigation

Readout errors act on the classical outcome after the quantum part is over, so they can be described by a stochastic matrix, like the Markov chains of HW1.

definition 19.2 — confusion matrix

For one qubit with \(e_0=P(\text{read }1\mid0)\) and \(e_1=P(\text{read }0\mid1)\), the confusion matrix \(A\) has columns indexed by the true value and rows by the value read:

$$A=\begin{pmatrix}1-e_0&e_1\\ e_0&1-e_1\end{pmatrix},\qquad \vec p_{\text{obs}}=A\,\vec p_{\text{true}} .$$

It is estimated by preparing \(|0\rangle\) and \(|1\rangle\) many times and recording what is read. For \(n\) qubits with independent readout errors, the full \(2^n\times2^n\) matrix is \(A_{n-1}\otimes\cdots\otimes A_0\).

A qubit has \(e_0=0.03\) and \(e_1=0.06\), and its true distribution is \(p_{\text{true}}=(0.8,\,0.2)\). With what frequency is 1 read?

Use the second row of \(A\): \(p_{\text{obs}}(1)=e_0\,p_{\text{true}}(0)+(1-e_1)\,p_{\text{true}}(1)\).
\(0.03\cdot0.8+0.94\cdot0.2=0.024+0.188=0.212\): true 0s misread as 1 add more than true 1s misread as 0 take away.
proposition 19.1 — inverting one qubit's readout

If \(e_0+e_1\ne1\), then \(A\) is invertible and the corrected probability of reading 1 is

$$p_{\text{true}}(1)=\frac{p_{\text{obs}}(1)-e_0}{1-e_0-e_1}.$$

\(\det A=(1-e_0)(1-e_1)-e_0e_1=1-e_0-e_1\). The second row of \(\vec p_{\text{obs}}=A\vec p_{\text{true}}\) reads \(p_{\text{obs}}(1)=e_0\,p_{\text{true}}(0)+(1-e_1)\,p_{\text{true}}(1)\). Substitute \(p_{\text{true}}(0)=1-p_{\text{true}}(1)\): \(p_{\text{obs}}(1)=e_0+(1-e_0-e_1)\,p_{\text{true}}(1)\), and solve.

example 19.2 — correcting a measured probability

Readout errors are \(e_0=0.02\) and \(e_1=0.05\). (a) An experiment reads 1 with frequency 0.30. What is the mitigated estimate? (b) Another reads 1 with frequency 0.015. What goes wrong?

(a) \((0.30-0.02)/(1-0.07)=0.28/0.93\approx0.301\). The correction is small here because the two errors nearly cancel near 0.3: \(|1\rangle\) results lost to \(e_1\) are replaced by \(|0\rangle\) results misread as 1.

(b) \((0.015-0.02)/0.93\approx-0.0054\): a negative "probability". The observed frequency is itself random, and when the true value is near 0, shot noise can put \(p_{\text{obs}}(1)\) below \(e_0\). The inverse of a stochastic matrix is not stochastic. In practice one projects the result back to the nearest probability vector (here: 0) or uses a constrained least-squares fit.

The cost of readout mitigation is mild for few qubits: the variance of the estimate is multiplied by about \(1/(1-e_0-e_1)^2\) per qubit. The difficulty is size: a \(2^n\times2^n\) matrix cannot even be stored for \(n=50\). Practical methods assume a tensor-product (or nearest-neighbour) structure, or mitigate only expectation values of Pauli observables, where each qubit's correction is a single factor. Lab 5 builds the matrix for a GHZ experiment and applies it.

Readout correction

Set the two readout errors and the observed frequency of 1. The bars show the observed and corrected distributions. Push the observed frequency below \(e_0\) to see the inverse go negative.

5 — Zero-noise extrapolation

Gate errors cannot be undone after the fact the way readout errors can, because they act in the middle of the computation. Zero-noise extrapolation (ZNE) takes a different route: we cannot reduce the noise, but we can increase it in a controlled way, measure how the answer changes, and extrapolate back to zero noise.

definition 19.3 — zero-noise extrapolation by gate folding

Let \(E(\lambda)\) be the measured expectation value of an observable when the noise is scaled by a factor \(\lambda\ge1\), with \(E(1)\) the ordinary noisy run. Gate folding replaces a gate \(G\) by \(G\,G^\dagger G\): the same unitary, three times the noise. Folding every gate \(k\) times gives \(\lambda=2k+1\in\{1,3,5,\dots\}\). ZNE fits a model to \(E(\lambda_1),\dots,E(\lambda_m)\) and reports the fitted value at \(\lambda=0\).

The answer depends on the model. A linear fit assumes \(E(\lambda)\approx a+b\lambda\). Richardson extrapolation passes a polynomial of degree \(m-1\) through all \(m\) points. An exponential fit assumes \(E(\lambda)\approx a\,e^{-b\lambda}\), which is what a depolarizing channel after every gate produces: each use shrinks the Bloch vector, and an observable's expectation value, by a fixed factor. Each extrapolated value is a fixed linear combination \(\sum_iw_iE(\lambda_i)\) of the measurements (for the linear and polynomial fits), with \(\sum_iw_i=1\).

A ZNE experiment measures \(E(1)=0.60\) and \(E(3)=0.45\). What is the linear extrapolation to \(\lambda=0\)?

The slope per unit of \(\lambda\) is \((0.45-0.60)/2\). Going from \(\lambda=1\) back to \(\lambda=0\) is one unit.
The slope is \(-0.075\), so \(E(0)=0.60+0.075=0.675\). (The exponential model would give \(0.60/\sqrt{0.75}\approx0.693\): the model matters.)
example 19.3 — ZNE by hand

An observable whose noiseless value is unknown is measured at \(\lambda=1\) and \(\lambda=3\), giving \(E(1)=0.80\) and \(E(3)=0.56\). Extrapolate to \(\lambda=0\) with a straight line and with an exponential.

Linear: the slope is \((0.56-0.80)/2=-0.12\) per unit of \(\lambda\), so \(E(0)=0.80+0.12=0.92\). Exponential: \(E(3)/E(1)=0.7=e^{-2b}\), so each unit of \(\lambda\) multiplies by \(\sqrt{0.7}\approx0.837\), and \(E(0)=0.80/\sqrt{0.7}\approx0.956\). Two reasonable models differ by 0.036, more than the shot noise of a typical run. Choosing the model is the main source of systematic error in ZNE.

Zero-noise extrapolation on synthetic dataMeasured expectation values at noise scale factors 1, 3 and 5 (circles with error bars: 0.921, 0.796, 0.675), generated from the model exp(-0.08 lambda) with 4000 shots each. Three fits are extended to lambda = 0: a least-squares line gives 0.982, the quadratic through all three points (Richardson) gives 0.984, and an exponential fit gives 0.998. The true noiseless value 1 is a dashed line. The raw value at lambda = 1 is 0.921.0.60.70.80.91.01.1012345noise scale factor lambdalinear fit: 0.982Richardson: 0.984exponential: 0.998raw (lambda = 1): 0.921true value: 1bars: +/- 2 standarderrors, 4000 shots
Synthetic ZNE data: \(E(\lambda)=e^{-0.08\lambda}\) (true noiseless value 1), sampled with 4,000 shots at each of \(\lambda=1,3,5\) (seeded, verify_L19.py). The raw value is 0.921. The exponential fit, which matches how the data were generated, recovers 0.998; the linear and Richardson fits get most of the way, to 0.982 and 0.984. On hardware the true model is not known.
proposition 19.2 — the price of extrapolation

If the \(E(\lambda_i)\) are independent with standard deviations \(\sigma_i\), an extrapolated value \(\sum_iw_iE(\lambda_i)\) has standard deviation \(\sqrt{\sum_iw_i^2\sigma_i^2}\). For \(\lambda=1,3,5\), the Richardson weights are \(\big(\tfrac{15}8,-\tfrac54,\tfrac38\big)\) and the least-squares-line weights are \(\big(\tfrac{13}{12},\tfrac13,-\tfrac5{12}\big)\). With equal \(\sigma\), the variance is multiplied by \(\sum w_i^2\approx5.22\) and \(1.46\) respectively.

The variance formula is the variance of a linear combination of independent variables. Richardson: the quadratic through the three points evaluated at 0 is \(\sum_iE(\lambda_i)\ell_i(0)\) with the Lagrange basis \(\ell_i(0)=\prod_{j\ne i}\frac{0-\lambda_j}{\lambda_i-\lambda_j}\): \(\ell_1(0)=\frac{(-3)(-5)}{(-2)(-4)}=\frac{15}8\), \(\ell_3(0)=\frac{(-1)(-5)}{(2)(-2)}=-\frac54\), \(\ell_5(0)=\frac{(-1)(-3)}{(4)(2)}=\frac38\). Then \(\sum w_i^2=\frac{225+100+9}{64}=\frac{334}{64}\approx5.22\). The least-squares line through \((\lambda_i,E_i)\) has intercept \(\bar E-\bar\lambda\,\hat b\) with \(\hat b=\sum(\lambda_i-\bar\lambda)E_i/\sum(\lambda_i-\bar\lambda)^2\), \(\bar\lambda=3\), \(\sum(\lambda_i-3)^2=8\), so \(w_i=\frac13-\frac{3(\lambda_i-3)}8\): \(\frac{13}{12},\frac13,-\frac5{12}\), with \(\sum w_i^2=\frac{169+16+25}{144}\approx1.46\).

Compared with simply reporting the raw noisy value \(E(1)\), the Richardson extrapolation from \(\lambda=1,3,5\) (with the same shots per point) has

Proposition 19.2: what is \(\sum w_i^2\) for Richardson, and what is it for the raw value (one weight, equal to 1)?
Richardson removes the noise exactly if \(E(\lambda)\) is quadratic, so its bias is small, but its variance is about 5.2 times that of one raw point. Bias is traded for variance.

In the figure, the raw value has standard error 0.006, the linear extrapolation 0.009 and the Richardson extrapolation 0.017 (the folded runs are also noisier, since their \(E\) is smaller). To keep the same precision, Richardson needs about \(0.017^2/0.006^2\approx8\) times as many shots. The more aggressive the model, the smaller the bias and the larger the variance: the usual statistical trade-off.

ZNE explorer

The "device" has true noiseless value 1 and decays as \(e^{-b\lambda}\) (or, with the second model, as \(1-b\lambda-b^2\lambda^2\)). Choose the noise strength and the shots per point, draw a new data set, and compare the three extrapolations. Redraw several times to see the spread.

6 — Twirling: making errors simple

Not all errors are random. A gate that is miscalibrated by a small angle \(\varepsilon\) applies \(R_X(\varepsilon)\) every time, a coherent error. Coherent errors add up in amplitude: after \(n\) repetitions the state has rotated by \(n\varepsilon\), and the error probability is \(\sin^2(n\varepsilon/2)\), which grows like \(n^2\varepsilon^2\). A stochastic error that flips the qubit with probability \(p\) each time grows only like \(np\).

Pauli twirling converts the first kind into the second. Before each noisy gate apply a random Pauli \(P\), and after it the Pauli that undoes \(P\) (for a Clifford gate this is another Pauli, which can be merged into neighbouring gates, so the ideal circuit is unchanged). Averaged over the random choices, the error becomes a Pauli channel: a mixture \(\sum_Pq_PP\rho P\). For the over-rotation, \(\tfrac14\sum_PPR_X(\varepsilon)P\,\rho\,PR_X(\varepsilon)^\dagger P=\cos^2\tfrac\varepsilon2\,\rho+\sin^2\tfrac\varepsilon2\,X\rho X\) (checked numerically in verify_L19.py), a bit flip with \(p=\sin^2(\varepsilon/2)\).

For small total errors, doubling the number of repetitions \(n\) multiplies the error probability of a coherent over-rotation by about and that of the twirled (stochastic) error by about .

Coherent: \(\sin^2(n\varepsilon/2)\approx n^2\varepsilon^2/4\). Stochastic: about \(np\).
The coherent probability grows like \(n^2\), so it quadruples; the Pauli error grows like \(n\), so it doubles. That gap is what twirling buys.
example 19.4 — coherent versus twirled

A gate over-rotates by \(\varepsilon=0.02\) rad and is applied 100 times to \(|0\rangle\). Compare the probability of reading 1 with and without twirling.

Coherent: \(\sin^2(100\cdot0.02/2)=\sin^2(1)\approx0.708\). Twirled: each gate is a bit flip with \(p=\sin^2(0.01)\approx10^{-4}\); after \(n\) uses the flip probability is \(\tfrac12\big(1-(1-2p)^n\big)\approx0.0099\). Twirling did not make the gate better on average (the average fidelity of one gate is unchanged); it made the errors stop adding coherently. It also makes the noise the kind that ZNE's models and error correction's analysis assume. This is also called randomized compiling (Wallman and Emerson, 2016).

7 — Mitigation versus correction, and the "utility" experiments

Every mitigation method trades shots for bias. The most powerful one, probabilistic error cancellation, writes the inverse of each gate's noise channel as a combination of physical operations with some negative coefficients, and samples circuits from it; the price is a factor \(\gamma^2\) more shots per gate, where \(\gamma\gt1\) grows with the gate's error. Over a circuit of \(N\) gates the shot count is multiplied by \(\gamma^{2N}\). With \(\gamma=1.002\) (an illustrative value for a gate with error of order \(10^{-3}\)), that is a factor of 54 for \(N=1{,}000\) gates and about \(2\times10^{17}\) for \(N=10{,}000\). ZNE's variance grows more slowly, but its bias grows with the circuit size instead.

With \(\gamma=1.002\) per gate, by what factor does probabilistic error cancellation multiply the number of shots for a circuit of \(N=500\) gates?

The factor is \(\gamma^{2N}\), and \(\gamma^{2N}=e^{2N\ln\gamma}\approx e^{2N(\gamma-1)}\).
\(1.002^{1000}\approx e^{2}\approx7.4\). Ten times more gates would give \(e^{20}\approx5\times10^8\): the cost is exponential in \(N\).
caution — mitigation does not scale

Mitigation estimates expectation values; it never produces a less noisy quantum state, and its cost grows exponentially with the total error \(\varepsilon N\) of the circuit. It extends what noisy devices can do by a constant factor. It cannot run Shor's algorithm on RSA-2048, which needs billions of gates (Lecture 17). That requires error correction, in which the cost grows only polylogarithmically with the circuit size, as long as the physical error rate is below a threshold (Lectures 21–23).

Between these two regimes sits the current "utility" era. In 2023, IBM researchers (Kim et al., Nature 618, 500) ran the time evolution of a 127-spin Ising model on a 127-qubit device, with up to 60 layers of two-qubit gates (2,880 CNOTs), and used ZNE to obtain expectation values that agreed with exactly solvable cases and that, they argued, were beyond brute-force classical simulation. Within weeks, several groups reproduced the results classically with tensor-network and Pauli-propagation methods, which exploited the specific structure of the problem. Both halves of the story matter: mitigated experiments at the 100-qubit scale really do produce trustworthy numbers, and "beyond classical simulation" claims for them are a moving target. Lecture 24 returns to how to read such claims.

8 — Try it in code

tool — calibration data and transpilation (qiskit 2.5, qiskit-ibm-runtime 0.50)
import numpy as np
from qiskit import QuantumCircuit, transpile
from qiskit_ibm_runtime.fake_provider import FakeFez

backend = FakeFez()                       # a stored calibration snapshot of ibm_fez (156 qubits)
t = backend.target
print("snapshot:", backend.properties().last_update_date.date(), " basis:", sorted(n for n in t.operation_names if n in ("cz", "rz", "sx", "x")))
print(" q    T1(us)  T2(us)  readout   sx error")
for q in range(4):
    p = t.qubit_properties[q]
    print(f"{q:2d} {p.t1*1e6:8.1f} {p.t2*1e6:7.1f}  {t['measure'][(q,)].error:7.4f}  {t['sx'][(q,)].error:9.2e}")
cz = np.array([v.error for v in t["cz"].values()])
print(f"CZ error: median {np.median(cz):.4f}, worst {cz.max():.3f}   CZ time {t['cz'][(0, 1)].duration*1e9:.0f} ns")

# a 5-qubit GHZ circuit written with CNOTs, then compiled for the device
ghz = QuantumCircuit(5); ghz.h(0)
for k in range(4): ghz.cx(0, k + 1)       # all CNOTs from qubit 0: not native to a sparse graph
tq = transpile(ghz, backend, optimization_level=1, seed_transpiler=7)
print("compiled ops:", dict(tq.count_ops()), " depth", tq.depth())
snapshot: 2025-02-26  basis: ['cz', 'rz', 'sx', 'x']
 q    T1(us)  T2(us)  readout   sx error
 0     48.8    42.4   0.0115   7.64e-04
 1    255.7   302.8   0.0117   1.78e-04
 2    274.4   100.0   0.0049   1.98e-04
 3    219.7   215.5   0.0159   2.39e-04
CZ error: median 0.0039, worst 1.000   CZ time 84 ns
compiled ops: {'sx': 19, 'rz': 18, 'cz': 10}  depth 26

FakeFez is a stored snapshot, so this runs offline; with an IBM account, QiskitRuntimeService().backend(name), for any device your account lists, gives the same interface with live numbers. The four CNOTs of the GHZ circuit became 10 CZs: on a graph where no qubit has four neighbours, the extra six are routing. The single-qubit gates come from translating CNOTs and \(H\) into the basis.

tool — readout mitigation by hand, and a noisy simulator from calibration data
import numpy as np
from qiskit import QuantumCircuit, transpile
from qiskit_aer import AerSimulator
from qiskit_ibm_runtime.fake_provider import FakeFez

# readout mitigation by hand for one qubit (Example 19.2) and for a pair (A tensor A)
e0, e1 = 0.02, 0.05                                   # P(read 1 | 0), P(read 0 | 1)
A = np.array([[1 - e0, e1], [e0, 1 - e1]])
print("one qubit:  observed P(1) = 0.30 -> mitigated", np.round(np.linalg.solve(A, [0.70, 0.30])[1], 4))
seen = np.kron(A, A) @ [0.5, 0, 0, 0.5]               # a perfect Bell pair read through noisy detectors
print("Bell pair:  seen", np.round(seen, 4), "-> mitigated", np.round(np.linalg.solve(np.kron(A, A), seen), 4) + 0.0)

# a 3-qubit GHZ state on a noisy simulator built from the FakeFez calibration snapshot
ghz = QuantumCircuit(3); ghz.h(0); ghz.cx(0, 1); ghz.cx(1, 2); ghz.measure_all()
for name, sim in (("ideal", AerSimulator(seed_simulator=19)), ("noisy", AerSimulator.from_backend(FakeFez(), seed_simulator=19))):
    tq = transpile(ghz, sim, optimization_level=1, seed_transpiler=19, initial_layout=[2, 3, 4] if name == "noisy" else None)
    counts = sim.run(tq, shots=4000).result().get_counts()
    good = (counts.get("000", 0) + counts.get("111", 0)) / 4000
    print(f"{name}: P(000 or 111) = {good:.4f}; other outcomes {sorted(k for k in counts if k not in ('000', '111'))}")
one qubit:  observed P(1) = 0.30 -> mitigated 0.3011
Bell pair:  seen [0.4814 0.0335 0.0335 0.4514] -> mitigated [0.5 0.  0.  0.5]
ideal: P(000 or 111) = 1.0000; other outcomes []
noisy: P(000 or 111) = 0.9718; other outcomes ['001', '010', '011', '100', '101', '110']

AerSimulator.from_backend builds a noise model (thermal relaxation from \(T_1\), \(T_2\) and gate times, depolarizing gate errors, readout errors) from the snapshot. The fraction of 000 and 111 is not the GHZ fidelity: a mixture of \(|000\rangle\) and \(|111\rangle\) with no coherence would score 1 as well. Lab 5 measures the coherence too, with parity oscillations, and applies the mitigation of Sections 4 and 5.

9 — Summary, exercises and Lab 5

summary

Next time: quantum key distribution, where noise and eavesdropping look the same. Lab 5 launches today; project ideas are posted with it. HW9 is due at the start of Week 11.

exercises 19
  1. A qubit with \(T_1=100\) μs is measured by a 2 μs readout. What is the probability that \(|1\rangle\) survives the whole readout? Which readout error, \(e_0\) or \(e_1\), does this contribute to?
  2. A qubit has \(T_1=200\) μs and \(T_2=100\) μs. Find \(T_\varphi\). Could a qubit have \(T_1=50\) μs and \(T_2=120\) μs?
  3. With \(e_0=0.01\) and \(e_1=0.03\), the observed frequency of 1 is 0.50. Find the mitigated value.
  4. ZNE gives \(E(1)=0.70\) and \(E(3)=0.49\). Extrapolate linearly and exponentially.
  5. Find the Richardson weights for scale factors \(\lambda=1,2,3\) and the factor by which they multiply the standard deviation (equal \(\sigma\)). Why are \(\lambda=2\) runs harder to make by gate folding?
  6. Repeat Example 19.4 with \(\varepsilon=0.05\) and \(n=40\).
  7. How many CNOTs does a CNOT between the end qubits of a 4-qubit line need after routing? Is there a better choice than moving the control all the way?
  1. \(e^{-2/100}\approx0.980\): about 2% of \(|1\rangle\) states decay during the readout and are read as 0. This contributes to \(e_1=P(\text{read }0\mid1)\), which is why \(e_1\gt e_0\) is typical.
  2. \(1/T_\varphi=1/100-1/400\), so \(T_\varphi\approx133.3\) μs. No: \(T_2\le2T_1=100\) μs.
  3. \((0.50-0.01)/0.96\approx0.510\).
  4. Linear: \(0.70+0.21/2=0.805\). Exponential: \(0.70/\sqrt{0.7}=\sqrt{0.7}\approx0.837\).
  5. \(\ell_1(0)=\frac{(-2)(-3)}{(-1)(-2)}=3\), \(\ell_2(0)=\frac{(-1)(-3)}{(1)(-1)}=-3\), \(\ell_3(0)=\frac{(-1)(-2)}{(2)(1)}=1\); \(\sqrt{9+9+1}=\sqrt{19}\approx4.36\). Folding whole gates gives only odd factors; \(\lambda=2\) needs folding half the gates (partial folding), which assumes all gates are equally noisy.
  6. Coherent: \(\sin^2(1)\approx0.708\) again (the same \(n\varepsilon\)). Twirled: \(p=\sin^2(0.025)\approx6.25\times10^{-4}\), and \(\tfrac12(1-(1-2p)^{40})\approx0.024\).
  7. Two SWAPs plus the CNOT: 7 (Qiskit agrees). Moving both ends toward the middle, SWAP(0,1) and SWAP(3,2) then CNOT(1,2), also uses two SWAPs, but the two SWAPs act on different qubits and can run in parallel: the same count, less depth.
lab 5 — noise and mitigation (launch)

Lab 5 reproduces Lecture 18's channel calculations in code, builds a noise model from calibration data, measures GHZ fidelity against the number of qubits, applies readout mitigation and zero-noise extrapolation, and finishes with a short hardware run. Bring a laptop with the course environment installed. Project ideas for Lab 7 are posted alongside.

Reading and sources

all numbers and figures in these notes are computed in python (verify_L19.py) and follow the page theme