Skip to content

Quantum Gates & Circuits

Category: Quantum Computing
Difficulty: Intermediate
Time Complexity: O(2^n * g)
Space Complexity: O(2^n)

Quantum gates are unitary operators that transform qubit states. Just as classical logic gates (AND, OR, NOT) manipulate bits, quantum gates manipulate qubits — but with the full power of superposition and entanglement. Each gate corresponds to a unitary matrix U satisfying U†U = I, which guarantees that probabilities are preserved. A quantum circuit composes gates sequentially: the state vector |psi> is updated by matrix multiplication at each step. Single-qubit gates (H, X, Y, Z, S, T) act on individual qubits, while multi-qubit gates (CNOT, CZ, SWAP) create correlations between qubits, including entanglement. This visualization lets you build a circuit gate by gate, observe how the full 2^n-dimensional state vector evolves, and see measurement probabilities update in real time.

{
"numQubits": 2,
"gates": [
{
"gate": "H",
"qubits": [
0
]
},
{
"gate": "CNOT",
"qubits": [
0,
1
]
},
{
"gate": "X",
"qubits": [
1
]
},
{
"gate": "H",
"qubits": [
0
]
},
{
"gate": "Z",
"qubits": [
1
]
}
]
}
{
"numQubits": 2,
"gates": [
{
"gate": "H",
"qubits": [
0
]
},
{
"gate": "CNOT",
"qubits": [
0,
1
]
}
]
}
{
"numQubits": 3,
"gates": [
{
"gate": "H",
"qubits": [
0
]
},
{
"gate": "CNOT",
"qubits": [
0,
1
]
},
{
"gate": "CNOT",
"qubits": [
0,
2
]
}
]
}
{
"numQubits": 1,
"gates": [
{
"gate": "H",
"qubits": [
0
]
},
{
"gate": "T",
"qubits": [
0
]
},
{
"gate": "H",
"qubits": [
0
]
},
{
"gate": "T",
"qubits": [
0
]
},
{
"gate": "H",
"qubits": [
0
]
}
]
}
{
"numQubits": 3,
"gates": [
{
"gate": "H",
"qubits": [
1
]
},
{
"gate": "CNOT",
"qubits": [
1,
2
]
},
{
"gate": "CNOT",
"qubits": [
0,
1
]
},
{
"gate": "H",
"qubits": [
0
]
}
]
}
{
"numQubits": 2,
"gates": [
{
"gate": "X",
"qubits": [
0
]
},
{
"gate": "CNOT",
"qubits": [
0,
1
]
},
{
"gate": "CNOT",
"qubits": [
1,
0
]
},
{
"gate": "CNOT",
"qubits": [
0,
1
]
}
]
}
{
"numQubits": 2,
"gates": [
{
"gate": "X",
"qubits": [
1
]
},
{
"gate": "H",
"qubits": [
0
]
},
{
"gate": "CNOT",
"qubits": [
0,
1
]
},
{
"gate": "H",
"qubits": [
0
]
}
]
}
function applyQuantumCircuit(numQubits, gates):
// 1. Initialize state vector to |0...0>
stateVector = [0] * 2^numQubits
stateVector[0] = 1 // all amplitude on |00...0>
// 2. Apply each gate sequentially
for each gate in gates:
if gate is single-qubit:
U = gateMatrix(gate.name, gate.angle)
for each pair of amplitudes separated by 2^target:
[a, b] = [stateVector[i], stateVector[j]]
stateVector[i] = U[0][0]*a + U[0][1]*b
stateVector[j] = U[1][0]*a + U[1][1]*b
if gate is two-qubit (e.g., CNOT):
U = gateMatrix4x4(gate.name)
for each group of 4 amplitudes:
apply 4x4 unitary to the subspace
// 3. Verify normalization
assert sum(|stateVector[k]|^2) == 1
// 4. Compute measurement probabilities
probabilities[k] = |stateVector[k]|^2 for each k
return stateVector, probabilities
import numpy as np
# Standard gate matrices
H = np.array([[1, 1], [1, -1]]) / np.sqrt(2)
X = np.array([[0, 1], [1, 0]])
Y = np.array([[0, -1j], [1j, 0]])
Z = np.array([[1, 0], [0, -1]])
S = np.array([[1, 0], [0, 1j]])
T = np.array([[1, 0], [0, np.exp(1j * np.pi / 4)]])
CNOT = np.array([[1,0,0,0],[0,1,0,0],[0,0,0,1],[0,0,1,0]])
def apply_single_qubit_gate(state, gate, target, n_qubits):
"""Apply a 2x2 gate to target qubit in an n-qubit state."""
n = len(state)
result = state.copy()
step = 1 << target
for i in range(n):
if i & step == 0:
j = i | step
a, b = state[i], state[j]
result[i] = gate[0,0]*a + gate[0,1]*b
result[j] = gate[1,0]*a + gate[1,1]*b
return result
def apply_cnot(state, control, target, n_qubits):
"""Apply CNOT: flip target when control is |1>."""
result = state.copy()
for i in range(len(state)):
if (i >> control) & 1: # control is |1>
j = i ^ (1 << target) # flip target
result[i], result[j] = state[j], state[i]
return result
def run_circuit(n_qubits, gates):
state = np.zeros(2**n_qubits, dtype=complex)
state[0] = 1.0 # |00...0>
for g in gates:
if g['gate'] in ('H','X','Y','Z','S','T'):
mat = {'H':H,'X':X,'Y':Y,'Z':Z,'S':S,'T':T}[g['gate']]
state = apply_single_qubit_gate(state, mat, g['qubits'][0], n_qubits)
elif g['gate'] == 'CNOT':
state = apply_cnot(state, g['qubits'][0], g['qubits'][1], n_qubits)
probs = np.abs(state)**2
assert abs(sum(probs) - 1.0) < 1e-9
return state, probs
// Standard gate matrices (row-major, complex as [re, im])
const H = [[[0.7071,0],[0.7071,0]],[[0.7071,0],[-0.7071,0]]];
const X = [[[0,0],[1,0]],[[1,0],[0,0]]];
const Z = [[[1,0],[0,0]],[[0,0],[-1,0]]];
function applySingleQubitGate(state, gate, target, nQubits) {
const result = state.map(([re, im]) => [re, im]);
const step = 1 << target;
for (let i = 0; i < state.length; i++) {
if ((i & step) === 0) {
const j = i | step;
const [aRe, aIm] = state[i];
const [bRe, bIm] = state[j];
// result[i] = gate[0][0]*a + gate[0][1]*b
result[i] = cAdd(cMul(gate[0][0], [aRe,aIm]), cMul(gate[0][1], [bRe,bIm]));
// result[j] = gate[1][0]*a + gate[1][1]*b
result[j] = cAdd(cMul(gate[1][0], [aRe,aIm]), cMul(gate[1][1], [bRe,bIm]));
}
}
return result;
}
function applyCNOT(state, control, target) {
const result = state.map(([re, im]) => [re, im]);
for (let i = 0; i < state.length; i++) {
if ((i >> control) & 1) {
const j = i ^ (1 << target);
result[i] = [state[j][0], state[j][1]];
result[j] = [state[i][0], state[i][1]];
}
}
return result;
}
function runCircuit(nQubits, gates) {
let state = Array.from({ length: 1 << nQubits }, (_, i) =>
i === 0 ? [1, 0] : [0, 0]
);
for (const g of gates) {
if (['H','X','Y','Z','S','T'].includes(g.gate)) {
const mat = { H, X, Z }[g.gate];
state = applySingleQubitGate(state, mat, g.qubits[0], nQubits);
} else if (g.gate === 'CNOT') {
state = applyCNOT(state, g.qubits[0], g.qubits[1]);
}
}
const probs = state.map(([re, im]) => re*re + im*im);
return { state, probs };
}
// Complex arithmetic helpers
function cMul([aR,aI], [bR,bI]) { return [aR*bR-aI*bI, aR*bI+aI*bR]; }
function cAdd([aR,aI], [bR,bI]) { return [aR+bR, aI+bI]; }

