# Quantum Measurement

```elixir
Mix.install([
  {:qx, "~> 0.8.0", hex: :qx_sim},
  {:kino, "~> 0.12"},
  {:vega_lite, "~> 0.1.11"},
  {:kino_vega_lite, "~> 0.1.11"}
])

alias Qx.Qubit
```

## Learning objectives

By the end of this tutorial you will be able to:

* State the Born rule and predict measurement probabilities from amplitudes, then confirm them with shot counts from `Qx.run/2`
* Explain why measurement is the one irreversible operation in quantum computing, and what collapse does to a superposition
* Account for the gap between ideal probabilities and finite-shot statistics, and watch it close as the shot count grows
* Measure a qubit in the X, Y, and Z bases at circuit level with `Qx.measure_x/3`, `Qx.measure_y/3`, and `Qx.measure_z/3`
* Read a `Qx.draw_counts/2` chart as the experimental shadow of a state vector you can no longer inspect directly

## Introduction

This is the third tutorial in the series, following **Quantum Operations and Gates**. There we built circuits from gates and ran our first one with shots. Every gate we met was unitary: it preserved the norm, rotated the Bloch vector, and could be undone. The whole previous tutorial leaned on that reversibility.

Measurement breaks the pattern. It is the only operation in quantum computing that is not unitary, the only one you cannot undo, and the only way to pull a classical answer out of a qubit. It also destroys the very superposition you spent gates building. That tension, between needing an answer and wrecking the state to get it, is what this tutorial is about.

We work mostly in **circuit mode** here, because measurement is fundamentally about statistics: you run a circuit many times and count outcomes. We drop back into calculation mode (`Qx.Qubit`) whenever it helps to look at a state vector before it collapses.

**Prerequisites:** the first two tutorials in this series. You should be comfortable with state vectors and amplitudes, the X, Y, and Z bases, relative phase, and building a small circuit with `Qx.create_circuit/2`, `Qx.h/2`, and `Qx.run/2`.

Run the helper cell below first; we use it to render the occasional Bloch sphere.

```elixir
# Helper function for rendering Bloch sphere SVGs
defmodule BlochHelper do
  def render(qubit) do
    svg = Qubit.draw_bloch(qubit, format: :svg)
    Kino.Image.new(svg, :svg)
  end
end
```

## The Born rule: amplitudes become probabilities

A qubit's amplitudes $\alpha$ and $\beta$ are not things you can read off a meter. They live in the math. The only numbers a measurement hands you are the *probabilities* of each outcome, and those come from squaring the magnitude of each amplitude. This rule, mapping amplitude to probability, is the **Born rule**, and it is the bridge between the quantum description and the classical bit you get back.

For a single qubit $\ket{\psi} = \alpha\ket{0} + \beta\ket{1}$:

$$
P(0) = |\alpha|^2, \qquad P(1) = |\beta|^2, \qquad |\alpha|^2 + |\beta|^2 = 1
$$

The normalisation condition from the first tutorial is exactly the statement that these probabilities sum to 1. Let's build a deliberately lopsided state and check. An $R_y(\pi/3)$ rotation on $\ket{0}$ produces amplitudes $\cos(\pi/6)$ and $\sin(\pi/6)$, so $P(0) = \cos^2(\pi/6) = 0.75$ and $P(1) = 0.25$.

**Predict first:** out of 1024 shots, roughly how many land on `0`? Work out $1024 \times 0.75$, then run the cell.

```elixir
qc =
  Qx.create_circuit(1, 1)
  |> Qx.ry(0, :math.pi() / 3)
  |> Qx.measure(0, 0)

result = Qx.run(qc, shots: 1024)
Qx.draw_counts(result, title: "ry(π/3) on |0⟩ — 1024 shots")
```

About 768 on `0` and 256 on `1`, give or take sampling noise. The 3:1 split is the Born rule made visible.

The shots introduce randomness. If you want the underlying probabilities themselves, with no sampling noise, run a circuit that has *no* measurement and ask for its distribution directly:

```elixir
# A circuit with no measurement still has a clean probability distribution
Qx.create_circuit(1)
|> Qx.ry(0, :math.pi() / 3)
|> Qx.get_probabilities()
```

