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 sxtwo 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 Statevector into 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 v0single_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.