sabfodel / physics

project · active · Rust

qsim-rs

State-vector quantum circuit simulator written from scratch, without a quantum SDK.

Circuit diagram of a Bell-state preparation — a Hadamard on qubit 0 followed by a CNOT onto qubit 1 — next to a histogram with only the outcomes 00 and 11.
Fig. 1 The Bell-state example. Over 1024 shots only 00 and 11 appear — the two qubits are perfectly correlated.

result Tests check physics, not code paths — unitarity of every gate, H² = I, HZH = X, Bell and GHZ correlations, and an 80k-shot histogram flat within 4σ.

I use Qiskit for quantum computing coursework, but I wanted to know what a simulator actually does when you call run(). So I wrote one.

How it works

An nn-qubit pure state is a vector of 2n2^n complex amplitudes. Index ii in binary labels the basis state ∣i⟩\lvert i \rangle; qubit 0 is the least significant bit, matching Qiskit.

The stride trick. A single-qubit gate on qubit tt only couples amplitude pairs whose indices differ in bit tt. With s=2ts = 2^t, those pairs are (i, i+s)(i,\ i + s) for every ii with bit tt clear, and each pair is updated by the 2×22 \times 2 unitary:

(a′b′)=(u00u01u10u11)(ab)\begin{pmatrix} a' \\ b' \end{pmatrix} = \begin{pmatrix} u_{00} & u_{01} \\ u_{10} & u_{11} \end{pmatrix} \begin{pmatrix} a \\ b \end{pmatrix}

One pass over the vector, O(2n)O(2^n), and no 2n×2n2^n \times 2^n matrix is ever built.

Controlled gates are index masking. Apply the same 2×22 \times 2 block only where the control bit is set. CNOT is a controlled-X; no separate 4×44 \times 4 matrix needed.

Measurement samples from ∣amplitude∣2\lvert \text{amplitude} \rvert^2 (the Born rule) for full-register shots, or does a projective single-qubit measurement with collapse and renormalisation.

Gate set

H, X, Y, Z, S, T, Rx, Ry, Rz, CNOT, CZ — with a builder API:

// Bell state: H on q0, then CNOT(q0 → q1)
let state = Circuit::new(2).h(0).cnot(0, 1).run();

What I learned

Qubit ordering is a convention you must pick on day one. Half the confusion in comparing against textbooks comes from little- vs big-endian labelling.

Interference is the test that matters. H2=IH^2 = I restores ∣0⟩\lvert 0 \rangle exactly, which no classical probability model reproduces — it’s the cleanest check that the amplitudes, not just the probabilities, are right.

Limitations

  • Exponential memory: every extra qubit doubles the state vector.
  • Pure states only — no noise or mixed states yet.

Next

  • Grover’s algorithm example (oracle + diffuser)
  • BB84 key distribution
  • Noise channels (depolarising, amplitude damping)
  • Benchmark against Qiskit Aer’s statevector output