Simulating a tiny quantum computer
A quantum state is a vector of amplitudes, and gates are matrices. Build Hadamard, X and CNOT in numpy, make a Bell state, and see why n qubits need 2ⁿ numbers.
In 60 seconds
Simulating a tiny quantum computer
A quantum state is a vector of amplitudes, and gates are matrices. Build Hadamard, X and CNOT in numpy, make a Bell state, and see why n qubits need 2ⁿ numbers.
Three gates
| Gate | Acts on | What it does | Matrix |
|---|---|---|---|
| X (NOT) | 1 qubit | Swaps |0⟩ and |1⟩, like a classical NOT | [[0, 1], [1, 0]] |
| H (Hadamard) | 1 qubit | |0⟩ → (|0⟩ + |1⟩)/√2 and |1⟩ → (|0⟩ − |1⟩)/√2 | [[1, 1], [1, −1]] / √2 |
| CNOT | 2 qubits | Flips the second (target) qubit if the first (control) is 1 | 4 × 4, swaps the 10 and 11 amplitudes |
Two qubits: order and the Kronecker product
np.kron. For example, np.kron(H, I) applies H to qubit 0 and leaves qubit 1 alone.Build a Bell state
- 1
Start
Both qubits in |0⟩: the vector [1, 0, 0, 0]. - 2
Hadamard on qubit 0
Now (|00⟩ + |10⟩)/√2. - 3
CNOT, control 0, target 1
The |10⟩ part becomes |11⟩. Result: (|00⟩ + |11⟩)/√2.
import numpy as np
I = np.eye(2)
H = np.array([[1, 1], [1, -1]]) / np.sqrt(2)
CNOT = np.array([[1, 0, 0, 0],
[0, 1, 0, 0],
[0, 0, 0, 1],
[0, 0, 1, 0]])
state = np.array([1.0, 0, 0, 0]) # |00>
state = np.kron(H, I) @ state # H on qubit 0
state = CNOT @ state # entangle
for label, amp in zip(["00", "01", "10", "11"], state):
print(label, round(float(amp), 3), "prob", round(float(amp) ** 2, 3))Why big simulations are hard
# Each amplitude stored as a complex number takes 16 bytes (complex128 in numpy).
for n in [10, 20, 30, 40, 50]:
amplitudes = 2 ** n
gigabytes = amplitudes * 16 / 1e9
print(f"{n:2d} qubits: {amplitudes:>20,d} amplitudes, about {gigabytes:,.3f} GB")np.kron(I, X) (X on qubit 1) before the Hadamard. Which two outcomes appear now?Watch and read more
Lab
A numpy simulator that builds a Bell state and a second entangled state from gate matrices, with their probabilities printed.
The problem
Run this in the browser, or with Python 3 and numpy. Qubit 0 is the left bit.
- Make
bellequal (|00⟩ + |11⟩)/√2 by applying H on qubit 0 and then CNOT tostart. Use the matrices, not typed-in answers. - Make
otherequal (|01⟩ + |10⟩)/√2, starting again fromstart. Hint: first apply X to one qubit. - Print the probabilities of both states with
show. - Write one sentence: how many amplitudes would a 3-qubit version need?
Practice lab
Edit the code and run it. Python runs in your browser — nothing is sent to our server.
No output. Add print(...) to see values.
You are done when
Hard questions
Try to answer before you reveal. If you can answer these, you understood the lesson.
Q1Extend the simulator to 3 qubits and make (|000⟩ + |111⟩)/√2. Which gates do you need?Reveal
Apply H to qubit 0 with np.kron(np.kron(H, I), I). Then apply CNOT from qubit 0 to qubit 1 with np.kron(CNOT, I), and CNOT from qubit 1 to qubit 2 with np.kron(I, CNOT). The state vector has 8 amplitudes, and only 000 and 111 are non-zero. This is often called a GHZ state.
Q2Our simulator builds full 4 × 4 or 8 × 8 matrices. Why do serious simulators avoid building a 2ⁿ × 2ⁿ matrix for each gate?Reveal
A full matrix for n qubits has 2ⁿ × 2ⁿ entries, far more than the state vector itself. Since each gate only touches one or two qubits, a simulator can update the state vector directly, pair by pair or in small groups of amplitudes, without ever building the big matrix. The memory needed is then about the size of the state vector, which is still 2ⁿ.
Questions people ask
Why are gates matrices?
Quantum mechanics says the changes you can make to a closed system (without measuring) are linear and keep the total probability equal to 1. Linear maps are matrices, and the "keep probability 1" rule means the matrices are unitary. X, H and CNOT are all unitary.
Is measurement also a matrix?
Not in the same way. Measurement is not a unitary gate: it picks a random outcome with the Born rule and then the state jumps to match the outcome. In our simulator we do this by sampling from the probabilities.
Are real quantum programs written like this?
People usually use a quantum programming library that builds circuits for them, and can send them to a simulator or real hardware. Under the hood, a simulator does what you did here. Writing it yourself once makes those libraries much easier to understand.
If simulation is so hard, how do we check big quantum computers are right?
This is a real challenge. Researchers check small parts that can be simulated, use special circuits whose answers are known, and use problems where a proposed answer is easy to verify, such as checking that two numbers multiply to give a third.
Lesson test
5 questions. Get 3 right (60%) to pass and complete this lesson.