Quantum gates are the building blocks of quantum computation. Each gate is a unitary transformation that acts on one or more qubits. Common single-qubit gates include Hadamard (H), Pauli-X (bit flip), Pauli-Z (phase flip), and rotation gates (Rx, Ry, Rz).

Every quantum gate is represented by a unitary matrix U satisfying U†U = UU† = I. This ensures that the total probability of all measurement outcomes always sums to 1. Unitarity also means every quantum operation is reversible.

The quantum circuit model represents computation as a sequence of gates applied to qubits, drawn as horizontal wires. Gates are applied left to right. The circuit model is the most common framework for designing quantum algorithms, analogous to logic circuits in classical computing.

Multi-qubit gates act on two or more qubits simultaneously. The CNOT (controlled-NOT) gate is the most important: it flips a target qubit only when the control qubit is |1>. CNOT is essential for creating entanglement and is, together with single-qubit gates, universal for quantum computation.

  • Gate ordering matters: Unlike some classical operations, quantum gate order is critical. Applying H then Z produces a different result from Z then H, because matrix multiplication is not commutative. Always read circuits from left to right.
  • Global phase irrelevance: Two state vectors that differ only by a global phase factor e^{iγ} (e.g., |psi> and -|psi>) are physically indistinguishable. However, relative phase between amplitudes is observable and crucial for interference effects.
  • Measurement destroys superposition: Measuring a qubit collapses its state to |0> or |1> probabilistically. After measurement, the superposition is lost and the qubit is in a definite classical state. This is irreversible, unlike gate operations.

Q1: What state does applying a Hadamard gate to |0> produce?

  • A) |1>
  • B) (|0> + |1>) / sqrt(2)
  • C) (|0> - |1>) / sqrt(2)
  • D) i|1>
Show answer

Answer: B) (|0> + |1>) / sqrt(2)

The Hadamard gate maps |0> to (|0> + |1>)/sqrt(2), which is the |+> state. This creates an equal superposition with a 50/50 probability of measuring 0 or 1.

Q2: Which gate pair, when applied to |00>, creates a Bell state (maximally entangled pair)?

  • A) X then Z
  • B) H on qubit 0, then CNOT(0,1)
  • C) H on both qubits
  • D) SWAP then H
Show answer

Answer: B) H on qubit 0, then CNOT(0,1)

Applying H to the first qubit creates (|0> + |1>)/sqrt(2) on qubit 0. Then CNOT entangles the qubits: |00> + |11>) / sqrt(2). This is the Bell state |Phi+>, a maximally entangled state.

Q3: Why must quantum gates be represented by unitary matrices?

  • A) To make computation faster
  • B) To preserve the normalization of the state vector (total probability = 1)
  • C) To ensure gates can be manufactured physically
  • D) To allow classical simulation
Show answer

Answer: B) To preserve the normalization of the state vector (total probability = 1)

Unitarity (U†U = I) guarantees that the norm of the state vector is preserved. Since measurement probabilities are the squared amplitudes, this ensures probabilities always sum to 1 after any gate operation.