|q⟩ Bad Qubits

intermediate · Programming · Multi-Qubit Registers & State Simulation

Ancilla Qubits

Quantum circuits must be reversible — every gate is a unitary and can be undone. This creates a practical problem: when you need scratch space to hold an intermediate result, how do you get rid of it without disturbing your data? The answer is a technique called uncomputation.

What is an ancilla qubit?

An ancilla (Latin for "helper") is a qubit that starts in a known state, typically 0|0\rangle, is temporarily used to hold an intermediate value, and is then returned to its original state before the end of the computation. A clean ancilla:

If you forget to uncompute, the ancilla stays entangled with the rest of the register. Tracing it out would collapse a superposition — the quantum analogue of a memory leak that corrupts your answer.

A worked example: AND via Toffoli

Suppose you want to flip a target qubit tt only when both q0=1q_0 = 1 and q1=1q_1 = 1. The classical AND of two bits cannot be done with a two-qubit reversible gate alone — reversibility demands as many outputs as inputs. The standard fix is to borrow an ancilla aa initialised to 0|0\rangle and use the Toffoli gate CCXCCX:

CCXq0,q1,a=q0,q1,a(q0q1).CCX\,|q_0,q_1,a\rangle = |q_0,q_1,a \oplus (q_0 \land q_1)\rangle.

After CCX(q0,q1,a)CCX(q_0, q_1, a), the ancilla holds q0q1q_0 \land q_1 while the data qubits are unchanged. You can then use aa as a control for further gates. Once you are done, apply CCX(q0,q1,a)CCX(q_0, q_1, a) again:

CCXq0,q1,q0q1=q0,q1,0.CCX\,|q_0,q_1, q_0 \land q_1\rangle = |q_0, q_1, 0\rangle.

Because xx=0x \oplus x = 0 for any bit xx, the second Toffoli undoes the first and returns the ancilla exactly to 0|0\rangle. This pattern — compute, use, uncompute — is the backbone of every large quantum algorithm that must manage qubit overhead.

Circuit picture

A critical constraint for uncomputation is that the Toffoli's control qubits must be unchanged between the two Toffoli calls. If the "use" step modifies one of those controls, the second Toffoli no longer sees the same inputs and cannot undo the first. To avoid this pitfall the standard pattern uses a dedicated output qubit that is separate from both data qubits.

For a four-qubit register with q0=1q_0 = 1, q1=1q_1 = 1, a=0a = 0 (ancilla), t=0t = 0 (output):

  1. CCX(0,1,2)CCX(0,1,2): ancilla becomes 0(11)=10 \oplus (1 \land 1) = 1. State is 1110|1110\rangle.
  2. CX(2,3)CX(2,3): output tt is flipped (controlled on ancilla =1= 1). State is 1111|1111\rangle.
  3. CCX(0,1,2)CCX(0,1,2): q0q_0 and q1q_1 are still 1, so 11=11 \land 1 = 1 and the ancilla flips back: a=11=0a = 1 \oplus 1 = 0. State is 1101|1101\rangle.

The ancilla is clean (0|0\rangle), q0q_0 and q1q_1 are unchanged, and tt has been flipped exactly when both inputs were 1. Because the "use" step (the CX on line 2) touches only tt — not q0q_0 or q1q_1 — the second Toffoli is a perfect inverse of the first.

The correct order is:

  1. Compute: CCX(q0,q1,a)CCX(q_0, q_1, a) — ancilla now holds q0q1q_0 \land q_1.
  2. Use: CX(a,t)CX(a, t) — this modifies tt (an output qubit, not a Toffoli control).
  3. Uncompute: CCX(q0,q1,a)CCX(q_0, q_1, a) — with unchanged q0q_0 and q1q_1.

Trace through: starting from 1,1,0,0|1,1,0,0\rangle,

The ancilla is clean (0|0\rangle) and the output tt has been set to q0q1=1q_0 \land q_1 = 1, implemented without leaving any garbage.

Try it

Complete the three TODOs: the two Toffoli gates and the intermediate CX. The grader verifies the full statevector of the four-qubit register, so the ancilla (q2) must end in 0|0\rangle and the output (q3) must end in 1|1\rangle.

Run your code to see the quantum state.

Sign in on the full site to ask questions and join the discussion.