The SWAP Test: Estimating Similarity Between Quantum States

The SWAP Test: Estimating Similarity Between Quantum States

Use one ancilla and a controlled-SWAP gate to turn the overlap between two quantum states into a measurable probability. Then build the circuit in Qiskit.

Two quantum programs can prepare different circuits yet end up in almost the same state. You might want to check a state-preparation routine, compare a trial state with a target, or evaluate a quantum kernel. The SWAP test gives a direct way to estimate how much two prepared states overlap, using one extra qubit and a measurement probability.

What quantity does it estimate?

For normalized pure states |ψ⟩ and |φ⟩, their squared overlap is |⟨ψ|φ⟩|². It equals 1 when the states are identical up to a global phase and 0 when they are orthogonal. In quantum information this quantity is often called the fidelity between pure states.

The test needs two separately prepared registers of the same size, one for each state, plus an ancilla initialized to |0⟩. Apply a Hadamard gate to the ancilla, then a controlled-SWAP gate that exchanges the two data registers only when the ancilla is |1⟩. A second Hadamard on the ancilla turns the interference between the two branches into a measurable result.

The probability of measuring 0 on the ancilla is:

P(ancilla = 0) = (1 + |⟨ψ|φ⟩|²) / 2

So repeated shots give an estimate: squared overlap = 2 × measured_fraction_of_zero - 1. With identical states, an ideal circuit returns 0 with certainty. For orthogonal states, 0 and 1 each have probability one half. The circuit does not reveal the full states or the phase of their inner product. It gives one useful comparison number.

A small Qiskit example

This circuit compares |0⟩ with |+⟩ = (|0⟩ + |1⟩) / √2. The first qubit is the ancilla, the second is |0⟩, and the third is prepared as |+⟩. With qiskit-aer installed, the code runs an ideal shot-based simulation.

from qiskit import QuantumCircuit, transpile
from qiskit_aer import AerSimulator

# q0 is the ancilla. q1 starts in |0>, and q2 becomes |+>.
qc = QuantumCircuit(3, 1)
qc.h(0)
qc.h(2)
qc.cswap(0, 1, 2)
qc.h(0)
qc.measure(0, 0)

shots = 4096
backend = AerSimulator()
compiled = transpile(qc, backend)
counts = backend.run(compiled, shots=shots).result().get_counts()
p_zero = counts.get("0", 0) / shots
overlap_squared = 2 * p_zero - 1
print(f"Estimated squared overlap: {overlap_squared:.3f}")

The exact squared overlap of |0⟩ and |+⟩ is 1/2, so the ancilla's probability of 0 is 3/4. Finite shots make the printed estimate wiggle around 0.5. If you change qc.h(2) to qc.x(2), the second state becomes |1⟩, which is orthogonal to |0⟩, and the estimate should move toward zero.

Qiskit's cswap method takes the control qubit first, followed by the two target qubits. For registers with several qubits, apply a controlled-SWAP to each corresponding pair. See IBM's Qiskit CSwapGate reference for the gate convention.

What the number does not say

For mixed states ρ and σ, the same ancilla measurement is related to Tr(ρσ), the trace overlap. That is not generally the same as the usual mixed-state fidelity, so it is important to name the quantity being estimated. The simple pure-state example above avoids that distinction.

A controlled-SWAP is also a costly logical operation on many devices. Hardware may need to decompose it into simpler gates, and noise plus finite sampling can blur the result. The SWAP test is a clean way to turn a comparison into an experiment, but it is not a free shortcut around state preparation, circuit depth, or statistical uncertainty.