Chapter 11 — Key Takeaways (Simulation and Noise Models)
The simulator page. The noise signature table is the diagnostic skill.
The four methods
| Method | Cost | Practical limit | Use for |
|---|---|---|---|
statevector |
$2^n$ | ~30 qubits | the default; exact |
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 bounded | shallow, 1-D circuits |
extended_stabilizer |
exp. in $T$ count | near-Clifford | approximate |
Measured on a GHZ chain, 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
Density matrix costs the SQUARE — every noise simulation needing one is half as wide.
Density matrix gives what counts cannot
qc.save_density_matrix()
sim = AerSimulator(method="density_matrix", noise_model=noise)
rho = DensityMatrix(sim.run(transpile(qc, sim)).result().data()["density_matrix"])
| depolarizing $p$ | purity | fidelity |
|---|---|---|
| 0.00 | 1.0000 | 1.0000 |
| 0.05 | 0.9269 | 0.9625 |
| 0.10 | 0.8575 | 0.9250 |
| 0.20 | 0.7300 | 0.8500 |
Getting the equivalent from counts requires tomography and exponentially many settings (Ch. 30).
★ Stabilizer: the wall has a hole
Gottesman–Knill: Clifford circuits ($H$, $S$, CNOT, Paulis) are simulable in polynomial time, at any size — track $n$ Pauli generators ($O(n^2)$ bits), never write down the state.
| Follows | Does not follow |
|---|---|
| Clifford circuits give no quantum advantage | that entanglement is not the resource |
| T-count is the currency of resource estimation (Ch. 23) | — a 1000-qubit GHZ state is maximally entangled and easy |
| QEC is simulable (Ch. 25) |
⚠️ The testing trap. Appending $T$ gates before a measurement did not break the stabilizer method —
RemoveDiagonalGatesBeforeMeasuredeleted them first (a diagonal gate before a $Z$ measurement changes nothing observable). OnlyH T H, where $T$ genuinely matters, made it fail.Check that your test case survives to the thing you are testing. Print the transpiled circuit.
method P(0) error (exact = 0.8536)
statevector 0.8563 0.0028
stabilizer FAILED <- correct behavior
extended_stabilizer 0.8318 0.0218 <- APPROXIMATE
matrix_product_state 0.8563 0.0028
MPS: entanglement, not qubit count, is what costs
| n=10 | n=16 | n=20 | n=24 | |
|---|---|---|---|---|
| low entanglement, sv / MPS | 65/46 | 67/46 | 77/49 | 214/49 ms |
| high entanglement, sv / MPS | 67/45 | 81/54 | 125/66 | 1563/85 ms (18×) |
⚠️ Caveat: the "high entanglement" circuit is H + CNOT = Clifford — entangled but structured.
Genuinely hard needs high entanglement AND non-Clifford gates.
The inference is one-way. MPS fast → your circuit is easy (a genuine finding). MPS slow → only that this method struggled. Proving easy needs one algorithm; proving hard needs ruling out all of them.
Hardness needs both:
| low entanglement | high entanglement
Clifford | easy (stabilizer) | easy (stabilizer)
non-Clifford| easy (MPS) | HARD
Noise models from a backend
sim = AerSimulator.from_backend(FakeSherbrooke()) # THE most useful line here
Basis gates, coupling map, and calibrated errors — locally, no queue. Reproduced Chapter 2's Bell error fraction (0.0439) at 0.0447 from a completely different code path.
Limits: static snapshot · independent Markovian errors · no crosstalk correlations · no drift. Order of magnitude right, third decimal wrong.
★★ Noise signatures — two INDEPENDENT axes
$$\text{error fraction} = \frac{n_{01}+n_{10}}{N}, \qquad \text{imbalance} = \frac{n_{00}-n_{11}}{n_{00}+n_{11}}$$
| Channel | Error fraction | Imbalance | Reading |
|---|---|---|---|
| Depolarizing $p{=}0.05$ | 0.0251 ($\approx p/2$) | −0.0005 | impossible outcomes, balanced |
| Readout $p{=}0.05$ | 0.0897 ($\approx 2p$) | −0.0042 | same shape, much larger per $p$ |
| Amplitude damping $\gamma{=}0.15$ | 0.0000 | +0.144 | no impossible outcomes, tilted |
| Thermal, 533 ns | 0.0021 | +0.003 | both, small |
| Thermal, 5000 ns | 0.0225 | +0.024 | both, scaling with duration |
| Phase damping, any $\gamma$ | 0.0000 | +0.0007 | INVISIBLE |
Reading rule: impossible outcomes → depolarizing or readout (a gate-free circuit separates them). Peak imbalance → $T_1$. Both, co-scaling with duration → thermal relaxation.
★ The channel this cannot see
phase damping γ=0.1 / 0.3 / 0.6: {'00': 4099, '11': 4093} -- IDENTICAL, bit for bit
A sixfold difference in decoherence, and the histogram does not move. The computational basis is blind to phase (Ch. 3 §3.5) — a decohered Bell state is Chapter 4's classical impostor and gives identical counts.
Measure in the $X$ basis:
γ = 0.0 → <XX> = +1.0000 γ = 0.3 → <XX> = +0.8396
γ = 0.1 → <XX> = +0.9482 γ = 0.6 → <XX> = +0.6379
Cleanly separated, monotonically, by one extra circuit — Chapter 4's entanglement witness doing its job.
$T_2$ is arguably the most important noise mechanism in quantum computing, and the default measurement cannot see it. A GHZ "fidelity" reported as the fraction of all-zeros/all-ones outcomes scores a fully decohered classical mixture at 100%.
Fifth appearance of this book's most persistent theme: your measurement can only see what it is sensitive to.
Testing in three tiers
| Tier | What it asserts | Cost |
|---|---|---|
| 1. exact, noiseless, seeded | the algorithm is correct | milliseconds |
| 2. sampled, seeded, tolerance | the measurement layer is correct | ~1 s |
| 3. noisy, device model | the circuit is runnable | ~1 s |
Tier 3 catches a design regression — an ansatz change that tripled routing cost (Ch. 10 CS1) — in a second, with no hardware.
Common pitfalls
- Diagnosing from the error fraction alone (misses $T_1$ entirely).
- Reading a clean histogram as a clean state (misses $T_2$ entirely).
- Concluding hardness from MPS being slow.
- Calling a Clifford demonstration a computation.
- Using
density_matrixabove ~15 qubits. - A test whose hard case gets optimized away before it is tested.
Project piece added this chapter
vqelab/tests/test_sim.py — noiseless_energy() (the reference every hardware result is measured
against), noisy_energy(), noise_signature() (the two-axis classifier), and five tests across the
three tiers, all passing.
Without the reference, "the energy was −1.125" is uninterpretable. With it, "12 mHa above the noiseless value" is a statement you can act on.