Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Quantum Gates

A reference for the quantum gates used in qcfront — what they do mathematically and when to use them. For how gates map to physical hardware operations (microwave pulses, lasers, etc.), see GatePhysics.md.

All gates are available in roqoqo as roqoqo::operations::*.

Qubit Basics

A qubit has two basis states: |0⟩ and |1⟩. A general qubit state is α|0⟩ + β|1⟩ where α and β are complex numbers with |α|² + |β|² = 1. |α|² is the probability of measuring 0, |β|² of measuring 1.

The Bloch sphere visualizes a qubit as a point on a unit sphere:

  • |0⟩ is the north pole
  • |1⟩ is the south pole
  • |+⟩ = (|0⟩+|1⟩)/√2 is on the equator

Gates are rotations and reflections on this sphere.

Bloch Sphere

Open bloch.html for an interactive 3D visualization. Drag to rotate, scroll to zoom, apply gates to see how they move the state vector.

  • Z axis: |0⟩ (north) ↔ |1⟩ (south). Rz rotates around this axis.
  • X axis: |+⟩ ↔ |−⟩. Rx rotates around this axis.
  • Y axis: |+i⟩ ↔ |−i⟩. Ry rotates around this axis.
  • Hadamard: reflects through the XZ plane (swaps Z and X axes).

Single-Qubit Gates

Pauli Gates

PauliX (X gate, NOT gate, bit-flip)

Flips the qubit: , . Like a classical NOT gate. On the Bloch sphere: 180° rotation around X.

#![allow(unused)]
fn main() {
circuit += PauliX::new(0); // flip qubit 0
}

PauliY (Y gate)

Flips the qubit and adds a phase: , . 180° rotation around Y axis. Rarely used directly; appears in decompositions.

PauliZ (Z gate, phase-flip)

Doesn't change measurement probabilities — only flips the phase of |1⟩. , . 180° rotation around Z.

