Chapter 3 — Key Takeaways (Qubit Manipulation in Code)
The single-qubit reference. Everything in Part IV is built from this page plus the CNOT.
The one idea
State = length-2 complex vector. Gate = 2×2 unitary matrix. Applying a gate = matrix–vector product.
$$|\psi\rangle = \alpha|0\rangle + \beta|1\rangle, \qquad |\alpha|^2 + |\beta|^2 = 1, \qquad P(0) = |\alpha|^2$$
Amplitudes carry more than probabilities, because they have phase — and phases can be negative, so amplitudes can cancel. Cancellation is the whole computational advantage.
The gate table
| Gate | Matrix | Bloch rotation | On $\lvert0\rangle$ | Qiskit |
|---|---|---|---|---|
| X | $\begin{pmatrix}0&1\\1&0\end{pmatrix}$ | 180° about $x$ | $\to\lvert1\rangle$ | qc.x(0) |
| Y | $\begin{pmatrix}0&-i\\i&0\end{pmatrix}$ | 180° about $y$ | $\to i\lvert1\rangle$ | qc.y(0) |
| Z | $\begin{pmatrix}1&0\\0&-1\end{pmatrix}$ | 180° about $z$ | unchanged | qc.z(0) |
| H | $\tfrac1{\sqrt2}\begin{pmatrix}1&1\\1&-1\end{pmatrix}$ | 180° about $x{+}z$ | $\to\lvert+\rangle$ | qc.h(0) |
| S | $\begin{pmatrix}1&0\\0&i\end{pmatrix}$ | 90° about $z$ | unchanged | qc.s(0) |
| T | $\begin{pmatrix}1&0\\0&e^{i\pi/4}\end{pmatrix}$ | 45° about $z$ | unchanged | qc.t(0) |
| $R_x(\theta)$ | $\begin{pmatrix}\cos\frac\theta2 & -i\sin\frac\theta2\\ -i\sin\frac\theta2 & \cos\frac\theta2\end{pmatrix}$ | $\theta$ about $x$ | qc.rx(t, 0) |
|
| $R_y(\theta)$ | $\begin{pmatrix}\cos\frac\theta2 & -\sin\frac\theta2\\ \sin\frac\theta2 & \cos\frac\theta2\end{pmatrix}$ | $\theta$ about $y$ | $P(0)=\cos^2\frac\theta2$ | qc.ry(t, 0) |
| $R_z(\theta)$ | $\begin{pmatrix}e^{-i\theta/2}&0\\0&e^{i\theta/2}\end{pmatrix}$ | $\theta$ about $z$ | unchanged | qc.rz(t, 0) |
| $P(\lambda)$ | $\begin{pmatrix}1&0\\0&e^{i\lambda}\end{pmatrix}$ | $\lambda$ about $z$ | unchanged | qc.p(l, 0) |
$Z = P(\pi)$, $S = P(\pi/2)$, $T = P(\pi/4)$. $T^4 = Z$, $T^8 = I$.
Every $z$-rotation leaves $|0\rangle$ alone — that state is on the axis. Geometry, not a special case.
⚠️ The half angle
$$R_y(\theta)|0\rangle \Rightarrow P(1) = \sin^2\!\tfrac{\theta}{2}, \quad \textbf{not } \sin^2\theta$$
To hit a target $p$: $\theta = 2\arcsin\sqrt{p}$. When a rotation does half or twice what you expected, check this first. A $2\pi$ turn gives $-|\psi\rangle$; you need $4\pi$ to return exactly. This is spin-½ physics, not a convention.
The named states
| State | Circuit from $\lvert0\rangle$ | Amplitudes | Bloch |
|---|---|---|---|
| $\lvert0\rangle$ | — | $(1, 0)$ | $(0,0,+1)$ |
| $\lvert1\rangle$ | x |
$(0, 1)$ | $(0,0,-1)$ |
| $\lvert+\rangle$ | h |
$\tfrac1{\sqrt2}(1, 1)$ | $(+1,0,0)$ |
| $\lvert-\rangle$ | x, h |
$\tfrac1{\sqrt2}(1, -1)$ | $(-1,0,0)$ |
| $\lvert{+}i\rangle$ | h, s |
$\tfrac1{\sqrt2}(1, i)$ | $(0,+1,0)$ |
| $\lvert{-}i\rangle$ | h, sdg |
$\tfrac1{\sqrt2}(1, -i)$ | $(0,-1,0)$ |
All have Bloch radius exactly 1 — pure states live on the surface. Interior points are mixed states and need a density matrix (Ch. 11).
Statevector — your microscope
from qiskit.quantum_info import Statevector
sv = Statevector(qc) # exact simulation, no shots, no noise
sv.data # complex amplitudes
sv.probabilities() # |amplitude|^2
sv.probabilities_dict() # keyed by bitstring
Statevector.from_label("+") # convenience constructor: 0 1 + - r l
sv.equiv(other) # compare UP TO GLOBAL PHASE <- use this
- Exact. No sampling error.
- Impossible on hardware. Debugging only — never in a correctness argument.
- Costs $2^n$ memory. Shrink the instance first (Ch. 26).
★ The interference demonstration
# H H -> {'0': 1024} with certainty
# H Z H -> {'1': 1024} with certainty
Z changes no measurement probability at the moment it acts (both 0.5/0.5) and reverses the final answer completely.
$$H(|{+}\rangle) = \tfrac12[(|0\rangle{+}|1\rangle) + (|0\rangle{-}|1\rangle)] = |0\rangle \qquad H(|{-}\rangle) = \tfrac12[(|0\rangle{+}|1\rangle) - (|0\rangle{-}|1\rangle)] = |1\rangle$$
The $|1\rangle$ terms cancel in one, the $|0\rangle$ terms in the other. Probabilities can only accumulate; amplitudes can annihilate. And $HZH = X$, so the second circuit was an X in disguise.
The pattern: superpose (H) → apply phases (oracle) → interfere (H). That is Deutsch–Jozsa, Bernstein–Vazirani, Grover's diffuser, and — with a QFT for the last step — Shor.
Global vs. relative phase
| Observable? | Compare with | |
|---|---|---|
| Relative phase (between amplitudes) | Yes — it is the whole point | == if you mean it |
| Global phase ($e^{i\phi}$ times everything) | No — by any measurement | .equiv() |
The exception that matters: controlled-$(-I)$ is observable, because the phase applies to only one branch and becomes relative. This is phase kickback, the engine of Ch. 19, 20, 22.
Never delete a global phase from a subcircuit you might later control.
The gate/matrix bridge
from qiskit.quantum_info import Operator
Operator(HGate()).data # gate -> matrix
Operator(qc).data # whole circuit -> matrix
Operator(qc).equiv(Operator(XGate())) # verify an identity in one line
qc.unitary(Operator(m), 0) # matrix -> gate (m must be unitary)
Unitary means $U^\dagger U = I$ — total probability preserved. Hence every gate is reversible; there is no quantum AND (Ch. 19 §19.5).
⚙️ Hardware costs
| Op | Cost on current IBM devices |
|---|---|
rz(θ) |
virtual — a phase-reference shift in the controller. Zero duration, zero error |
sx |
a real pulse, ~57 ns, error ~$3\times10^{-4}$ |
x |
a real pulse |
H decomposes to $R_z(\pi/2)\,\sqrt{X}\,R_z(\pi/2)$ + global phase $\pi/4$ → one real pulse.
An arbitrary single-qubit gate → 3 rz + 2 sx → two pulses, always, regardless of the gate.
Consequences: merge single-qubit gates aggressively (the transpiler does it optimally — do not hand-optimize); measure cost in two-qubit depth; structure circuits so rotations land on $z$.
Common pitfalls
- Using
==where you mean.equiv()— makes correct code look broken. - Forgetting the half angle. (Case Study 1 is entirely this bug.)
- Testing only endpoints: at $p=0$ and $p=1$ the buggy and correct rotations agree.
- Letting
Statevectorinto an algorithm rather than only into debugging. - Believing the Bloch sphere generalizes to many qubits. It does not (Ch. 4 §4.4).
- Testing decomposition code on a special matrix (real orthogonal, diagonal, permutation) and concluding the general path works.
Project piece added this chapter
vqelab/circuits.py v0 — single_qubit_ansatz() using $R_y$ (real matrix, smooth sweep,
differentiable), plus state_of(): amplitudes, probabilities, and Bloch vector in one call, with a
clear error when parameters are unbound. Your microscope for the rest of the book.