Chapter 5 — Key Takeaways (Measurement, Shots, and Statistics)

The page you will consult every time you have to defend a number.

What measurement is

  1. Returns a classical bit — 0 with probability $|\alpha|^2$, 1 with $|\beta|^2$.
  2. Replaces the state with the corresponding basis state, irreversibly.

The second is the one people forget. It is why print(qubit) is impossible and why Chapter 26 exists.

Measurement happens in a basis. The computational basis is a default, not a law. A state can be deterministic in one basis and a fair coin in another.

Bitstrings

   '1 0 1 1'                     multiple registers: '00 1'
    │ │ │ └── qubit 0                               └┬┘ │
    │ │ └──── qubit 1                                b  a   (b declared LAST → leftmost)
    │ └────── qubit 2
    └──────── qubit 3

Rightmost is qubit 0. Last-declared register is leftmost. measure([0,1],[1,0]) is legal and silently bit-reverses everything. Test with asymmetric states — palindromes hide ordering bugs.

★ Sampling error

$$\sigma = \sqrt{\frac{p(1-p)}{N}} \;\le\; \frac{1}{2\sqrt N}, \qquad N \approx \frac{0.96}{\epsilon^2} \ \text{(95\% confidence)}$$

Precision Shots QPU @100 μs
±0.1 97 10 ms
±0.05 385 38 ms
±0.01 9,604 0.96 s
±0.005 38,416 3.8 s
±0.001 960,400 1.6 min
±0.0001 96,040,000 2.7 h

Ten times the precision costs a hundred times the shots — always, on any hardware, forever. This is the statistics of sampling; a perfect fault-tolerant machine faces it too. (Amplitude estimation reaches $1/N$, but needs deep coherent circuits — not available on NISQ.)

Measured, 40 repetitions per point:

shots std of $p$ $1/(2\sqrt N)$
100 0.05877 0.05000
10,000 0.00477 0.00500
100,000 0.00138 0.00158

Counts → probabilities → expectation values

def pauli_expval(counts, pauli):
    """Qubit 0 is RIGHTMOST in both strings. Parity of non-identity positions."""
    total, acc = sum(counts.values()), 0
    for bits, n in counts.items():
        parity = sum(int(b) for b, p in zip(bits, pauli) if p != "I")
        acc += n * (1 if parity % 2 == 0 else -1)
    return acc / total

def expval_stderr(counts, pauli):
    n = sum(counts.values())
    ev = pauli_expval(counts, pauli)
    return math.sqrt(max(0.0, 1 - ev**2) / n)
Estimating Shots needed
full distribution over $n$ qubits grows like $2^n$
one expectation value $O(1/\epsilon^2)$, independent of $n$

That exponential gap is why the Estimator primitive exists. Asking the right question is worth an exponential factor.

Note: $\sigma = \sqrt{(1-\langle P\rangle^2)/N}$, so an observable near $\pm1$ has a tiny error bar and one near 0 has the largest. Budget shots for the terms you expect near zero.

Bell state correlators (measured)

value
$\langle ZZ\rangle$ $+1$
$\langle XX\rangle$ $+1$
$\langle YY\rangle$ $-1$ ← two factors of $i$; a witness assuming $+1$ fails on a perfect Bell state
$\langle ZI\rangle, \langle IZ\rangle, \langle XI\rangle$ exactly 0 ← a single qubit carries no information

Measuring in another basis

Hardware only measures in $Z$. Rotate the state instead.

Basis Insert before measure Why
$Z$ nothing the default
$X$ h $HZH = X$
$Y$ sdg then h $S^\dagger$: $Y \to X$, then $H$: $X \to Z$

Measured (4,096 shots; ±0.008 standard error, so "0.0015" is zero):

state $\langle Z\rangle$ $\langle X\rangle$ $\langle Y\rangle$
$\lvert0\rangle$ +1.000 −0.002 −0.002
$\lvert+\rangle$ −0.002 +1.000 −0.002
$\lvert{+}i\rangle$ −0.002 −0.002 +1.000

Certain in exactly one basis, maximally random in the others. This — rotate, sample, take a parity — is the engine of VQE, and the need for a basis per Pauli term is where VQE's cost lives.

Marginals vs. partial measurement

from qiskit.result import marginal_counts
marginal_counts(counts, indices=[0, 1])       # free classical post-processing
What it does
Marginal Forgets bits you already measured. No quantum operation, no extra shots
Partial measurement Destroys information — collapses entangled partners too

A marginal cannot tell you what a different basis would have shown. One dataset answers one set of questions.

★ Statistical power

$$\chi^2 = \sum_i \frac{(O_i - E_i)^2}{E_i}$$

A genuinely biased circuit ($P(1) = 0.55$) tested against fair:

shots p-value verdict
100 0.549 cannot reject ← the test is blind to a 5-point bias
1,000 0.037 REJECT fair
10,000 <0.001 REJECT fair

A large p-value does not mean your circuit is correct. It means your experiment lacked the power to prove otherwise.

Shots to detect a bias $\delta$: roughly $1/\delta^2$. Compute it before you run. Always report $N$ with a p-value.

Choosing a shot count

  1. What are you estimating — probability, expectation value, or distribution?
  2. What precision does the problem require? (1.6 mHa is chemistry, not preference.)
  3. $N \approx 0.96/\epsilon^2$.
  4. × terms × iterations × 100 μs. Check the budget.
  5. Is that precision smaller than your systematic error? If noise biases you by 5%, precision beyond that is waste — fix the bias instead.
Situation Shots
Quick check 1,024
A number in a plot 4,096–10,000
A number in a paper 10,000+, with an error bar
Inside a VQE loop as few as convergence tolerates
Detecting an effect $\delta$ $\sim 1/\delta^2$, computed in advance

Reporting discipline (Case Study 2)

  • Error bar on every estimate; on a difference, $\sqrt{\sigma_A^2 + \sigma_B^2}$.
  • Interleave and repeat — drift and layout change between runs, and one run of each cannot separate them from the effect.
  • Include the do-nothing baseline.
  • Report cost alongside benefit.
  • Say how many configurations you tried (8 comparisons → 34% chance of a spurious 2σ result).
  • State where the conclusion stops applying: this device, this layout, this calibration window.

Common pitfalls

  • Quoting a fidelity with four significant figures and no uncertainty.
  • Adding shots when the dominant noise is run-to-run drift.
  • Concluding "correct" from a large p-value.
  • Estimating a biased quantity to three decimal places.
  • Assuming $\langle YY\rangle = +1$ for a Bell state.
  • Leaving a debugging measure mid-circuit — it changes the algorithm, silently.

Project piece added this chapter

vqelab/measure.py v0probabilities, pauli_expval, expval_stderr, basis_rotation, shots_for_precision, report.

The error bar is not optional: comparing to $-1.137 \pm 0.0016$ Ha is the entire point of the project, and an expectation value without an uncertainty cannot be compared to a target. Chapter 24's optimizer calls basis_rotation() and pauli_expval() on every iteration.