The quantum gates that built our art, explained with Qiskit
Every circuit we ran to generate the Quantum Genesis pieces is built from a small set of quantum gates. When I first picked up Qiskit, gates felt like abstract boxes on a diagram — I could run them but I didn't really get what they were doing. This is the walkthrough I needed back then, built the way I actually learned it: pick a gate, run it, look at the output, and only then believe the description.
If you've never touched quantum computing, here's the one mental hook that makes everything else click: a qubit's state is a point on a sphere (the Bloch sphere), and each gate rotates that point. Different gates rotate around different axes by different amounts. A computation is just a sequence of rotations followed by a measurement that collapses the sphere to a definite 0 or 1.

What quantum gates are
In classical computing, logic gates (AND, OR, NOT) transform bits. Quantum gates do the same for qubits, but they operate on probability amplitudes rather than just 0s and 1s.
Mathematically, a quantum gate is a unitary transformation — a matrix U where U times its conjugate transpose equals the identity matrix. That guarantees quantum information is preserved: no information lost, no probabilities exceeding 1.
In circuit diagrams, gates are boxes on horizontal wires, one wire per qubit, with time flowing left to right.
Pauli gates: X, Y, Z
The three Pauli gates are the fundamental single-qubit operations, each a 180-degree rotation around one axis.
Pauli-X (bit flip) is the quantum NOT gate. It maps |0⟩ to |1⟩ and |1⟩ to |0⟩.
from qiskit import QuantumCircuit
qc = QuantumCircuit(1)
qc.x(0) # Apply X gate to qubit 0
qc.measure_all()
print(qc.draw())
# ┌───┐ ░ ┌─┐
# q_0: ┤ X ├─░─┤M├
# └───┘ ░ └╥┘
Starting in |0⟩, after X the qubit is guaranteed |1⟩. Simple and deterministic.
Pauli-Y combines a bit flip with a phase flip, rotating 180 degrees around the Y axis. Less common alone, but essential in many algorithms.
qc = QuantumCircuit(1)
qc.y(0) # Apply Y gate
Pauli-Z leaves |0⟩ unchanged but flips the phase of |1⟩ (multiplies by -1). You can't observe this in a single measurement, but it changes interference in larger circuits.
qc = QuantumCircuit(1)
qc.z(0) # Apply Z gate -- phase flip only
Think of Z as flipping the "hidden sign" of a qubit — invisible on its own, but critical once gates interact.
The Hadamard gate: superposition creator
The Hadamard (H) gate is arguably the most important single-qubit gate. It puts a qubit into an equal superposition of |0⟩ and |1⟩.
Applied to |0⟩, H produces (|0⟩ + |1⟩)/√2 — a 50/50 chance of measuring 0 or 1. Applied to |1⟩ it produces (|0⟩ - |1⟩)/√2, still 50/50 but with a phase difference that matters for interference.
from qiskit import QuantumCircuit
from qiskit_ibm_runtime import SamplerV2 as Sampler
qc = QuantumCircuit(1)
qc.h(0) # Hadamard: creates superposition
qc.measure_all()
print(qc.draw())
# ┌───┐ ░ ┌─┐
# q_0: ┤ H ├─░─┤M├
# └───┘ ░ └╥┘
# Running on real hardware gives ~50% |0>, ~50% |1>
# But NOT exactly 50/50 -- that's real quantum noise!
> Fun fact: applying H twice returns the qubit to its original state. H is its own inverse — a quantum toggle switch.
On the Bloch sphere, H takes the north pole (|0⟩) to the equator, right between 0 and 1. It's the starting point of nearly every quantum algorithm — without it, qubits behave classically.
CNOT: the entanglement gate
The CNOT (Controlled-NOT) gate is the most important two-qubit gate. It takes a control and a target qubit; if the control is |1⟩ it flips the target, and if the control is |0⟩ it does nothing.
qc = QuantumCircuit(2)
qc.cx(0, 1) # CNOT: qubit 0 controls, qubit 1 is target
print(qc.draw())
# q_0: ──■──
# ┌─┴─┐
# q_1: ┤ X ├
# └───┘
On its own, CNOT isn't that exciting. The magic happens with a Hadamard:
qc = QuantumCircuit(2)
qc.h(0) # Put qubit 0 in superposition
qc.cx(0, 1) # Entangle qubit 0 and qubit 1
qc.measure_all()
# q_0: ┤ H ├──■──
# ┌─┴─┐
# q_1: ──────┤ X ├
# Results: ~50% "00", ~50% "11"
# NEVER "01" or "10" -- they're entangled!
This H + CNOT combination creates a Bell state, the simplest form of entanglement. The two qubits become correlated: measuring one instantly determines the other.
Rotation gates: Rx, Ry, Rz
While Pauli gates are fixed 180-degree rotations, rotation gates let you specify any angle, giving fine-grained control.
import math
qc = QuantumCircuit(1)
# Rotate by any angle (in radians)
qc.rx(math.pi / 4, 0) # Rotate around X axis by 45 degrees
qc.ry(math.pi / 3, 0) # Rotate around Y axis by 60 degrees
qc.rz(math.pi / 2, 0) # Rotate around Z axis by 90 degrees
- Rx(θ) rotates around the X axis. At θ=π it equals Pauli-X.
- Ry(θ) rotates around the Y axis. Useful for preparing specific probability distributions — Ry(π/2) on |0⟩ gives equal superposition like H, without the phase difference.
- Rz(θ) rotates around the Z axis. A pure phase rotation; it changes the hidden angle without affecting measurement probabilities in the standard basis.
> Universality: any single-qubit gate decomposes into Rz, Ry, Rz. Combined with CNOT, you can build any quantum circuit. This is the universal gate set.
Toffoli: 3-qubit control
The Toffoli gate (CCX) extends CNOT to three qubits: two controls and one target. The target flips only when both controls are |1⟩ — the quantum equivalent of a classical AND (followed by XOR).
qc = QuantumCircuit(3)
qc.ccx(0, 1, 2) # Toffoli: qubits 0,1 control, qubit 2 is target
print(qc.draw())
# q_0: ──■──
# │
# q_1: ──■──
# ┌─┴─┐
# q_2: ┤ X ├
# └───┘
The Toffoli is universal for classical computation — any Boolean circuit can be built from Toffolis alone — and it's reversible, making it the bridge between classical and quantum computing. In practice it's expensive: it decomposes into about 6 CNOT gates, so algorithms try to minimize its use.
Combining gates into circuits
A quantum circuit is a sequence of gates on a register of qubits, followed by measurements. Here's a complete 4-qubit entangled state:
from qiskit import QuantumCircuit
qc = QuantumCircuit(4, 4)
# Step 1: Superposition on all qubits
for i in range(4):
qc.h(i)
# Step 2: Entangle pairs
qc.cx(0, 1)
qc.cx(2, 3)
# Step 3: Cross-entangle
qc.cx(1, 2)
# Step 4: Add some rotation for variety
qc.rz(0.5, 0)
qc.ry(0.3, 3)
# Step 5: Measure
qc.measure(range(4), range(4))
print(qc.draw())
The output is a probability distribution over 16 states (0000 through 1111). On a real quantum computer, noise and decoherence add extra variation — which is a feature, not a bug, when generating art.
Gate order matters. Unlike classical logic, the order of quantum gates dramatically affects the outcome — matrix multiplication isn't commutative, so the order of Bloch-sphere rotations matters:
# These produce DIFFERENT states:
qc1 = QuantumCircuit(1)
qc1.h(0)
qc1.z(0) # H then Z
qc2 = QuantumCircuit(1)
qc2.z(0)
qc2.h(0) # Z then H -- different result!
How we used these gates
For Quantum Genesis we designed circuits for maximum entropy — unpredictable, irreproducible randomness:
# Simplified version of our NFT generation circuit
qc = QuantumCircuit(8, 8)
# Hadamard on all 8 qubits -- maximum superposition
for i in range(8):
qc.h(i)
# CNOT chain -- entangle all qubits
for i in range(7):
qc.cx(i, i + 1)
# Measure all
qc.measure(range(8), range(8))
# Run on REAL quantum hardware (IBM ibm_fez or Origin WK_C180)
# Each run produces genuinely random bits
The H + CNOT chain entangles all 8 qubits in a GHZ-like state. When measured, the quantum noise from real hardware produces bits that are fundamentally unpredictable — not pseudo-random, but physically random from quantum mechanics.
These raw bits become seeds for color palettes, geometry, and composition. Pieces #1-18 were generated on the Origin Quantum WK_C180 (180 qubits), and #19-100 on IBM Quantum's ibm_fez and ibm_torino processors.
Why real hardware matters: a simulator gives you perfect 50/50 distributions from Hadamard gates. Real hardware has noise — gate errors, decoherence, crosstalk between qubits. That noise is genuinely random and makes each execution unique and irreproducible. For art, that's exactly what you want.
Gate summary
| Gate | Qubits | Symbol | Effect | Qiskit |
|---|---|---|---|---|
| Pauli-X | 1 | X | Bit flip (NOT) | qc.x(0) |
| Pauli-Y | 1 | Y | Bit + phase flip | qc.y(0) |
| Pauli-Z | 1 | Z | Phase flip | qc.z(0) |
| Hadamard | 1 | H | Superposition | qc.h(0) |
| CNOT | 2 | CX | Conditional flip | qc.cx(0,1) |
| Rx/Ry/Rz | 1 | R | Arbitrary rotation | qc.rx(θ,0) |
| Toffoli | 3 | CCX | Double-controlled flip | qc.ccx(0,1,2) |

Gates stop being intimidating the moment you stop reading about them and start running them. Write a two-qubit circuit, add an H and a CNOT, and look at the distribution — you'll see the correlation yourself, and that's the whole foundation of what makes quantum-generated art interesting.
Comments
Post a Comment