2. The four postulates of quantum mechanics
Why this layer exists
Every chapter after this one is built from four statements. They are the four postulates of quantum mechanics, and they are the whole of what this book takes from physics. There is no wavefunction in a box, no perturbation theory, no hydrogen atom, no “what is a particle.” This is a computation primer, not a physics course, and the four postulates are the line that keeps it one. You take them as four rules for manipulating a vector, a matrix, a set of operators, and a tensor product, and you build a computer out of them.
The reason this chapter comes first is that the circuit model — the gates, the circuits, the interference you exploit in Part III — is not a suggestion. It is the shape those four postulates force. If you understand the postulates, you understand why a quantum computer is built the way it is; if you only learn the circuit model, you have learned a recipe. This chapter is the why. The rest is the how.
What breaks without this chapter is the rest of the book. Chapter 5 treats gates as rotations on the Bloch sphere; that is Postulate II. Chapter 4 treats measurement as collapse; that is Postulate III. Chapter 6 builds entanglement out of the tensor product; that is Postulate IV. Every algorithm in Part III is a circuit, and every circuit is a unitary, and every unitary is Postulate II. Without the four postulates you are memorising a language without grammar.
The four postulates
Postulate I — the state is a vector
The state of a quantum system is a unit vector in a complex Hilbert space. For a single qubit the space is $\mathbb{C}^2$, and the state is
The vector is written in Dirac notation as a ket $|\psi\rangle$, and it is the complete description of the system: everything you can know about the qubit is in this one object. The condition $|a|^2 + |b|^2 = 1$ is not optional — a state must be normalised, a unit vector, because its entries are amplitudes and the squared moduli are probabilities that must sum to one.
The computational basis is two special vectors, $|0\rangle = (1, 0)$ and $|1\rangle = (0, 1)$. Every qubit state is a superposition of these,
which is where the phrase “superposition” comes from. It is not a coin spinning in the air; it is a vector written as a combination of two basis vectors. The word “superposition” is just “linear combination” in the qubit dialect.
In tqp the state is a numpy array of two complex numbers, ZERO and
ONE are the basis, and normalize enforces the unit-vector rule:
def normalize(state: np.ndarray) -> np.ndarray:
"""Return the unit vector parallel to ``state``.
Postulate I requires a state to be a unit vector: <psi|psi> = 1.
"""
norm = np.linalg.norm(state)
if norm == 0:
raise ValueError("cannot normalize the zero vector")
return state / norm
The ValueError on the zero vector is the machine telling you that a state
must exist: you cannot build a probability distribution out of nothing.
Postulate II — evolution is unitary
A closed quantum system evolves by a unitary operator $U$ satisfying
where $U^\dagger$ is the conjugate transpose. If the system is $|\psi\rangle$ before the evolution and $|\psi’\rangle$ after, then
The reason evolution must be unitary is that it has to preserve the normalisation. A unitary preserves the length of every vector, so a normalised state stays normalised; and a unitary is invertible, so the evolution is reversible, which is what you expect of a closed system with no measurement in it. The Schrödinger equation,
is the differential form of this: it generates a unitary $U = e^{-iHt/\hbar}$
from a Hermitian Hamiltonian $H$, and every unitary arises this way. This
book does not use the Schrödinger equation — it is a computation primer,
not a physics course — but the consequence is what matters: every gate
you apply is a unitary, and every unitary is a gate. The gates in
tqp are unitary matrices, and is_unitary checks the defining relation:
def is_unitary(U: np.ndarray, tol: float = 1e-9) -> bool:
"""Whether ``U`` is unitary: U^dagger U = I."""
return np.allclose(dagger(U) @ U, np.eye(U.shape[0]), atol=tol)
This is the one property that separates a quantum gate from an arbitrary matrix, and it is a strong constraint: a gate cannot destroy information, because it can always be undone.
Postulate III — measurement
A measurement is a set of operators ${M_m}$ satisfying the completeness relation
If the state before measurement is $|\psi\rangle$, then the probability of obtaining outcome $m$ is the Born rule,
and the state after the measurement, given that outcome $m$ occurred, is
This is the one postulate you cannot undo. Measurement collapses the state onto the subspace $M_m$ selected by the outcome, and the collapse is irreversible: you cannot recover $|\psi\rangle$ from $|\psi’\rangle$, because many states collapse to the same outcome. This is the single most important fact about measurement, and it shapes everything after it. You build interference before you measure, because once you measure the superposition is gone.
The projective measurement in the computational basis is the special case $M_m = |m\rangle\langle m|$: the probability of outcome $|m\rangle$ is
the squared modulus of the amplitude. In tqp this is probability:
def probability(state: np.ndarray, basis: np.ndarray) -> float:
"""The Born-rule probability of measuring ``basis`` in state ``state``.
P = |<basis|psi>|^2. This is Postulate III: the probability of an
outcome is the squared modulus of its amplitude.
"""
return abs(inner(basis, normalize(state))) ** 2
The abs(...)**2 is the Born rule written in one expression: the inner
product $\langle\text{basis}|\psi\rangle$ is the amplitude, and its squared
modulus is the probability. This is the only place in the book where a
probability comes from, and it is the only place it should.
Postulate IV — composite systems
The state of a composite system is the tensor product of the states of its parts. Two qubits, each in $\mathbb{C}^2$, live in
a four-dimensional space with basis $|00\rangle, |01\rangle, |10\rangle, |11\rangle$. If qubit one is $|\psi\rangle = a|0\rangle + b|1\rangle$ and qubit two is $|\phi\rangle = c|0\rangle + d|1\rangle$, their joint state is the tensor product
The reason the tensor product is a tensor product and not a regular product is that it is the only way to describe a composite system that allows entanglement. Not every vector in $\mathbb{C}^4$ is a tensor product of two qubits; the vectors that are not are entangled, and they are the reason a quantum computer is more than the sum of its qubits. Chapter 6 builds entanglement out of this postulate; here the point is that the dimension of a composite system grows exponentially, $2^n$ for $n$ qubits, and that is the resource a quantum computer exploits.
In tqp the tensor product is kron, and basis builds the computational
basis states of a multi-qubit register:
def basis(n: int, index: int) -> np.ndarray:
"""The computational basis state |index> of n qubits.
``index`` is the integer whose binary expansion gives the bit string.
|00> = [1,0,0,0], |01> = [0,1,0,0], |11> = [0,0,0,1].
"""
dim = 2 ** n
v = np.zeros(dim, dtype=complex)
v[index] = 1.0
return v
A two-qubit register is a vector of four complex numbers; an $n$-qubit register is a vector of $2^n$. This is the exponential state space, and it is the thing every algorithm after this one is trying to use.
The Bloch sphere
A single qubit state $|\psi\rangle = a|0\rangle + b|1\rangle$ has four real parameters — the real and imaginary parts of $a$ and $b$ — reduced to two by normalisation and by the fact that a global phase is unobservable. Those two parameters are the Bloch sphere: every pure qubit state is a point on the surface of the unit sphere in $\mathbb{R}^3$,
where $\theta$ and $\phi$ are the polar and azimuthal angles. $|0\rangle$ is the north pole, $|1\rangle$ the south pole, and $|+\rangle = (|0\rangle + |1\rangle)/\sqrt{2}$ a point on the equator.
The Bloch sphere is the mental model for a single qubit, and it is not a probability distribution: a point on the sphere is a state, not a distribution over outcomes. The coordinates of the point are the expectation values of the three Pauli operators,
and a pure state is on the surface ($x^2 + y^2 + z^2 = 1$) while a mixed state is inside. Chapter 8 builds mixed states; here the point is that the sphere is the geometry a single qubit lives in, and gates are rotations of that sphere.
In tqp from_bloch builds the state from its Bloch coordinates and
bloch returns them:
def from_bloch(theta: float, phi: float) -> np.ndarray:
"""Build the state whose Bloch vector is (theta, phi).
The Bloch sphere maps a qubit state to a point on the unit sphere:
|psi> = cos(theta/2)|0> + e^{i phi} sin(theta/2)|1>
``theta`` is the polar angle from |0> (north pole); ``phi`` the
azimuthal phase. The radius of the sphere is the Bloch vector, not
the probability, so the sphere is not a probability distribution.
"""
half = theta / 2.0
a = np.cos(half)
b = np.exp(1j * phi) * np.sin(half)
return normalize(np.array([a, b], dtype=complex))
def bloch(state: np.ndarray) -> np.ndarray:
"""Return the Bloch vector (x, y, z) of a pure qubit state.
z = <psi|Z|psi>, x = <psi|X|psi>, y = <psi|Y|psi>. A pure state lies
on the surface of the unit sphere; a mixed state lies inside.
"""
s = normalize(state)
z = (np.conj(s) @ gates.Z @ s).real
x = (np.conj(s) @ gates.X @ s).real
y = (np.conj(s) @ gates.Y @ s).real
return np.array([x, y, z])
from_bloch and bloch are inverses: this is the check that the sphere is
the right geometry. bloch(|0\rangle) is $(0, 0, 1)$, the north pole;
bloch(|1\rangle) is $(0, 0, -1)$, the south pole; bloch(|+\rangle) is
$(1, 0, 0)$, on the equator.
The four postulates in one picture
The four postulates are one story:
- a state is a vector (I),
- it evolves by a unitary (II),
- it is read out by a measurement that collapses it (III),
- composite systems are tensor products (IV).
The circuit model is this story with the gates spelled out: a circuit is a unitary (II) built from elementary gates, applied to a state (I), read out by a measurement (III), over a register of qubits that is a tensor product (IV). Everything after this chapter is that story told in more detail.
Exercises
(a) Why must evolution be unitary, and why does that imply it is reversible?
Answer
Evolution must preserve the normalisation of the state, because a normalised state is the only thing the Born rule makes sense for: the probabilities must sum to one, always. The linear maps that preserve the length of every vector are exactly the unitaries, $U^\dagger U = I$. A unitary has an inverse, $U^{-1} = U^\dagger$, so the evolution can always be undone: apply $U^\dagger$ and you recover the original state. That is why a closed quantum system is reversible — there is no measurement, no loss of information, only a rotation of the state.
(b) What is the dimension of the state space of five qubits?
Answer
Each qubit is $\mathbb{C}^2$, and the composite system is the tensor product, so five qubits live in $(\mathbb{C}^2)^{\otimes 5} = \mathbb{C}^{2^5} = \mathbb{C}^{32}$. The dimension is $2^5 = 32$. This is the exponential growth: $n$ qubits need $2^n$ complex amplitudes, which is why a classical computer cannot easily simulate a large quantum one.
(c) Why is the Bloch sphere not a probability distribution?
Answer
A probability distribution over two outcomes is a point on a line segment, parametrised by one number $p \in [0, 1]$. The Bloch sphere is a surface in $\mathbb{R}^3$, parametrised by two numbers $\theta$ and $\phi$, and a point on it is a *state*, not a distribution: the coordinates are the expectation values $\langle X\rangle, \langle Y\rangle, \langle Z\rangle$, not the probabilities of outcomes. The probability of measuring $|0\rangle$ in a state at polar angle $\theta$ is $\cos^2(\theta/2)$, read off from the state, not a coordinate on the sphere. A mixed state — a genuine probability distribution over states — lies *inside* the sphere, on the radius, which is the tell: the distribution is not the sphere itself.
(d) Write the tensor product of $|+\rangle = (|0\rangle + |1\rangle)/\sqrt{2}$ with itself, and show it is a product state.
Answer
$|+\rangle \otimes |+\rangle = \frac{1}{2}(|0\rangle + |1\rangle) \otimes (|0\rangle + |1\rangle) = \frac{1}{2}(|00\rangle + |01\rangle + |10\rangle + |11\rangle)$, the vector $(\tfrac12, \tfrac12, \tfrac12, \tfrac12)$. It is a product state because it factors into a vector from qubit one times a vector from qubit two; it is not entangled. The Bell state $(|00\rangle + |11\rangle)/\sqrt{2}$, by contrast, does not factor, and that is what makes it entangled.
Lab: the four postulates in tqp
The first circuit that runs is chapter 14’s, but this lab runs the four
postulates directly, in tqp, so you can see each one doing its job.
Build labs/ch02/ from the repository root:
mkdir -p labs/ch02
Write a script that does four things, one per postulate:
- Postulate I. Build the state $|+\rangle = (|0\rangle + |1\rangle)/\sqrt{2}$
and check it is a unit vector with
numpy.linalg.norm. - Postulate II. Apply the Hadamard gate to $|0\rangle$ and check the
result is $|+\rangle$, and that the Hadamard is unitary with
is_unitary. - Postulate III. Measure $|+\rangle$ in the computational basis and
check that $p(0) = p(1) = \tfrac12$ with
probability. - Postulate IV. Build the two-qubit state $|+\rangle \otimes |0\rangle$
with
kronand check it has four entries.
Run it:
make lab CH=02
The acceptance test checks that the four postulates each do their job: the state is a unit vector, the Hadamard is unitary, the measurement gives equal probabilities, and the tensor product has four entries.
make test
should be green.
Further reading
The three documents this book keeps open:
- The four postulates of quantum mechanics — state, evolution, measurement, composite systems. The why behind the circuit model.
- The Qiskit textbook: quantum computing fundamentals — the reference derivation of the circuit model, the QFT, and Shor.
- Quantum computation and quantum information (Nielsen and Chuang, 2010) — the standard reference.
And the paper behind the cloud QPU, read in Part III:
- Exponential quantum speedup in simulating molecule dynamics (Aspuru-Guzik et al., 2004) — the canonical GPU-class problem, and the honest answer to “what is a QPU for?”.