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)
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.
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.
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}|\)?
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=\) .
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).
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.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.
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.
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:
optimization_level works harder.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?
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.
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?
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.
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.
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.
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\)?
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.
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
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.
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 .
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).
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?
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.
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.
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.
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.
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.
all numbers and figures in these notes are computed in python (verify_L19.py) and follow the page theme