A small, fast, header-only C++17 state-vector simulator for quantum circuits.
The state of n qubits is a vector of 2ⁿ complex numbers — the amplitudes.
To test or debug a quantum algorithm on an ordinary machine you have to carry
that whole vector and evolve it gate by gate.
The naive way to apply a gate is to treat it as a 2ⁿ × 2ⁿ matrix and multiply.
That is hopeless almost immediately: at 20 qubits that matrix has ~10¹² entries,
and the cost is O(4ⁿ). A textbook implementation stalls around 12–13 qubits.
The trick every real simulator uses: a gate on one or two qubits only ever mixes
pairs of amplitudes whose indices differ in those qubit bits. So you sweep
the 2ⁿ vector once, updating strided index pairs in place — O(2ⁿ) time and
no extra memory, no matrix ever built. The sweep is also embarrassingly
parallel.
statevector-sim is a compact, dependency-free implementation of exactly that:
the standard gate set, a fluent circuit builder, measurement sampling, OpenMP
parallelism, and correctness checks against analytic results (Bell, GHZ, QFT).
It is meant for learning, for testing small quantum algorithms, and as a
reference point next to production simulators like Qiskit Aer.
- Header-only, C++17, no external dependencies for the core (
#include "svsim/circuit.hpp"). - Gates:
H, X, Y, Z, S, S†, T, T†,RX, RY, RZ, phase,CX, CZ, CPHASE, SWAP, and any user-supplied 2×2. O(2ⁿ)strided-pair gate application; OpenMP-parallel; state vector allocated once, updated in place.- Measurement: single-shot sampling and
{outcome → count}histograms from|amplitude|². Circuitbuilder with method chaining; ready-madeghz(n)andqft(n).- Catch2 test suite; multi-OS CMake CI (Linux / macOS / Windows, Debug + Release).
- Optional experimental Python binding via pybind11.
cmake -B build -DCMAKE_BUILD_TYPE=Release
cmake --build build --parallel
ctest --test-dir build --output-on-failureRequires CMake ≥ 3.16 and a C++17 compiler. Catch2 is fetched automatically for
the tests; pass -DSVSIM_BUILD_TESTS=OFF to skip it.
Run the demo and the scaling benchmark:
./build/svsim_demo
./build/svsim_bench 26 # optional arg = max qubit count#include <iostream>
#include "svsim/circuit.hpp"
#include "svsim/state_vector.hpp"
int main() {
// Build a Bell pair and sample it.
svsim::StateVector sv = svsim::Circuit(2).h(0).cx(0, 1).run();
for (auto [outcome, count] : sv.sample_counts(/*shots=*/1000, /*seed=*/42)) {
std::cout << svsim::StateVector::to_bitstring(outcome, 2) << ": " << count << '\n';
}
// ~ 00: 500 11: 500
// Or drive the state directly.
svsim::StateVector q(3);
q.h(0);
q.cx(0, 1);
q.rz(1, 0.5);
std::cout << "P(|000>) = " << q.probability(0) << '\n';
}The core loop, for a gate on target with stride = 1 << target:
for each block of 2*stride consecutive amplitudes:
for offset in [0, stride):
i0 = block_base + offset # target bit = 0
i1 = i0 + stride # target bit = 1
(amp[i0], amp[i1]) = M * (amp[i0], amp[i1])
Every amplitude is touched exactly once, so one gate is O(2ⁿ). Controlled
gates run the same loop and skip pairs whose control bit is 0. CPHASE / CZ
and SWAP are single passes over the vector.
Qubits are little-endian: qubit q is bit q of the basis index (qubit 0 is
the least-significant bit). to_bitstring prints qubit n-1 on the left.
svsim_bench applies a full layer (a Hadamard on every qubit plus a CX chain,
2n − 1 gates) and reports time per gate as n grows. Representative shape
(numbers are machine-dependent; the point is the scaling):
| qubits | state size | time / full layer |
|---|---|---|
| 20 | 16 MiB | a few ms |
| 24 | 256 MiB | tens of ms |
| 28 | 4 GiB | hundreds of ms |
Time per gate grows ~2× per qubit, matching the O(2ⁿ) amplitude count; memory
is exactly 2ⁿ × 16 bytes.
-
-Werror/ clang-tidy gate in CI - Fused gate layers and cache blocking for large
n - Explicit qubit measurement with state collapse
- SIMD (AVX2 / NEON) kernels for the 1-qubit sweep
-
pip install-able Python package (scikit-build-core) - Benchmark comparison against Qiskit Aer
Built as a companion to a computer-engineering thesis on quantum algorithms (dr-andromeda/Theoretical-Practical-Study-Fundamentals-and-Implementation-of-Quantum-Algorithms), which benchmarked Qiskit / Cirq / PennyLane — this is a from-scratch look at what those libraries do underneath.
MIT © 2026 Baltasar Hurtado Jiménez