There they are: $0.75$ and $0.25$, exact. The simulator can compute these because it holds the full state vector. A real quantum computer cannot; all it can do is sample. That difference is the whole subject of the next two sections.

## Collapse: the state after you look

Here is the part that has no classical parallel. Before measurement, the qubit genuinely is in superposition, both amplitudes nonzero. The instant you measure in the Z-basis, the qubit *becomes* whichever basis state you observed. Measure and get `0`, and the qubit is now exactly $\ket{0}$. The amplitude $\beta$ that was there a moment ago is gone, and so is any phase information the state carried.

$$
\alpha\ket{0} + \beta\ket{1} \;\xrightarrow{\text{measure } 0}\; \ket{0} \quad (\text{prob } |\alpha|^2), \qquad \alpha\ket{0} + \beta\ket{1} \;\xrightarrow{\text{measure } 1}\; \ket{1} \quad (\text{prob } |\beta|^2)
$$

This is why measurement is irreversible. A gate maps the whole state vector to another state vector, so a second gate can map it back. Measurement throws away everything except the single outcome, and no operation can reconstruct what you discarded. Qx encodes this in its design: a circuit without measurement has an inspectable state vector, but once you add a measurement there is no longer a clean state to hand back.

```elixir
# A measurement-free circuit: the state vector is well-defined
Qx.create_circuit(1)
|> Qx.h(0)
|> Qx.get_state()
```

```elixir
# Add a measurement and the state vector is no longer defined.
# Uncomment to see Qx raise Qx.MeasurementError — collapse, enforced by the simulator.

Qx.create_circuit(1, 1)
 |> Qx.h(0)
 |> Qx.measure(0, 0)
 |> Qx.get_state()
```

The lost-information point bites hardest with phase. From the previous tutorials you know $\ket{+}$ and $\ket{-}$ differ only in the sign of their $\ket{1}$ amplitude, yet a Z-basis measurement gives both a 50/50 split. Watch the two states come out identical:

```elixir
# |+⟩ from H, |−⟩ from X then H — both measured in the Z-basis
plus_z = Qx.create_circuit(1, 1) |> Qx.h(0) |> Qx.measure(0, 0)
minus_z = Qx.create_circuit(1, 1) |> Qx.x(0) |> Qx.h(0) |> Qx.measure(0, 0)

Kino.Layout.grid(
  [
    Qx.draw_counts(Qx.run(plus_z, shots: 1024), title: "|+⟩ measured in Z"),
    Qx.draw_counts(Qx.run(minus_z, shots: 1024), title: "|−⟩ measured in Z")
  ],
  columns: 2
)
```

Two different states, one indistinguishable readout. The Z-basis measurement is blind to the phase that separates them, and after it fires that phase is gone for good. We get it back in the last section by measuring somewhere else.

## Shots: statistics, not certainty

A single shot returns one bit. That is all. It cannot tell you a probability, the same way one coin flip cannot tell you the coin is fair. To estimate the probabilities behind a quantum state you run the circuit many times and count, and the counts are themselves random. This is why every chart so far said "roughly" 512 or "about" 768.

The estimate sharpens as you add shots. The expected count for an outcome is $\text{shots} \times P$, and the typical relative error shrinks like $1/\sqrt{\text{shots}}$, so a hundredfold increase in shots buys a tenfold tighter estimate. Watch a fair coin ($\ket{+}$ via Hadamard) settle toward 50/50:

```elixir
coin = Qx.create_circuit(1, 1) |> Qx.h(0) |> Qx.measure(0, 0)

for shots <- [20, 200, 2000, 20000] do
  %{counts: counts} = Qx.run(coin, shots: shots)
  {shots, counts}
end
```

At 20 shots the split can be lopsided, an 11/9 or worse. By 20000 it sits within a fraction of a percent of even. Same circuit, same state, sharper picture. Side by side, the noise at low shot count is obvious:

```elixir
Kino.Layout.grid(
  [
    Qx.draw_counts(Qx.run(coin, shots: 50), title: "50 shots — noisy"),
    Qx.draw_counts(Qx.run(coin, shots: 5000), title: "5000 shots — smooth")
  ],
  columns: 2
)
```