Key insight: Z does nothing to basis states individually (they're eigenstates). It matters in superposition: .

Hadamard Gate

Hadamard (H gate)

Creates superposition from a basis state: , .

The most important gate in quantum computing — almost every algorithm starts with H on all qubits. (self-inverse).

#![allow(unused)]
fn main() {
// Create equal superposition over all 3-qubit states
for q in 0..3 {
    circuit += Hadamard::new(q);
}
}

Used in: Grover (initialization), Shor/QPE (counting register), Deutsch-Jozsa, Bernstein-Vazirani, teleportation.

Rotation Gates

RotateX(θ), RotateY(θ), RotateZ(θ)

Rotate the qubit by angle θ around the X, Y, or Z axis of the Bloch sphere. These are the continuous-parameter gates — any single-qubit gate can be decomposed into a sequence of rotations.

changes amplitudes (measurement probabilities). changes only phases (no effect on probabilities). This is why Möttönen state preparation uses for amplitude trees and for phase trees.

How rotations move states on the Bloch sphere

Try these in bloch.html: start from |0⟩ and apply gates.

Key intuition:

  • Ry(θ) changes how much |0⟩ vs |1⟩ — it moves the state between the poles. This controls measurement probabilities. Ry(π/2) takes |0⟩ → |+⟩ → |1⟩ → |−⟩ → |0⟩.
  • Rz(θ) changes the phase between |0⟩ and |1⟩ without changing probabilities. It spins the state around the equator. Rz(π/2) takes |+⟩ → |+i⟩ → |−⟩ → |−i⟩ → |+⟩.
  • Rx(θ) is like Ry but in the Z-Y plane.

This is why Möttönen state preparation uses Ry for amplitudes (setting probabilities) and Rz for phases (setting interference patterns).

Common rotation angles

Angle effect effect
IdentityIdentity
Slight tilt toward equator45° phase rotation
(equal superposition)
(full flip) (like Z)
Back to start (with phase)Back to start (with phase)

Note: is the rotation angle, but the state-vector coefficients use (half-angle). produces .

Special cases:

  • (same as X up to global phase)
#![allow(unused)]
fn main() {
use qoqo_calculator::CalculatorFloat;
// Rotate qubit 0 by π/4 around Y axis: tilt toward equator
circuit += RotateY::new(0, CalculatorFloat::Float(std::f64::consts::PI / 4.0));

// Rotate qubit 1 by π/2 around Z axis: add 90° relative phase
circuit += RotateZ::new(1, CalculatorFloat::Float(std::f64::consts::FRAC_PI_2));
}

Used in: State preparation (Möttönen decomposition uses Ry and Rz trees).

Phase Gates

SGate (√Z, phase gate)

Adds a phase to |1⟩. .

TGate (π/8 gate)

Adds a phase to |1⟩. . Important for universal gate sets and fault-tolerant quantum computing (T gate is the expensive one to implement with error correction).

PhaseShiftGate1(θ)

General phase shift. , , .

Two-Qubit Gates

CNOT (Controlled-NOT, CX)

Flips the target qubit if the control qubit is : . The fundamental entangling gate.

#![allow(unused)]
fn main() {
circuit += CNOT::new(0, 1); // control=0, target=1
}

Bell state creation: then creates . This is the "hello world" of entanglement.

Used in: Everything — Bell states, teleportation, Grover diffusion, QPE controlled unitaries, state preparation (Möttönen decomposition), error correction.

ControlledPauliZ (CZ)

Phase-flips only . Symmetric: . .

#![allow(unused)]
fn main() {
circuit += ControlledPauliZ::new(0, 1);
}

Used in: Grover phase oracle (multi-CZ marks solutions).

SWAP

Exchanges two qubit states: . Built from 3 CNOTs: .

Used in: Shor (controlled modular multiplication swaps work qubits).

Three-Qubit Gates

Toffoli (CCX, CCNOT)

Flips the target only when both controls are . Classical AND gate made reversible. Universal for classical computation.

#![allow(unused)]
fn main() {
// roqoqo convention: first arg is TARGET
circuit += Toffoli::new(2, 0, 1); // target=2, ctrl1=0, ctrl2=1
}

⚠️ roqoqo convention: Toffoli::new(target, control_1, control_2) — the first argument is the target, not a control. This differs from some other frameworks.

Used in: SAT oracle (clause evaluation), modular arithmetic.

ControlledControlledPauliZ (CCZ)

Phase-flips only . Symmetric in all three qubits. .

Used in: Multi-target Grover oracle (marks multiple solutions).

Composite Operations

QFT (Quantum Fourier Transform)

Not a single gate but a built-in roqoqo operation that emits the full QFT circuit (Hadamards + controlled phase rotations + swaps).

#![allow(unused)]
fn main() {
let qubits = vec![0, 1, 2, 3];
circuit += QFT::new(qubits, true, true); // inverse=true, swap=true
}

Used in: Shor/QPE (inverse QFT extracts phase from counting register).

MeasureQubit

Collapses a qubit to |0⟩ or |1⟩ and records the classical result. Irreversible — destroys superposition.

#![allow(unused)]
fn main() {
circuit += MeasureQubit::new(0, "result".to_string(), 0);
//                          qubit  register_name     bit_index
}

PragmaGetStateVector

QuEST-specific: extracts the full state vector without measurement. Deterministic (no collapse). Used for verification/debugging.

#![allow(unused)]
fn main() {
circuit += DefinitionComplex::new("sv".to_string(), dim, true);
circuit += PragmaGetStateVector::new("sv".to_string(), None);
}

Ancilla Qubits

An ancilla (Latin: "servant") is a helper qubit added to a circuit that doesn't hold input or output data. Ancillas serve as scratch space for computations that can't be done directly on the data qubits.

Why ancillas are needed

Quantum gates are reversible — every gate has an inverse. But many useful operations (like AND, OR, multi-controlled gates) are irreversible classically. To make them reversible for a quantum circuit, we store intermediate results in ancilla qubits and uncompute them afterward.

Example: a 5-qubit controlled-Z can't be built from 1- and 2-qubit gates alone. The V-chain decomposition uses 3 ancilla qubits as a "Toffoli ladder" to cascade the AND of controls:

controls: ─●──●─────────────────●──●─
           │  │                 │  │
           ├──┤                 ├──┤
controls: ─●──┼──●──────────●──┼──●─
              │  │          │  │
ancilla₀: ───⊕──●──────────●──⊕─── (back to |0⟩)
              │  │          │  │
ancilla₁: ──────⊕──●────●──⊕────── (back to |0⟩)
                    │    │
ancilla₂: ─────────⊕─CZ─⊕──────── (back to |0⟩)
                      │
target:   ────────────●──────────── (phase flipped)
           forward    ↑   reverse
           pass      gate  pass

The golden rule: clean up after yourself

Ancillas must be returned to |0⟩ after use. If an ancilla is left entangled with the data qubits, subsequent operations (like the diffuser in Grover's algorithm) will act on the wrong subspace, silently producing wrong results.

The standard pattern is compute → use → uncompute:

  1. Compute: fill ancillas with intermediate results
  2. Use: apply the target operation (e.g., phase flip)
  3. Uncompute: run the compute steps in reverse to erase ancillas

Since every quantum gate is its own inverse or has a known inverse, uncomputation is always possible — just replay the gates backward.

Common uses in qcfront

WhereAncilla purposeCount
build_multi_czToffoli V-chain for n-qubit CZmax(0, n−2)
build_multi_cxToffoli V-chain for n-qubit CNOTmax(0, n−2)
CnfOracleClause evaluation + MCZ/MCX scratchc + max(mcx, mcz)
Grover diffuserShares MCZ pattern with oraclemax(0, n−2)

Ancilla vs workspace vs scratch

These terms are used interchangeably in the literature. In qcfront:

  • ancilla = any non-data qubit
  • The Oracle trait's num_ancillas() reports total scratch needed
  • The driver allocates ancillas and passes them via apply()

Gate Universality

Any quantum computation can be built from:

  • — universal gate set (discrete)
  • — universal gate set (continuous)

qcfront's state preparation uses . The algorithms use for clarity.

Quick Reference

GateQubitsroqoqoEffect
X1PauliXBit flip
Y1PauliYBit + phase flip
Z1PauliZPhase flip
H1HadamardCreate superposition
S1SGateπ/2 phase
T1TGateπ/4 phase
Ry(θ)1RotateYY-axis rotation
Rz(θ)1RotateZZ-axis rotation
CNOT2CNOTControlled NOT
CZ2ControlledPauliZControlled phase
SWAP2SWAPExchange qubits
Toffoli3ToffoliDoubly-controlled NOT
CCZ3ControlledControlledPauliZDoubly-controlled phase