> "The simulator is your lab. Hardware is your exam. The gap between them is the syllabus."
Prerequisites
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
Learning Objectives
- Choose an Aer simulation method from a circuit's structure, and predict where each method's scaling gives out.
- Explain why stabilizer and matrix-product-state simulation escape the exponential wall, and what they give up.
- Build a noise model from a real backend and reproduce its error behavior locally.
- Construct noise models by hand from depolarizing, readout, amplitude-damping, and thermal-relaxation channels.
- Predict the qualitative signature each noise channel leaves on a Bell state's counts.
- Use the density-matrix method to obtain fidelity and purity rather than samples.
- Design a simulator-based regression test for a quantum program.
In This Chapter
- Overview
- Learning Paths
- 11.1 The Simulator Family
- 11.2 Statevector: Exact, and Bounded
- 11.3 Density Matrix: For Noise
- 11.4 Stabilizer: The Exponential Wall Has a Hole
- 11.5 Matrix Product States: Bounded Entanglement
- 11.6 Noise Models from a Backend
- 11.7 Building Noise by Hand
- 11.8 The Simulator as a Regression Test
- 11.9 Summary
Chapter 11: Simulation and Noise Models
"The simulator is your lab. Hardware is your exam. The gap between them is the syllabus."
Overview
You have used AerSimulator since Chapter 2 and treated it as one thing. It is not. Aer provides
several genuinely different simulation algorithms, and choosing the right one is the difference
between a circuit that runs in fifty milliseconds and one that does not run at all.
The headline result of this chapter is that the exponential wall of Chapter 1 is not universal. It applies to general circuits simulated by the statevector method. Two other methods escape it in different ways, and this chapter measures both:
- Stabilizer simulation handles Clifford circuits at any size — flat runtime from 5 qubits to 25 and beyond, as Chapter 7 §7.3 previewed with a thousand-qubit GHZ state.
- Matrix product states handle circuits whose entanglement stays bounded, regardless of qubit count. Measured here: at 24 qubits, MPS was 18× faster than statevector on a hard circuit.
Meanwhile the density-matrix method, which you need for noise, hits the wall harder — it failed outright at 20 qubits where statevector was still comfortable.
The chapter's second half is about noise models: reproducing a real device's error behavior on your laptop. You will build one automatically from a backend, and by hand from individual channels — and learn to recognize the distinct fingerprint each channel leaves, because being able to look at a histogram and say "that looks like readout error, not gate error" is a real diagnostic skill.
In this chapter, you will learn to:
- Choose a simulation method from circuit structure, and know where each one stops.
- Explain how stabilizer and MPS escape the exponential wall, and what they give up.
- Build a noise model from a backend, and reproduce its behavior.
- Construct noise by hand: depolarizing, readout, amplitude damping, thermal relaxation.
- Recognize each channel's signature in the counts.
- Use density matrices for fidelity and purity rather than samples.
- Write a simulator regression test.
Learning Paths
How to read this chapter by track. - 🔰 Beginner — §11.1, §11.6, and §11.8. Use
AerSimulator.from_backend()and move on. - 🔬 Researcher — §11.4 and §11.5 decide which of your circuits are classically simulable, which is exactly the question a quantum-advantage claim turns on. §11.7 is how you model your device. - 🤖 Quantum ML — §11.5 (MPS) is directly relevant: shallow variational circuits often have low enough entanglement to simulate classically, which is both useful and a warning. - 🏗️ Quantum Engineer — the whole chapter. §11.9's regression testing is what keeps a quantum codebase honest. - 🔐 Security — §11.4. Which circuits are classically simulable is the core of every "is this really quantum?" question, and Gottesman–Knill is the sharpest tool for answering it.
11.1 The Simulator Family
from qiskit_aer import AerSimulator
print(sorted(AerSimulator().available_methods()))
['automatic', 'density_matrix', 'extended_stabilizer', 'matrix_product_state',
'stabilizer', 'statevector', 'superop', 'unitary']
Chapter 7 §7.3 listed them. Now measure them. Running a GHZ chain at 128 shots:
n=5 n=10 n=15 n=20 n=25
statevector 101 ms 64 ms 66 ms 71 ms 351 ms
density_matrix 37 ms 49 ms 9,148 ms FAILED —
stabilizer 269 ms 332 ms 300 ms 294 ms 297 ms
matrix_product_state 38 ms 43 ms 45 ms 50 ms 52 ms
Four different shapes, and each tells you something.
Statevector is flat until it is not. The small-$n$ numbers are dominated by process startup; the real growth begins around 20 qubits and doubles per qubit thereafter. Chapter 1's wall is at 30–35 qubits on a typical machine.
Density matrix hits the wall much sooner — nine seconds at 15 qubits, and an outright failure at 20. It represents $4^n$ entries rather than $2^n$, so it costs the square. Every noise simulation that needs a density matrix is roughly half as wide as the equivalent pure-state simulation.
Stabilizer is flat. 297 ms at 25 qubits, the same as at 5. It would be flat at 250. This is Gottesman–Knill, and §11.4 explains what it costs you.
MPS is flat too, and fastest of all here — 52 ms at 25 qubits. But its flatness has a different cause and a different failure mode, which §11.5 measures.
Reading the table: constant overhead is not scaling
Every cell in that table is a sum of two things — a fixed cost that does not depend on $n$, and a cost that does — and reading the sum instead of the parts gets both flat rows and both growing rows wrong.
Stabilizer at $n = 5$ took 269 ms — nearly three times statevector's 101 ms. Stop there and you conclude stabilizer is slow. It is not slow; it is flat, which is a different property and a far more valuable one. At five qubits almost the entire measurement is process startup, library load, and transpilation, and those costs are identical for every method in the table.
Subtract the floor and the exponents appear. The statevector row sits at 64–66 ms from $n = 10$ through $n = 15$, which is a fair estimate of its fixed cost. Take that off both ends of the growing region:
statevector, floor of 64 ms removed
n=20 71 - 64 = 7 ms of actual compute
n=25 351 - 64 = 287 ms of actual compute
ratio 287 / 7 = 41x over 5 qubits -> 2.10x per qubit
2.10× per qubit against a predicted 2.00×. That is $2^n$, extracted from a table whose first four columns look flat.
Do the same to the density-matrix row, whose floor sits near 37–40 ms:
density_matrix, floor of 40 ms removed
n=10 49 - 40 = 9 ms
n=15 9,148 - 40 = 9,108 ms
ratio 9,108 / 9 = 1,012x over 5 qubits -> 3.99x per qubit
3.99× per qubit against a predicted 4.00×, and $4^5 = 1{,}024$ against a measured ratio of 1,012 — 1.2% apart. The measured table contains its own complexity proof, in both rows.
📊 What the Numbers Say — the floor is a fitted parameter, and it matters.
Both derivations above depend on where you put the constant, and neither is robust to the third digit. Move the statevector floor from 64 ms to 60 ms and 2.10× becomes 1.93×; to 50 ms and it becomes 1.70×. Move the density-matrix floor from 40 ms to 37 ms and 3.99× becomes 3.77×; to 45 ms and it becomes 4.69×.
The conclusion survives that sensitivity and the precision does not. Every plausible floor puts statevector near 2 and density matrix near 4, which is the claim being made and the claim theory predicts. None of them pins either exponent to two decimal places.
Two points and one free parameter is the smallest arrangement that can produce a slope. It is fine for confirming an exponent you already had a reason to expect. It is not the experiment you would run to establish one.
⚠️ Common Pitfall —
automaticis good, and it is not clairvoyant.The default method inspects your circuit and picks. It correctly recognizes Clifford circuits and routes them to
stabilizer, and it will fall back sensibly when a method fails.What it cannot do is know your intent. If you want a density matrix because you need purity, or MPS because you know your entanglement stays low, say so —
automaticoptimizes for completing the run, not for giving you the object you wanted.And it cannot rescue a genuinely hard circuit. A 30-qubit random circuit is hard for every method;
automaticwill pick the least bad one and still fail.
11.2 Statevector: Exact, and Bounded
The default, and the one you have been using. It holds $2^n$ complex amplitudes and applies each gate as a matrix–vector product.
What it gives you: exactness. No sampling error, no approximation. Statevector(qc) from
Chapter 3 is this method with the shots removed.
What it costs: Chapter 1 §1.4's table. 30 qubits is 16 GiB; 40 is 16 TiB.
When to use it: essentially always, below about 25 qubits, unless you need noise or a specific alternative representation.
The memory arithmetic, and the boundary it sets
Worth doing explicitly, because the number that falls out settles more arguments in this book than any other.
A complex128 amplitude is 16 bytes — two 64-bit floats. An $n$-qubit statevector holds $2^n$ of
them, so the state occupies
$$M(n) = 2^n \times 16 \text{ bytes}$$
with no constant factor to hide behind and no data structure to be clever about. Chapter 1 §1.4 tabulated it; this is the region that decides things:
n amplitudes statevector memory
20 1,048,576 16 MiB
25 33,554,432 512 MiB
30 1,073,741,824 16 GiB
35 34,359,738,368 512 GiB
40 1,099,511,627,776 16 TiB
Every qubit doubles it; five qubits multiply it by 32. That is the entire content of the exponential wall, and it has a consequence that is easy to state and hard to internalize: doubling your machine's memory buys you exactly one more qubit.
Not one more per year, or one more per hardware generation. One more, per doubling, permanently. A 16 GiB laptop reaches 30. A 512 GiB server reaches 35. The largest single-node machines you can rent reach 38 or 39. Every classical memory improvement there will ever be, applied to this problem, moves the boundary by single digits.
What that predicts about the measured table
§11.1's statevector row took 351 ms at 25 qubits, of which roughly 287 ms was compute. Extrapolate at the doubling rate the same table just established:
n=25 287 ms measured
n=28 2.3 s predicted
n=30 9.2 s predicted
n=32 36.7 s predicted
n=35 4.9 min predicted
Those four rows are predictions, not measurements. They assume the doubling continues and that memory bandwidth does not become the binding constraint before compute does. In practice it usually does, so the real curve bends upward somewhere past 30 as the state stops fitting first in cache and then in RAM. Read the table as a floor on the pain, not an estimate of it.
But it locates the thing. Somewhere between 30 and 35 qubits, exact classical simulation stops being something you do while waiting and becomes something you schedule. And the reason that boundary is the most consequential number in this chapter has nothing to do with your patience.
🔬 Honest Assessment — the 30–35 qubit boundary decides advantage arguments in both directions.
Chapter 35 §35.4 states the dilemma in its sharpest form. It belongs here too, because this is the chapter where the boundary is actually measured.
Below the boundary, any quantum result can be checked classically — which means the check is itself a classical algorithm solving the same problem. A method that works there has demonstrated correctness, not advantage.
Above the boundary, no quantum result can be checked classically. A method that works there cannot be verified, only trusted.
There is no regime in which a quantum advantage is both real and directly checkable. That is not a temporary state of engineering waiting on better simulators; it follows from the arithmetic on this page. And it is why Chapter 37 §37.7's question — what does the method produce, not just how does it score? — carries so much weight. An algorithm that emits a certificate, a bound on its own answer, escapes the dilemma. One that emits a bitstring does not.
It is also the right frame for the two escape routes in §11.4 and §11.5. Neither of them moves this boundary by a single qubit. They identify circuits that were never on the far side of it to begin with — which is a much more useful thing to be able to do, and a much less exciting one.
11.3 Density Matrix: For Noise
A pure state is a vector; a mixed state — a statistical mixture, which is what noise produces — is a matrix. Chapter 4 §4.4 used this to detect entanglement; here it is the tool for noise.
from qiskit.quantum_info import DensityMatrix, state_fidelity
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.save_density_matrix()
noise = NoiseModel()
noise.add_all_qubit_quantum_error(depolarizing_error(0.1, 2), ["cx"])
sim = AerSimulator(method="density_matrix", noise_model=noise)
rho = DensityMatrix(sim.run(transpile(qc, sim)).result().data()["density_matrix"])
pure = QuantumCircuit(2); pure.h(0); pure.cx(0, 1)
print(f"purity: {np.real(np.trace(rho.data @ rho.data)):.4f}")
print(f"fidelity: {state_fidelity(rho, Statevector(pure)):.4f}")
purity: 0.8575
fidelity: 0.9250
Two numbers you cannot get from counts.
Purity $\mathrm{Tr}(\rho^2)$ is 1 for a pure state and drops as noise mixes it. 0.8575 says the state is meaningfully mixed — the depolarizing channel has converted some of the coherent state into a classical mixture.
Fidelity against the ideal is 0.925 — a direct, single-number answer to "how close is this to what I wanted." Getting the equivalent from measurement counts requires state tomography and exponentially many settings (Chapter 26 §26.8).
The cost: $4^n$ entries. Practically, about 15 qubits. The measurement above failed outright at 20.
Why a density matrix at $n$ qubits costs a statevector at $2n$
"It costs the square" is the right instinct and it understates the situation. Write both out —
$$\text{statevector: } 2^n \text{ amplitudes} \qquad \text{density matrix: } 2^n \times 2^n = 4^n \text{ entries}$$
— and then notice that $4^n = 2^{2n}$. The density matrix of an $n$-qubit system is exactly the
same size as the statevector of a $2n$-qubit system. Not approximately, not up to a constant: the
same number of complex128 entries, to the byte.
density matrix, n=15 4^15 = 1,073,741,824 entries = 16 GiB
statevector, n=30 2^30 = 1,073,741,824 amplitudes = 16 GiB
density matrix, n=20 4^20 = 1,099,511,627,776 = 16 TiB
statevector, n=40 2^40 = 1,099,511,627,776 = 16 TiB
That identity explains §11.1's measurements exactly. The density-matrix method took 9,148 ms at 15 qubits because it was building a 16 GiB object — the same object a 30-qubit statevector run builds, and 30 is precisely where §11.2 put the statevector wall. It failed outright at 20 because 20 qubits of density matrix is 16 TiB, which is Chapter 1 §1.4's entry for a forty-qubit statevector.
So "roughly half as wide" is not a rule of thumb. It is a restatement of $4^n = 2^{2n}$, and it is exact: whatever qubit count your machine reaches with statevector, halve it, and you have the density-matrix limit to the byte.
The contrast at a single qubit count is the part to remember. At $n = 20$ the statevector is 16 MiB and ran in 71 ms; the density matrix is 16 TiB and did not run at all. A factor of a million in memory, at the same qubit count, on the same circuit — the only difference being that one representation can describe a mixed state and the other cannot.
⚠️ Common Pitfall — reaching for
density_matrixbecause the circuit has noise.Noise does not require a density matrix. Aer simulates noisy circuits perfectly well under the statevector method by sampling trajectories: each shot picks a random branch of each error channel, evolves a pure state through it, and measures. Average over enough shots and you recover the statistics the density matrix would have given you — at $2^n$ memory instead of $4^n$.
AerSimulator.from_backend(...)in §11.6 does exactly that, carrying a 127-qubit noise model, in milliseconds.You need the density matrix when you want the object, not the statistics — purity, fidelity against an ideal state, a partial trace, an entanglement measure. Those are properties of $\rho$ itself, and no number of shots produces them directly.
The price of confusing the two is fifteen qubits of headroom.
Where 0.8575 and 0.9250 come from
Both are exactly predictable, which makes them a check on the code that produced them rather than merely an output of it.
📐 Math Aside — the depolarizing channel's fidelity and purity, in closed form.
Qiskit's
depolarizing_error(p, 2)implements$$\mathcal{E}(\rho) = (1-p)\,\rho + p\,\mathrm{Tr}[\rho]\,\frac{I}{4}$$
— with probability $p$, discard the two-qubit state and replace it with the maximally mixed state. Apply it to the ideal Bell projector $P = |\Phi^+\rangle\langle\Phi^+|$ and write the result as $\rho = aP + bI$ with $a = 1 - p$ and $b = p/4$.
Fidelity against the ideal is $\langle\Phi^+|\rho|\Phi^+\rangle = a + b$, since $\langle\Phi^+|I|\Phi^+\rangle = 1$:
$$F = (1-p) + \frac{p}{4} = 1 - \frac{3p}{4}$$
Purity uses $P^2 = P$, $PI = P$, $\mathrm{Tr}\,P = 1$ and $\mathrm{Tr}\,I = 4$:
$$\rho^2 = a^2 P + 2ab\,P + b^2 I \quad\Longrightarrow\quad > \mathrm{Tr}(\rho^2) = a^2 + 2ab + 4b^2 = (1-p)^2 + \frac{p(1-p)}{2} + \frac{p^2}{4}$$
Against the measured sweep:
text p fidelity: pred / meas purity: pred / meas 0.00 1.0000 / 1.0000 1.0000 / 1.0000 0.05 0.9625 / 0.9625 0.9269 / 0.9269 0.10 0.9250 / 0.9250 0.8575 / 0.8575 0.20 0.8500 / 0.8500 0.7300 / 0.7300Eight predictions, eight matches to four decimal places. They agree in every digit because the density-matrix method has no sampling error at all — it evolves the operator, so there is nothing for a seed to perturb. This is the one place in the book where prediction and measurement are expected to agree exactly, and where a disagreement in the fourth decimal would mean a bug rather than a fluctuation.
The closed form also gives the floor. At $p = 1$ the state is $I/4$ and $\mathrm{Tr}(\rho^2) = 1/4$. Purity bottoms out at $1/d$, not at zero — $2^{-n}$ for $n$ qubits. So "purity near zero" is not a meaningful description of a large mixed state, and purity should always be read against its own floor rather than against 0. At two qubits that floor is 0.25; at ten it is 0.00098, and a purity of 0.001 there would mean completely mixed, not almost mixed.
11.4 Stabilizer: The Exponential Wall Has a Hole
The most surprising method, and the one with the deepest consequences.
Clifford circuits — built only from $H$, $S$, CNOT, and the Paulis — are efficiently simulable classically. Not approximately: exactly, in polynomial time, at any size. This is the Gottesman–Knill theorem, and it is why the stabilizer row above is flat.
Chapter 7 §7.3 measured the extreme case: a 1000-qubit GHZ state, simulated exactly, in about four seconds.
📐 Math Aside — Why Clifford circuits are easy.
The trick is to stop tracking the state and track its symmetries instead.
A stabilizer state is completely specified by the set of Pauli operators that leave it unchanged. The Bell state $\tfrac{1}{\sqrt2}(|00\rangle + |11\rangle)$ is the unique state satisfying $XX|\psi\rangle = |\psi\rangle$ and $ZZ|\psi\rangle = |\psi\rangle$ — you met both of those as $+1$ correlators in Chapter 5 §5.5.
For $n$ qubits you need $n$ such generators, each describable in about $2n$ bits. That is $O(n^2)$ bits total, against $2^n$ amplitudes.
And Clifford gates map Pauli operators to Pauli operators — that is the definition of Clifford. So applying a gate means updating $n$ generators, which is cheap. The state never gets written down.
Adding a single non-Clifford gate, such as $T$, breaks it: $T$ maps a Pauli to something that is not a Pauli, and the description stops being compact. The
extended_stabilizermethod handles a few $T$ gates at exponentially growing cost in their number.🔬 Honest Assessment — What Gottesman–Knill actually means.
This theorem is one of the most useful and most misused results in the field.
What it says: Clifford circuits, however large and however entangled, can be simulated classically in polynomial time.
What follows immediately: a quantum computer running only Clifford gates provides no advantage whatsoever. Anything it computes, your laptop computes.
What does not follow: that entanglement is not the resource. Clifford circuits generate enormous entanglement — a 1000-qubit GHZ state is maximally entangled across every bipartition. Entanglement is necessary for advantage and it is not sufficient.
What the theorem gives you practically: a sharp test. When someone claims a quantum demonstration, ask whether the circuit is Clifford. If it is, the demonstration is a hardware characterization exercise, not a computation — which is often exactly what was intended, and is worth stating.
It is also why T-count rather than gate count is the currency of fault-tolerant resource estimation (Chapter 23): $T$ gates are precisely what makes a circuit classically hard, and in a fault-tolerant architecture they are also precisely what is expensive to implement.
The other direction matters for your daily work: error correction is Clifford, which is why Chapter 25 can simulate real codes on hundreds of qubits on a laptop.
The tableau, sized
Turn the $O(n^2)$ into bytes, because the contrast is the whole theorem.
A stabilizer state on $n$ qubits is fixed by $n$ independent Pauli generators. Each generator needs two bits per qubit — one for its $X$ part, one for its $Z$ part — plus a sign bit. Simulators track the destabilizers alongside, giving a tableau of $2n$ rows of $2n + 1$ bits:
n tableau statevector at the same n
25 2,550 bits = 0.3 KiB 512 MiB
127 64,770 bits = 7.9 KiB 2^127 amplitudes
1,000 4,002,000 bits = 488 KiB 2^1000 amplitudes
Chapter 7 §7.3's thousand-qubit GHZ state fits in 488 KiB. It ran in about four seconds, and the object it built would sit comfortably in a phone's L2 cache. The statevector for the same state has more amplitudes than the observable universe has atoms, by a margin of roughly two hundred orders of magnitude.
That is not a better simulation of the same thing. It is a different question being answered well. The tableau knows every measurement-outcome distribution of that state and will sample from it all day. What it cannot do is hand you an amplitude, because no amplitude is written down anywhere.
The $T$ gate is billed twice, and that is the whole story
Gottesman–Knill says Clifford is easy and $T$ is what breaks it. Fault-tolerant hardware says Clifford is cheap and $T$ is what costs. Those are two independent facts about the same gate, and their coincidence is why $T$-count is the field's unit of account.
Chapter 15 measured the hardware half on Microsoft's resource estimator, and it produced the sharpest single number in Part III:
T gates physical qubits T factories
0 450 0
1 2,882 1
Zero $T$ gates: 450 physical qubits. One $T$ gate: 2,882. A 6.4× jump for a single gate — because a fault-tolerant machine performs Clifford operations directly on the encoded state, while every $T$ must be distilled in a dedicated magic-state factory, and the first factory costs 2,000 qubits whether you use it once or a billion times.
Chapter 15 is careful to note that this is two effects, not one: of the 2,432 added qubits, 2,000 are the factory and 432 are the algorithm register growing to a higher code distance. Both are consequences of the same $T$ gate; only the first is the factory.
Now set the two halves side by side:
the circuit is... classical simulation cost fault-tolerant hardware cost
---------------------------------------------------------------------------------
Clifford only O(n^2) -- a laptop, any n 450 qubits, no factories
+ one T gate the tableau description breaks 2,882 qubits, one factory
+ many T gates exponential in T count factory count, then factory time
The same axis, priced twice. A circuit that is cheap to run on a quantum computer is cheap to simulate on a classical one; a circuit that is expensive to simulate is expensive to run. There is no corner of that table offering an easy quantum implementation of something classically hard — which is a strikingly economical statement of why quantum advantage is difficult, and it falls out of the properties of one gate.
This is the book's "every remedy is denominated in the currency of the disease" in its purest form. The resource you must spend to escape classical simulability is precisely the resource fault tolerance charges most for.
📐 Math Aside — a large $T$ count, read in both currencies.
Chapter 21 §21.6 priced a 20-bit Grover search at 229,944 $T$ gates across 804 iterations — about 286 $T$ gates per iteration. Read that number twice.
As a simulation cost:
extended_stabilizer's runtime grows exponentially in $T$ count. At a $T$ count of one it is already the least accurate method in the table below — 0.0218 error against statevector's 0.0028 of pure sampling error, an order of magnitude worse before the exponential has even started. At 229,944 it is not a slow method, it is a category error. The circuit is classically hard by construction.As a hardware cost: Chapter 15 found that $T$ gates are serialized through the factories, so fault-tolerant runtime grows linearly in $T$ count. 229,944 of them is 229,944 sequential distillation-limited steps, before any routing overhead.
And as an argument for ancillas: Chapter 19 §19.5 measured an 8-input oracle at 26,978 $T$ gates without ancillas, and §19.6 got the same oracle down to 55 with six ancillas — a 491× reduction, bought entirely with space. That one design choice moves the circuit by more than two orders of magnitude on both axes at once: 491× cheaper to build fault-tolerantly, and 491× less of the quantity that makes it classically intractable.
Which is the uncomfortable corollary, and it is worth sitting with. Making a circuit cheaper to run makes it easier to simulate. The ancilla trick that turns 26,978 into 55 also moves the circuit 491× closer to something
extended_stabilizercould attempt. Optimisation is not free of consequences for the advantage argument; it is the advantage argument, run backwards.
A trap in testing this claim
The obvious way to verify "stabilizer cannot handle non-Clifford gates" is to take a GHZ chain, add some $T$ gates, and watch it fail. It does not fail:
T gates | stabilizer | transpiled ops
---------|------------|--------------------------------------------
0 | 318 ms | {'h': 1, 'cx': 13, 'measure': 14}
1 | 312 ms | {'h': 1, 'cx': 13, 'measure': 14}
4 | 341 ms | {'h': 1, 'cx': 13, 'measure': 14}
The $T$ gates are gone from the transpiled circuit.
A $T$ gate is diagonal, and a diagonal gate immediately before a $Z$-basis measurement cannot
change the measurement statistics — it only adds a phase, which the measurement is blind to
(Chapter 3 §3.5). Qiskit's RemoveDiagonalGatesBeforeMeasure pass deletes it, and you saw that pass
listed in the init stage in Chapter 10 §10.4.
The test never presented a non-Clifford circuit. Now try one where $T$ genuinely matters — H,
T, H, which is Chapter 3's interference experiment with a partial rotation, exact
$P(0) = \cos^2(\pi/8) = 0.8536$:
method P(0) error transpiled ops
----------------------------------------------------------------
EXACT 0.8536 -
statevector 0.8563 0.0028 {'u3': 1, 'measure': 1}
stabilizer FAILED QiskitError: contains invalid parameters
extended_stabilizer 0.8318 0.0218 {'h': 2, 't': 1, 'measure': 1}
matrix_product_state 0.8563 0.0028 {'u3': 1, 'measure': 1}
Now it fails, cleanly and with a clear message.
And note extended_stabilizer: it handles the circuit, and its answer is off by 0.0218 — an order of
magnitude more than the sampling error of 0.0028 that the other methods show. It is an
approximate method, a Monte Carlo sampler over stabilizer decompositions whose cost grows
exponentially in the $T$ count. Useful for near-Clifford circuits; not a general escape.
⚠️ Common Pitfall — A test that does not present the hard case proves nothing.
This is worth more than the physics lesson beside it. The first test looked like it exercised non-Clifford simulation. It ran, it passed, and it was measuring nothing — because a compiler pass had silently removed the very gates the test was about.
The same failure mode has now appeared four times in this book, in four costumes: palindromic bitstrings that hide ordering bugs (Ch. 5), symmetric states that hide endianness bugs (Ch. 4), axis-aligned states that hide phase bugs (Ch. 9), and now diagonal gates that get optimized away before they can be tested.
Check that your test case survives to the thing you are testing. Print the transpiled circuit. It takes one line and it is the difference between a test and a ritual.
11.5 Matrix Product States: Bounded Entanglement
The second escape route, and a more subtle one.
A matrix product state represents an $n$-qubit state as a chain of tensors. The size of those tensors is the bond dimension $\chi$, and the memory cost is roughly $O(n\chi^2)$ — linear in qubit count. The catch is that $\chi$ must grow with the entanglement across each cut, and for a maximally entangled state $\chi$ grows exponentially, recovering the wall.
So MPS is not a free lunch. It is a bet that your circuit's entanglement stays bounded.
Measured, comparing statevector against MPS on two circuit families:
LOW entanglement (rotations + a CNOT chain)
n=10: statevector 65 ms MPS 46 ms
n=16: statevector 67 ms MPS 46 ms
n=20: statevector 77 ms MPS 49 ms
n=24: statevector 214 ms MPS 49 ms
HIGH entanglement (H on all, then all-to-all CNOTs)
n=10: statevector 67 ms MPS 45 ms
n=16: statevector 81 ms MPS 54 ms
n=20: statevector 125 ms MPS 66 ms
n=24: statevector 1563 ms MPS 85 ms
MPS wins in both cases, and by 18× at 24 qubits on the harder circuit.
That second result deserves a caveat, and it is the kind of thing that separates a measurement from a conclusion. The "high entanglement" circuit above is built from $H$ and CNOT — which is Clifford. Clifford circuits have a compact stabilizer description, and MPS exploits related structure. So this comparison shows MPS beating statevector on a circuit that is entangled but structured, not on one that is genuinely hard.
A circuit that is hard for MPS needs both high entanglement and non-Clifford gates — random circuits with $T$ gates, for instance, which is exactly what random-circuit-sampling experiments use and exactly why they are hard to simulate.
The entanglement condition, made precise
"Entanglement stays bounded" is doing a great deal of work in that sentence. Here is the exact statement, because it is checkable.
Cut the qubit chain between sites $k$ and $k+1$. Any pure state can be written as a Schmidt decomposition across that cut,
$$|\psi\rangle = \sum_{i=1}^{r} \lambda_i \,|L_i\rangle \otimes |R_i\rangle$$
and the number of nonzero terms $r$ is the Schmidt rank of the cut. An MPS represents the state exactly if and only if its bond dimension $\chi$ is at least the Schmidt rank at every cut. That is the whole condition, and note what does not appear in it: the qubit count.
The link to entanglement is one line. The entanglement entropy across the cut is $S = -\sum_i \lambda_i^2 \log_2 \lambda_i^2$, and with only $r$ terms in the sum,
$$S \le \log_2 r \le \log_2 \chi \qquad\Longleftrightarrow\qquad \chi \ge 2^{S}$$
The bond dimension you need is exponential in the entanglement entropy across the worst cut. Bounded entanglement means bounded $\chi$ means $O(n\chi^2)$ memory, linear in $n$. Entropy that grows with system size — a volume law — means $\chi$ grows exponentially and the wall is back.
Two consequences fall straight out, and both are practical.
A maximally entangled cut needs everything. At the middle of an $n$-qubit chain the Schmidt rank cannot exceed $2^{n/2}$, so $\chi_{\max} = 2^{n/2}$ and MPS memory becomes $O(n \cdot 2^{n})$ — worse than statevector, by a factor of $n$. MPS at maximum bond dimension is statevector with overhead. It never fails to represent the state; it fails to be cheaper than the thing it replaced.
The crossover is computable. MPS stores roughly $2n\chi^2$ complex numbers against statevector's $2^n$, so MPS wins while
$$\chi < \sqrt{\frac{2^{n}}{2n}}$$
At the 24 qubits §11.5 measured, that permits $\chi < 591$ against a theoretical maximum of $2^{12} = 4{,}096$. A seventh of the way to maximal entanglement and the advantage is already gone. At 100 qubits the same inequality permits $\chi$ up to about $8 \times 10^{13}$ — which is why MPS is a hundred-qubit tool and statevector is not, and equally why "MPS handled 100 qubits" says nothing at all until you are told the bond dimension it used.
Ask for the bond dimension. It is the single number separating an MPS result that simulated your circuit from one that simulated a truncated approximation to it.
⚠️ Common Pitfall — a fast MPS run with truncation enabled is not an exact simulation.
Aer exposes
matrix_product_state_max_bond_dimensionandmatrix_product_state_truncation_threshold. Both make MPS faster by discarding small Schmidt coefficients, both are standard and legitimate practice, and both change the method's category: it stops being exact and becomes approximate, in exactly the senseextended_stabilizeris approximate.The measurements in this section used Aer's defaults, which do not truncate. That is why MPS and statevector agreed on 0.8563 for the
H T Hcircuit in §11.4 — digit for digit, including the identical 0.0028 of sampling error, because with no truncation they are computing the same thing.If you turn truncation on, say so, and report the discarded weight. An approximate simulator running under an exact simulator's name is the fastest route to a confidently wrong answer in this chapter.
⚠️ Common Pitfall — "MPS was fast, so my circuit is easy" is a valid inference. The reverse is not.
If MPS simulates your circuit quickly, your circuit has low entanglement or exploitable structure, and that is a genuine finding — it means a classical method can do what your quantum circuit does, which matters enormously for any advantage claim.
But if MPS is slow, that does not prove the circuit is quantum-advantageous. It proves this method struggles. Another method, or a better tensor-network contraction order, may not.
This asymmetry is why classical-simulation results keep narrowing quantum advantage claims, as Chapter 1 §1.5 warned: proving something is easy is much easier than proving it is hard.
11.6 Noise Models from a Backend
The most useful line in the chapter:
from qiskit_aer import AerSimulator
from qiskit_ibm_runtime.fake_provider import FakeSherbrooke
sim = AerSimulator.from_backend(FakeSherbrooke())
That single call builds a simulator carrying the device's basis gates, coupling map, and calibrated error rates — every gate error, every readout error, every $T_1$ and $T_2$ — from the backend's published data.
from qiskit_aer.noise import NoiseModel
nm = NoiseModel.from_backend(FakeSherbrooke())
print(f"noise on: {sorted(nm.noise_instructions)}")
print(f"qubits with noise: {len(nm.noise_qubits)}")
noise on: ['ecr', 'id', 'measure', 'reset', 'sx', 'x']
qubits with noise: 127
Every physical operation, on every qubit. And the result reproduces the hardware behavior you have been seeing since Chapter 2:
Bell state on AerSimulator.from_backend(FakeSherbrooke):
{'00': 1953, '01': 97, '10': 86, '11': 1960}
error fraction: 0.0447
Compare Chapter 2's measurement through the Runtime sampler: 4.39%. The same physics, from two different paths, which is a useful consistency check on both.
🧪 Run It — Build a noise model from your device.
```python from qiskit_ibm_runtime import QiskitRuntimeService from qiskit_aer import AerSimulator
real = QiskitRuntimeService().backend("ibm_something") sim = AerSimulator.from_backend(real) # today's calibration, on your laptop ```
This is the single most useful development practice in this book. You get the device's current error rates, locally, with no queue — so you can iterate on a circuit at hardware-realistic noise and only submit when you know what to expect.
Its limits, which matter: the model is a snapshot, it treats errors as independent and Markovian, and it does not capture crosstalk correlations, drift within a run, or non-Markovian effects. It will get the order of magnitude right and the third decimal place wrong.
Why the model is optimistic, not merely approximate
The box above lists what from_backend leaves out. This is what follows from that list, and it
matters more: the omissions are not symmetric.
omitted mechanism effect on fidelity direction
---------------------------------------------------------------------------
crosstalk (the zz_ terms) adds error worse than model
leakage out of {|0>, |1>} adds error worse than model
non-Markovian memory adds error worse than model
measurement-induced disturbance adds error worse than model
on neighbouring qubits
calibration drift moves error either way both
Four of the five omitted mechanisms can only make the device worse than its model, and the fifth is the only two-sided term. There is no omitted physics that makes real hardware better than the model of it. So the model's fidelity estimate is structurally an upper bound with one noisy exception — which makes "optimistic" the correct word rather than merely "approximate."
The crosstalk term is the one to watch, and Chapter 12 §12.2.4 shows why: the device publishes it.
Every calibration snapshot carries zz_<pair> fields — the always-on residual coupling between
neighbours — and NoiseModel.from_backend does not read them. That is the one field in the
snapshot describing an error your circuit suffers because of what a neighbouring circuit is doing,
which is precisely the error a per-gate, per-qubit, independent-error model has nowhere to put.
Chapter 29 §29.1 supplies the sting: crosstalk is a correlated error, so it does not average down
with shots the way independent error does. And Chapter 30 §30.5 lists it among the things randomized
benchmarking cannot see — while the per-gate error rates that from_backend consumes were measured
by randomized benchmarking. The model omits crosstalk because its own inputs were blind to it.
The comparison above cannot detect that bias
This section measured 0.0447 against Chapter 2's hardware 0.0439 and called it a consistency check. It is one. It is not evidence that the model is unbiased, and the reason is arithmetic.
simulator error fraction 0.0447 (4,096 shots)
Chapter 2, Runtime sampler 0.0439
difference +0.0008
simulator sampling SE alone 0.0032
difference, in standard errors +0.25
A quarter of one standard error, from the simulator's own shot noise, before counting the hardware run's sampling error at all. The smallest bias this comparison could have caught at two standard errors is 0.0065 — 15% of the quantity being measured. A model that systematically understated device error by 10% would have passed this check without a murmur.
And the bias being alleged grows with depth. Crosstalk accumulates over a circuit; non-Markovian dephasing accumulates over a circuit; drift accumulates over a session. A Bell state is two gates deep. This is a measurement taken at the one depth where the effect it would need to detect is smallest — the pattern Part V returns to under the name a measurement that cannot detect the thing being asked about, and it is worth noticing that this chapter walked into it while making a claim it was right about.
🔬 Honest Assessment — what
from_backendis, and is not, evidence of.It is a good model. Chapter 30 §30.4 measured this class of prediction landing within 12% of Chapter 28's measured circuit fidelity at the median. For a one-line call fed public calibration data, that is genuinely impressive.
And 12% is therefore the resolution. Chapter 12 §12.7 draws the consequence that costs people the most time: a 9% disagreement between your simulation and your hardware is not a disagreement. It is inside the model's own error bar, and reading a story into it is this book's most-repeated error in its most seductive costume.
What it supports: "will this circuit produce a usable signal at all?", "did my ansatz change triple its routing cost?", "which of these two layouts is better?" Order-of-magnitude questions and comparative questions.
What it does not support: any claim about a mitigation technique that acts on correlated noise. Chapter 13 §13.6 states it exactly — dynamical decoupling exists to reverse slow, correlated dephasing, and a memoryless model contains nothing for an echo to reverse. On a fake backend DD can only contribute the error of its own added pulses, and that is exactly what Chapter 31 §31.4 measured: the
XXsequence scored $1 - \text{TVD}$ worse by $0.0053 \pm 0.0012$ — a 4.4-standard-error degradation, from a technique that is a routine win on real hardware.The result is correct and the conclusion "DD is useless" would be wrong. The simulator lacks the physics the technique exists to address — and knowing which questions your instrument cannot answer is the same skill as §11.7's phase damping, aimed at a simulator instead of a circuit.
11.7 Building Noise by Hand
Automatic models are for reproducing a device. Hand-built models are for understanding — for asking "what would happen if readout error doubled?" and for isolating one mechanism at a time.
All measurements below: Bell state, 8,192 shots, seed 1234. The ideal is
{'00': 4092, '11': 4100}.
Depolarizing error
With probability $p$, replace the state with something completely random.
from qiskit_aer.noise import NoiseModel, depolarizing_error
nm = NoiseModel()
nm.add_all_qubit_quantum_error(depolarizing_error(0.05, 2), ["cx"])
p=0.01: {'00': 4076, '01': 23, '10': 16, '11': 4077} error 0.0048
p=0.05: {'00': 3991, '01': 108, '10': 98, '11': 3995} error 0.0251
Signature: symmetric. 01 and 10 appear in roughly equal numbers, and the two peaks shrink
equally. Depolarizing noise has no preferred direction — that is what "completely random" means.
The error fraction is about $p/2$, because a depolarizing event lands on a wrong outcome only some of the time.
📐 Math Aside — where $p/2$ comes from, exactly.
Qiskit's
depolarizing_error(p, 2)implements $\mathcal{E}(\rho) = (1-p)\rho + p\,\mathrm{Tr}[\rho]\,I/4$: with probability $p$, the two-qubit state is discarded and replaced by the maximally mixed state.So the measurement sees a mixture of exactly two things:
- with probability $1-p$, the ideal Bell state —
00and11, each $1/2$;- with probability $p$, the maximally mixed state —
00,01,10,11, each $1/4$.The impossible outcomes can only come from the second branch, and they take precisely half of it:
$$P(\texttt{01}) + P(\texttt{10}) = p \times \tfrac{1}{4} + p \times \tfrac{1}{4} = \frac{p}{2}$$
No approximation anywhere; the $\approx$ in the text is sampling error, not modelling error.
text p predicted p/2 measured difference 0.01 0.0050 0.0048 -0.0002 0.05 0.0250 0.0251 +0.0001And the imbalance is predicted to be zero, because the mixed branch feeds
00and11equally — measured $-0.0005$. Both axes, both values of $p$, out of one line of algebra.
Readout error
The measurement misreports, with no effect on the state.
from qiskit_aer.noise import ReadoutError
nm = NoiseModel()
nm.add_all_qubit_readout_error(ReadoutError([[1 - p, p], [p, 1 - p]]))
p=0.02: {'00': 3921, '01': 161, '10': 157, '11': 3953} error 0.0388
p=0.05: {'00': 3713, '01': 366, '10': 369, '11': 3744} error 0.0897
Signature: symmetric, and roughly $2p$ — because either of the two qubits can be misread, and a single misread is enough. Compare Chapter 2's Case Study 2, which derived exactly this.
Note how much more damaging readout error is per unit $p$: at $p = 0.05$, readout gives 9.0% error against depolarizing's 2.5%. This is why readout mitigation is the highest-value single technique in Chapter 13.
📐 Math Aside — and where the $2p$ comes from.
The state is untouched; each qubit's reported bit flips independently with probability $p$. A shot lands in an impossible outcome exactly when one bit flips and the other does not:
$$P(\texttt{01}) + P(\texttt{10}) = 2p(1-p)$$
The $\approx 2p$ in the text is that expression with the $(1-p)$ dropped, which is why the rule of thumb overshoots at larger $p$:
text p 2p 2p(1-p) measured z at 8,192 shots 0.02 0.040 0.0392 0.0388 -0.19 0.05 0.100 0.0950 0.0897 -1.64The $p = 0.05$ row sits 1.6 standard errors below its prediction. That is an ordinary draw and not a discrepancy — but note that with only that row in front of you it would be easy to "discover" that readout error is 5% weaker than theory, from a single seed. A result from one sample is a draw from a distribution, and this book documents seven separate occasions where its own author had to be reminded of that in print.
One more term hides in the algebra. Both bits flipping returns you to a legal outcome —
00is reported as11— so readout error also moves weight into the wrong peak while contributing nothing to the error fraction. At $p = 0.05$ that is $p^2 = 0.0025$ of all shots, silently mislabelled and invisible to the diagnostic. It is small here. It is not small when $p$ is 0.10 and your circuit has ten qubits.
Amplitude damping
Energy loss: $|1\rangle$ decays toward $|0\rangle$. This is $T_1$.
from qiskit_aer.noise import amplitude_damping_error
nm = NoiseModel()
nm.add_all_qubit_quantum_error(amplitude_damping_error(0.15), ["h"])
γ=0.05: {'00': 4293, '11': 3899} error 0.0000 imbalance +0.048
γ=0.15: {'00': 4687, '11': 3505} error 0.0000 imbalance +0.144
γ=0.30: {'00': 5285, '11': 2907} error 0.0000 imbalance +0.291
Signature: asymmetric — and it produces no impossible outcomes at all.
Read both columns. The error fraction is exactly zero: no 01, no 10, ever. What changes is the
balance between the two allowed peaks, and it tilts steadily toward 00 because damping drives
population from 1 toward 0.
This is a much sharper fingerprint than "asymmetric." Depolarizing and readout noise create
impossible outcomes and leave the peaks balanced. Amplitude damping does the exact opposite. If
your Bell histogram has clean 00/11 output but the two peaks are lopsided, you are looking at
$T_1$, not gate error — and no amount of readout mitigation will help.
📐 Math Aside — the imbalance is $\gamma$.
The noise here is attached to
h, and the circuit has exactly one: the Hadamard on qubit 0, before the CNOT. So the damping acts on a single qubit in the state $(|0\rangle + |1\rangle)/\sqrt2$, whose density matrix is $\tfrac12\left(\begin{smallmatrix}1&1\\1&1\end{smallmatrix}\right)$.Amplitude damping has Kraus operators $K_0 = \left(\begin{smallmatrix}1&0\\0&\sqrt{1-\gamma}\end{smallmatrix}\right)$ and $K_1 = \left(\begin{smallmatrix}0&\sqrt{\gamma}\\0&0\end{smallmatrix}\right)$. Applying both:
$$K_0\rho K_0^\dagger + K_1 \rho K_1^\dagger = > \frac{1}{2}\begin{pmatrix} 1+\gamma & \sqrt{1-\gamma} \\ \sqrt{1-\gamma} & 1-\gamma \end{pmatrix}$$
The populations are now $P(0) = (1+\gamma)/2$ and $P(1) = (1-\gamma)/2$. The CNOT that follows is noiseless and copies qubit 0 onto qubit 1, so
00and11inherit those two probabilities exactly and nothing can ever land in01or10. That is the measured error fraction of 0.0000, and it is exact rather than merely small — a structural zero, not a rounded one.The imbalance then takes one step:
$$\frac{n_{00} - n_{11}}{n_{00} + n_{11}} > = \frac{(1+\gamma)/2 - (1-\gamma)/2}{1} = \gamma$$
The imbalance equals the damping parameter. Against the measurements:
text gamma predicted imbalance measured z at 8,192 shots 0.05 0.0500 0.0481 -0.17 0.15 0.1500 0.1443 -0.52 0.30 0.3000 0.2903 -0.88All three land below prediction, and it would be easy to read a systematic 3% shortfall into that. Do not. All three runs share
seed_simulator=1234, so the three deviations are not independent draws, and the largest is under one standard error. Three correlated sub-sigma deviations are one observation, not three.The useful consequence: read the imbalance off a lopsided Bell histogram and you have read $\gamma$, directly, with no fitting. That works here only because the damping sits before the entangling gate — which is the next channel's problem.
Thermal relaxation
The realistic combination: $T_1$ and $T_2$ over a gate of known duration.
from qiskit_aer.noise import thermal_relaxation_error
err = thermal_relaxation_error(t1=200e-6, t2=120e-6, time=533e-9)
nm.add_all_qubit_quantum_error(err.tensor(err), ["cx"])
T1=200 μs, T2=120 μs, gate 533 ns: error 0.0021
Only 0.2% — because 533 ns against a 120 μs coherence time is a very short exposure. This is Chapter 2's Case Study 2 result arriving from the other direction: for a shallow circuit, decoherence is a minor term and readout dominates. It becomes the dominant term for deep circuits, which is what Chapter 29 is about.
📐 Math Aside — both axes of the thermal row, from $T_1$, $T_2$ and $t$.
thermal_relaxation_error(t1, t2, time)decays the excited-state population by$$\gamma = 1 - e^{-t/T_1}$$
and the coherence by $e^{-t/T_2}$. Here the error is tensored onto both qubits and applied after the CNOT, so it acts on the finished Bell state $(|00\rangle + |11\rangle)/\sqrt2$.
The
00half carries no excited population and nothing happens to it. The11half sees each qubit decay independently:
text from |11>, probability 1/2: both survive (1-g)^2 -> stays 11 exactly one 2g(1-g) -> 01 or 10 both decay g^2 -> 00which gives $P_{00} = \tfrac12(1 + \gamma^2)$ and $P_{11} = \tfrac12(1-\gamma)^2$, and therefore
$$\text{error fraction} = \gamma(1-\gamma), \qquad > \text{imbalance} = \frac{\gamma}{1 - \gamma + \gamma^2}$$
At $T_1 = 200\,\mu s$ and $t = 533$ ns, $\gamma = 1 - e^{-0.002665} = 0.002661$. Against the measured duration sweep:
text gate (ns) gamma error: pred / meas imbalance: pred / meas 533 0.002661 0.0027 / 0.0021 0.0027 / 0.0028 2,000 0.009950 0.0099 / 0.0089 0.0100 / 0.0097 5,000 0.024690 0.0241 / 0.0225 0.0253 / 0.0240Six predictions, all within one standard error at 8,192 shots — and, as with amplitude damping, all three error-fraction predictions land slightly high on a shared seed, which is one correlated observation rather than three independent ones.
Now notice what is absent from the derivation. $T_2$ appears nowhere in either formula. The coherence factor $e^{-t/T_2}$ does not move a single count in the computational basis: at $t = 5{,}000$ ns it has already destroyed 4.1% of the off-diagonal terms, and both axes are blind to every bit of it.
So the "thermal" row of the signature table is a $T_1$ measurement wearing a $T_2$ label. That is the subject two subsections down, and this derivation is why it is unavoidable rather than merely unlucky.
The signature table
Measured, all on the same Bell circuit at 8,192 shots. Imbalance is $(n_{00} - n_{11})/(n_{00} + n_{11})$:
| Channel | Error fraction | Imbalance | Diagnostic |
|---|---|---|---|
| Depolarizing $p{=}0.05$ | 0.0251 ($\approx p/2$) | −0.0005 | impossible outcomes, balanced peaks |
| Readout $p{=}0.05$ | 0.0897 ($\approx 2p$) | −0.0042 | same shape, much larger per unit $p$ |
| Amplitude damping $\gamma{=}0.15$ | 0.0000 | +0.144 | no impossible outcomes, tilted peaks |
| Thermal, $T_1{=}200\,\mu s$, 533 ns | 0.0021 | +0.003 | both, small — shallow circuit |
| Thermal, $T_1{=}200\,\mu s$, 5000 ns | 0.0225 | +0.024 | both grow with exposure time |
The two axes are independent, and that is what makes this diagnostic. Impossible outcomes mean depolarizing or readout error. Peak imbalance means $T_1$. Seeing both means thermal relaxation over a long circuit.
The channel this diagnostic cannot see
One more, and it is the most important entry in the table:
phase damping γ=0.1: {'00': 4099, '11': 4093} error 0.0000 imbalance +0.0007
phase damping γ=0.3: {'00': 4099, '11': 4093} error 0.0000 imbalance +0.0007
phase damping γ=0.6: {'00': 4099, '11': 4093} error 0.0000 imbalance +0.0007
Phase damping is completely invisible — and identically so at every strength. A sixfold difference in decoherence produced bit-for-bit identical counts. The diagnostic reports "clean" on a state that has been badly damaged.
Measure the same three runs in the $X$ basis and they separate cleanly:
γ = 0.0: <XX> = +1.0000
γ = 0.1: <XX> = +0.9482
γ = 0.3: <XX> = +0.8396
γ = 0.6: <XX> = +0.6379
The reason is the book's oldest theme, arriving for the fifth time: phase damping destroys
coherence without moving population, and a computational-basis measurement is blind to phase
(Chapter 3 §3.5). A Bell state whose coherence has been destroyed still gives 50% 00 and 50% 11 —
it has simply become a classical mixture of the two rather than a superposition, which is exactly
Chapter 4's impostor.
⚠️ Common Pitfall — A clean-looking histogram is not a clean state.
Phase damping — $T_2$ decoherence — is the mechanism that destroys the usefulness of a quantum state while leaving its computational-basis statistics untouched. It is arguably the most important noise channel in quantum computing, and it does not appear in the diagnostic above at all.
To see it you must measure in another basis. Add
hto both qubits before measuring, and the Bell state's $\langle XX\rangle$ correlator collapses from $+1$ toward $0$ as coherence is lost — which is precisely Chapter 4's Case Study 2 entanglement witness, doing exactly the job it was built for.This is the same lesson as Chapter 4 (entanglement), Chapter 5 (statistical power), Chapter 9 (teleportation), and Chapter 11 §11.4 (the vanishing $T$ gates), in a fifth costume: your measurement can only see what it is sensitive to, and the computational basis is blind to phase.
Learn this table. Being able to look at a histogram and say "that tilt is $T_1$, not gate error" turns a shrug into a diagnosis, and it is exactly the skill Chapter 12 §12.7 formalizes.
When a noise model is worth building at all
Everything in this section costs something — your time to build it, and the simulator's time to run it. Most of the time the honest answer is don't.
Build nothing. The default, and the right one more often than people expect. A noiseless
statevector run answers "is my algorithm correct?", which is the question you actually have most of
the time, and it answers it in milliseconds with no parameters to get wrong. Chapter 7's
reference_value() is exactly this, and §11.8 turns it into a test.
Use from_backend. One line, no parameters, and it answers "will this circuit produce a usable
signal on this device?" to within Chapter 30's 12%. Run it before every hardware submission; there is
no argument for skipping it. Chapter 39 measured local simulation of its hardware jobs at 22–74
ms, against a queue that made the same work 43,340× longer in wall clock than in QPU time.
Build by hand when you have a why question. "What would happen if readout error doubled?" "Is this circuit limited by $T_1$ or by gate error?" "How deep can I go before decoherence dominates?" Those are questions about mechanisms, and only a mechanism model answers them. The four channels above, applied one at a time, are the whole toolkit.
Do not build one to validate a mitigation technique. This is the trap, and it is subtle enough to have caught serious people.
⚠️ Common Pitfall — a mitigation method tested against a noise model you wrote is being tested against its own assumptions.
Zero-noise extrapolation assumes error grows predictably with circuit depth. Build a depolarizing noise model — which grows predictably with circuit depth — and ZNE will work beautifully. You have learned that your model is depolarizing.
Readout mitigation assumes readout error is a fixed stochastic matrix. Build a
ReadoutErrormodel — which is a fixed stochastic matrix — and mitigation will recover the ideal counts almost exactly. You have learned that you inverted a matrix correctly.The circularity is total, and it is invisible from the inside, because the simulation does improve and the improvement is real. Real about the model.
Chapter 13 §13.6 hit the opposite face of the same problem: dynamical decoupling exists to reverse correlated, slowly-varying dephasing, and a Markovian model has no correlations to reverse. On a fake backend DD could only contribute the error of its own pulses — and Chapter 31 §31.4 measured exactly that, a 4.4-standard-error degradation from a technique that is a routine win on real hardware.
A noise model can tell you a technique is broken. It cannot tell you a technique works. That asymmetry is the same one §11.5 found for MPS, with the same cause: a negative result rules something out, while a positive result only confirms what you assumed going in.
💰 Cost and Queue — the case for simulating first, priced.
Chapter 39 measured a Bell circuit at 4,096 shots as 6.93 ms of QPU time, and the same jobs locally at 22–74 ms. On that comparison the quantum computer wins by 3–10×, and the comparison is worthless, because it prices only the interval during which the device is running.
Include the queue and the ratio inverts by four orders of magnitude. Chapter 39 measured 2.31 × 10⁻⁵ utilization at a five-minute queue — 43,340× more wall clock than QPU time, or 99.99769% of your day spent waiting. And Chapter 39 §39.5 billed the same VQE run at $50 per-minute, $7,432 per-shot, or $185,542 on a trapped-ion machine, depending only on which pricing model applied.
A local noisy simulation costs 74 ms and zero dollars, and Chapter 30 says it is right to within 12% about what you would have seen. Every iteration you spend on the simulator instead of the queue is a five-minute wait and a metered minute you did not spend.
Which is the argument of the whole chapter: the simulator is not a lesser hardware. It is the instrument you use to decide what is worth putting on hardware.
11.8 The Simulator as a Regression Test
The practical payoff, and the reason Part V exists.
Every circuit should have a noiseless reference. Chapter 7's checkpoint already built one:
reference_value(), computed with StatevectorEstimator on the untranspiled circuit. It catches the
layout trap, and it catches a great deal else.
Three tiers of test, in increasing cost:
Tier 1 — exact, noiseless, seeded. Fast, deterministic, and the right default for CI. Asserts the algorithm is correct.
def test_bell_is_correct():
sv = Statevector(bell_circuit(measure=False))
assert sv.equiv(Statevector.from_label("00").evolve(...)) # or compare to known
Tier 2 — sampled, seeded, with a statistical tolerance. Catches errors in the measurement and post-processing layers, and Chapter 5 §5.8's power analysis tells you the shot count.
Tier 3 — noisy, against a device model. Asserts the circuit is not merely correct but runnable:
def test_bell_survives_device_noise():
sim = AerSimulator.from_backend(FakeSherbrooke())
counts = sim.run(transpile(bell_circuit(), sim, seed_transpiler=42),
shots=4096, seed_simulator=1234).result().get_counts()
error = (counts.get("01", 0) + counts.get("10", 0)) / 4096
assert error < 0.10, f"error fraction {error:.3f} exceeds budget"
That third test is the one that catches a regression in circuit design — an ansatz change that quietly tripled the routing cost, for instance (Chapter 10's Case Study 1). It runs in a second, it needs no hardware, and it fails loudly.
🧱 Project Checkpoint —
tests/test_sim.py: the noiseless reference.The project gets its first real test file, and the thing it establishes will be compared against for the rest of the book.
python def noiseless_energy(ansatz, hamiltonian, parameters): """The exact energy, with no noise and no sampling. The number everything else is measured against.""" bound = ansatz.assign_parameters(parameters) return float(StatevectorEstimator().run([(bound, hamiltonian)]).result()[0].data.evs)Plus three tests at the three tiers above, and one more that matters:
test_noise_model_matches_reference()runs the same circuit throughAerSimulator.from_backend()and asserts the result is within a stated tolerance of the noiseless reference. If it drifts outside, either the ansatz got more expensive (Chapter 10's failure mode) or the device model changed — and both are things you want to be told about.This is the file that makes every later hardware result interpretable, because "the mitigated hardware energy was 12 mHa above the noiseless reference" is a statement you can only make if you have the reference.
11.9 Summary
Aer is several simulation algorithms, and choosing among them matters:
| Method | Cost | Practical limit | Use for |
|---|---|---|---|
statevector |
$2^n$ | ~30 qubits | the default |
density_matrix |
$4^n$ | ~15 qubits | noise, purity, fidelity |
stabilizer |
$O(n^2)$ | thousands | Clifford only — QEC, benchmarking |
matrix_product_state |
$O(n\chi^2)$ | hundreds, if entanglement stays low | shallow and 1-D circuits |
Measured on a GHZ chain: at 25 qubits, statevector took 351 ms, stabilizer 297 ms, MPS 52 ms — and density matrix failed outright at 20 qubits, because $4^n$ costs the square.
Chapter 1's exponential wall is not universal. It applies to general circuits under statevector simulation. Stabilizer escapes it for Clifford circuits by tracking $n$ Pauli generators ($O(n^2)$ bits) instead of $2^n$ amplitudes — the Gottesman–Knill theorem. MPS escapes it for circuits with bounded entanglement, at cost $O(n\chi^2)$ in the bond dimension.
Neither escape is free. A Clifford circuit provides no quantum advantage — anything simulable that easily can just be simulated, which is why T-count is the currency of fault-tolerant resource estimation. And "MPS was fast" proves your circuit is easy, while "MPS was slow" proves nothing about hardness — an asymmetry that keeps narrowing advantage claims.
Verifying the Clifford boundary contained a trap worth remembering. Adding $T$ gates before a
measurement did not break the stabilizer method, because RemoveDiagonalGatesBeforeMeasure deleted
them first — a diagonal gate before a $Z$ measurement changes nothing observable. Only a circuit
where $T$ genuinely matters (H, T, H) made it fail. Check that your test case survives to the
thing you are testing; print the transpiled circuit. This is the fourth costume this same failure
has worn in this book.
AerSimulator.from_backend(backend) is the single most useful development practice here: the
device's real basis gates, coupling map, and calibrated errors, locally, with no queue. It reproduced
Chapter 2's Bell error fraction to within a few tenths of a percent from a completely different code
path. Its limits: a static snapshot, independent Markovian errors, no crosstalk correlations or
drift.
Hand-built noise isolates mechanisms, and each leaves a distinct signature along two independent axes — impossible outcomes, and peak imbalance:
| Channel | Error fraction | Imbalance |
|---|---|---|
| Depolarizing $p{=}0.05$ | 0.0251 ($\approx p/2$) | −0.0005 |
| Readout $p{=}0.05$ | 0.0897 ($\approx 2p$) | −0.0042 |
| Amplitude damping $\gamma{=}0.15$ | 0.0000 | +0.144 |
| Thermal, 533 ns gate | 0.0021 | +0.003 |
Readout at $p = 0.05$ gave 9.0% error against depolarizing's 2.5% — which is why readout mitigation is the highest-value technique in Chapter 13. And amplitude damping produced no impossible outcomes at all while tilting the peaks by 14%: impossible outcomes mean depolarizing or readout; peak imbalance means $T_1$.
And phase damping is invisible to both axes — error 0.0000 and imbalance 0.0007 at any strength, because it destroys coherence without moving population and the computational basis is blind to phase. A Bell state with its coherence gone still reads 50/50; it has merely become the classical mixture that was Chapter 4's impostor. To see $T_2$ you must measure in another basis — which is exactly what Chapter 4's entanglement witness does.
Test in three tiers: exact and noiseless for correctness, sampled and seeded for the measurement layer, and noisy against a device model for runnability — the tier that catches a design regression like a tripled routing cost.
Next: Chapter 12 — backends, calibration data, job management, and the decision procedure for the question this whole part has been building toward: is this noise, or is this a bug?