Choosing a shot count is a real decision when you run on hardware: more shots cost more time, and you want just enough to resolve the probabilities you care about.

## Measuring in a different basis

Every measurement so far asked the same question: "is the qubit $\ket{0}$ or $\ket{1}$?" That is the Z-basis, and we saw it cannot tell $\ket{+}$ from $\ket{-}$. The fix is to measure a different question. The X-basis asks "is the qubit $\ket{+}$ or $\ket{-}$?", and in that basis the two states are perfectly distinguishable.

It helps to see why. Here is $\ket{+}$ on the Bloch sphere:

```elixir
BlochHelper.render(Qubit.plus())
```

The vector lies flat on the equator, pointing along the positive X-axis. A Z-basis measurement projects onto the poles ($\ket{0}$ up, $\ket{1}$ down), and the equator sits exactly halfway between them, hence the 50/50 coin. An X-basis measurement projects onto the X-axis itself, where $\ket{+}$ already lives, so the answer is certain.

Qx exposes this at circuit level with `Qx.measure_x/3`, `Qx.measure_y/3`, and `Qx.measure_z/3` (the last is just an alias for the ordinary `Qx.measure/3`). Since $\ket{+}$ is the $+1$ eigenstate of $X$, an X-basis measurement of $\ket{+}$ should return index `0` every single time:

```elixir
plus = fn -> Qx.create_circuit(1, 1) |> Qx.h(0) end

z_version = plus.() |> Qx.measure_z(0, 0)
x_version = plus.() |> Qx.measure_x(0, 0)

Kino.Layout.grid(
  [
    Qx.draw_counts(Qx.run(z_version, shots: 1024), title: "|+⟩ in the Z-basis — a coin"),
    Qx.draw_counts(Qx.run(x_version, shots: 1024), title: "|+⟩ in the X-basis — certain")
  ],
  columns: 2
)
```

The Z-basis chart is a 50/50 coin; the X-basis chart is a single bar at `0`. Same state, and the right question turns guesswork into certainty.

One implementation note worth stating plainly. Qx always samples in the computational basis at the end of a circuit, so `measure_x` is carried out as "apply $H$, then measure in Z" and `measure_y` as "apply $S^\dagger$, then $H$, then measure in Z." The classical bit you read already accounts for this rotation: index `0` means $\ket{+}$ for `measure_x` and $\ket{i}$ for `measure_y`. The outcome is what the tutorial cares about.

**Predict first:** $\ket{-}$ is the $-1$ eigenstate of $X$. Measure it in the X-basis and which index should win? Build $\ket{-}$ with `x(0)` then `h(0)`, then run:

```elixir
Qx.create_circuit(1, 1)
|> Qx.x(0)
|> Qx.h(0)
|> Qx.measure_x(0, 0)
|> Qx.run(shots: 1024)
|> Qx.draw_counts(title: "|−⟩ measured in X — all on index 1")
```

A single bar at `1`. The phase that vanished under Z-basis measurement is fully recovered the moment we measure in the basis that was built to see it.

## Summary

* **The Born rule** turns amplitudes into outcome probabilities: $P(0) = |\alpha|^2$ and $P(1) = |\beta|^2$. Normalisation is the statement that these sum to 1.
* **Measurement is the one non-unitary operation.** It collapses a superposition onto the basis state you observe and discards the rest, which is why it cannot be undone.
* **Shots are samples.** A single shot is one bit; probabilities emerge only from many repetitions, and the estimate tightens like $1/\sqrt{\text{shots}}$.
* **The basis is a choice.** `Qx.measure_x/3`, `Qx.measure_y/3`, and `Qx.measure_z/3` ask different questions of the same qubit, and a phase invisible in one basis is plain in another.

### What's next

In the next tutorial, **Entanglement and Multi-Qubit Systems**, we put two qubits together, build the Bell states, and measure them. That is where collapse stops being a single-qubit curiosity and starts producing correlations that no classical system can reproduce: measure one qubit, and you instantly know the other.
