Organised by domain: Quantum Simulation, Molecular Chemistry, Condensed Matter, and Photonics. Full API and SDK reference with code examples.
pip install qumulator-sdk # CPU — unlimited qubits
pip install "qumulator-sdk[gpu]" # GPU — CuPy / JAX / PyTorch, auto-detected
from qumulator.local import LocalStatevectorEngine
eng = LocalStatevectorEngine(n_qubits=28) # no hard cap — use what your hardware has
eng.apply('h', 0)
for i in range(27): eng.apply('cx', [i, i+1])
result = eng.run(shots=4096, return_entropy_map=True)
Run your first quantum circuit in under two minutes. No account, no credit card, no hardware required.
One POST request returns a key immediately. The key is displayed once — save it somewhere safe.
# cURL
curl -s -X POST https://api.qumulator.com/keys \
-H "Content-Type: application/json" \
-d '{"name": "my-first-key"}'
# Response
{
"key": "qum_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"name": "my-first-key",
"created_at": "2026-04-20T12:00:00Z"
}
pip install qumulator-sdk
from qumulator import QumulatorClient
client = QumulatorClient(
api_url="https://api.qumulator.com",
api_key="qum_xxxxxxxx...",
)
# Build and run a 2-qubit Bell state
eng = client.circuit.engine(n_qubits=2)
eng.apply('h', 0).apply('cx', [0, 1])
counts = eng.sample(shots=1024)
print(counts) # {'00': ~512, '11': ~512}
QUMULATOR_API_KEY and read it with
os.environ["QUMULATOR_API_KEY"] to keep it out of source code.
Every request to the API (except POST /keys) must include your API key in the
X-API-Key header.
curl https://api.qumulator.com/circuits \
-H "X-API-Key: qum_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
The Python SDK handles this automatically once you pass api_key to
QumulatorClient.
POST /keys. There is no limit on how many keys you can create.
| Property | Value |
|---|---|
| Base URL | https://api.qumulator.com |
| Protocol | HTTPS only |
| Request format | JSON — Content-Type: application/json |
| Interactive docs | api.qumulator.com/docs (Swagger UI) |
The API is currently unversioned (no /v1/ prefix). Breaking changes will be
announced in advance.
pip install qumulator-sdk
Requires Python 3.10 or later. The core package has a single dependency: httpx.
Framework adapters (Qiskit, Cirq) require those packages installed separately.
# With Qiskit adapter
pip install qumulator-sdk qiskit
# With Cirq adapter
pip install qumulator-sdk cirq
QumulatorClient is the entry point for all computation types.
from qumulator import QumulatorClient
client = QumulatorClient(
api_url="https://api.qumulator.com",
api_key="qum_...",
)
| Attribute | Type | Purpose |
|---|---|---|
| client.circuit | CircuitClient | Quantum circuit simulation (gate builder, QASM, Hamiltonian evolution) |
| client.hamiltonian | HamiltonianClient | Spin ground states and Pauli Hamiltonian energy |
| client.hafnian | HafnianClient | Photonic amplitudes (hafnian, permanent, GBS) |
| client.homo | HomoClient | Molecular HOMO/LUMO frontier orbital energies |
| client.molecular | MolecularClient | Molecular ground-state energy via MPS/MPO (≤ 50 orbitals) |
| client.dmrg | DMRGClient | Exact DMRG ground-state energy via two-site sweeps (≤ 30 orbitals) |
| client.notebook | NotebookClient | Remote Jupyter notebook execution |
Submit quantum circuits via the gate builder, OpenQASM 2/3, Qiskit, or Cirq. The cluster circuit engine automatically routes each job to the most efficient backend — statevector (≤20 qubits), MPS (≤1,000 qubits), cluster-exact, Green’s function, or Gaussian — based on qubit count and entanglement structure. Results include measurement counts, the full statevector, per-qubit von Neumann entropy, QFI-based multipartite entanglement depth, and a Gaussian simulability certificate.
There are two ways to construct a circuit: the fluent gate builder and the direct gate-list API. Both are equivalent and produce identical results. No simulation runs locally — all execution is server-side.
Obtain a CircuitEngine from client.circuit.engine(),
accumulate gates with .apply(), then submit with
.run() or .sample().
eng = client.circuit.engine(n_qubits=3)
eng.apply('h', 0 ) # Hadamard on qubit 0
.apply('cx', [0, 1] ) # CNOT: control 0, target 1
.apply('cx', [0, 2] ) # CNOT: control 0, target 2
.apply('rz', 2, params=[1.5708]) # Rz(pi/2) on qubit 2
result = eng.run(
shots=4096,
return_statevector=True,
return_entropy_map=True,
)
print(result.counts) # {'000': ~2048, '111': ~2048}
print(result.entropy_map) # [1.0, 0.0, 0.0] — qubit 0 maximally entangled
print(result.statevector) # complex ndarray, length 8
result = client.circuit.run(
gates=[
('h', 0),
('cx', [0, 1]),
],
n_qubits=2,
shots=2048,
)
| Gate(s) | Qubits | Params | Description |
|---|---|---|---|
| h, x, y, z | 1 | — | Pauli and Hadamard |
| s, t, sdg, tdg | 1 | — | Phase / T gates and their adjoints |
| rx, ry, rz | 1 | [θ] | Rotation gates; angle in radians |
| u | 1 | [θ, φ, λ] | General single-qubit unitary (IBM U gate) |
| cx, cnot | 2 | — | CNOT (control, target) |
| cz | 2 | — | Controlled-Z |
| swap | 2 | — | SWAP |
| iswap | 2 | — | iSWAP |
| fsim | 2 | [θ, φ] | fSim gate (Google Sycamore / Willow family) |
| syc | 2 | — | Sycamore gate |
| ecr | 2 | — | Echoed cross-resonance (IBM native gate) |
| ccx, toffoli | 3 | — | Toffoli (CCNOT) |
| cswap, fredkin | 3 | — | Fredkin |
| unitary | 1–N | matrix | Arbitrary unitary; pass a 2N×2N complex matrix via params |
eng.apply('cx', [0, 1]).
Bitstrings in results are MSB-first: qubit 0 is the leftmost character.
| Parameter | Type | Description | |
|---|---|---|---|
| n_qubits | int | required | Number of qubits in the register |
| mode | str | Simulation mode. Default: "mps". See Simulation
Modes. |
|
| bond_dim | int | Bond dimension cap for "cluster_mps" and "mps"
modes |
| Parameter | Type | Default | Description |
|---|---|---|---|
| shots | int | 1024 | Measurement samples (1 to 1 000 000) |
| seed | int | None | RNG seed for reproducible sampling |
| return_statevector | bool | False | Include complex amplitude vector (requires N ≤ 20, "statevector" mode
only)
|
| return_probabilities | bool | False | Include probability vector (requires N ≤ 20, "statevector" mode only)
|
| return_entropy_map | bool | False | Include per-qubit entanglement entropy values |
Both OpenQASM 2 and OpenQASM 3 source strings are accepted. Pass the source to
client.circuit.run_qasm().
qasm_source = """
OPENQASM 3.0;
include "stdgates.inc";
qubit[3] q;
bit[3] c;
h q[0];
cx q[0], q[1];
cx q[0], q[2];
measure q -> c;
"""
result = client.circuit.run_qasm(
qasm=qasm_source,
shots=2048,
mode="statevector",
return_entropy_map=True,
)
print(result.counts) # {'000': ~1024, '111': ~1024}
stdgates.inc,
qelib1.inc, and custom gate definitions are all supported.
For gates with no standard QASM name (e.g. the SYC gate in Google Willow circuits), use the
instructions input with an explicit matrix:
import numpy as np
# Arbitrary 2-qubit unitary (e.g. Google SYC gate)
my_gate = np.array([
[1, 0, 0, 0 ],
[0, 0, -1j, 0 ],
[0, -1j, 0, 0 ],
[0, 0, 0, np.exp(1j * np.pi / 6)],
])
eng = client.circuit.engine(n_qubits=4)
eng.apply('unitary', [0, 1], params=my_gate.tolist())
.apply('unitary', [2, 3], params=my_gate.tolist())
result = eng.run(shots=1024)
Pass mode= to engine() or
run(). The default "mps" uses the MPS backend
and scales to 1,000 qubits.
| Mode | Best for | N limit |
|---|---|---|
"auto" |
Let the engine choose. Analyses the circuit’s entanglement graph and selects the
optimal backend automatically using the Kaplan–Yorke dimension (DKY).
The resolved mode and routing diagnostics are returned in
result.resolved_mode and
result.preflight_report.
|
≤ 1000 |
| "statevector" | Small circuits requiring full amplitude precision. Statevector and probability arrays available. | ≤ 20 |
| "mps" | General use. Matrix Product State backend — scales to 1,000 qubits. Optimal for circuits with 1D or near-1D connectivity, VQE, QAOA, chemistry ansätze. | ≤ 1000 |
| "cluster_mps" | Cluster-factorised MPS. Best for circuits with moderate entanglement and block structure — shallow random circuits, variational ansätze. | ≤ 1000 |
| "hamiltonian" | Direct time evolution under a Pauli-string Hamiltonian. Use with evolve_hamiltonian(). |
≤ 1000 |
| "gaussian" | Clifford-heavy circuits. Returns a GaussianCertificate classifying non-Clifford content. Memory scales as O(N²). | ≤ 1000 |
| "cluster_statevector" | Exact cluster-factorisation engine. No 2N state vector is ever allocated. Memory O(∑ 2kc) where kc is the size of each entangled cluster. Exact for all circuits (TVD = 0). Returns per-qubit marginal probabilities. | ≤ 1000 |
| "greens" | Green’s function / Bloch encoding. Exact within the free-fermion (Gaussian) subspace.
O(N2) memory. Returns per-qubit marginals and von Neumann entropy map.
Note: CNOT in the exchange subspace is not faithfully represented — use
"cluster_statevector" for exact results on entangling circuits.
|
≤ 1000 |
| "fibonacci_anyon" | Topological quantum computing. SU(2)3 Chern–Simons Fibonacci
anyons. Hilbert space dimension FN+2. Native braid gates:
fibonacci_f, fibonacci_r,
fibonacci_b, fibonacci_bdg.
Topological XEB score available. Matches Microsoft topological qubit target.
|
≤ 1000 |
| "kuramoto" | Bose-Hubbard BEC / Kuramoto synchronisation. Phase-oscillator engine;
superfluid order parameter r = |⟨eiθ⟩|.
O(N2) memory. Call kuramoto_diagnostics()
for full phase-space output. Scales to N = 10,000+ oscillators.
|
≤ 10000 |
| "cluster_gaussian" | Cluster-factorised exact probability engine. Never builds 2N statevector; O(∑ 2kc) memory. Exact joint probabilities P(x) via cluster Born rule. | ≤ 1000 |
| "sparse" | Adaptive sparse exact simulation. O(K log K) per gate where K = active basis states. Up to 78× faster than dense statevector for GHZ / particle-conserving circuits. Automatically hands off to MPS when K exceeds the MPS crossover threshold. | Unlimited (K ≪ 2N) |
When mode="auto" is used, the engine builds the circuit’s
entanglement graph, estimates the fractal dimension DKY of its entanglement
structure, and routes to the optimal backend before simulation begins.
Tree-topology circuits are routed to "mps";
Clifford-only circuits to "gaussian";
high-entanglement small circuits to "statevector".
No simulation cost is incurred for the analysis.
Use POST /circuits/preflight to inspect the routing decision
without running a simulation at all (zero compute units).
Use mode="hamiltonian" and call evolve_hamiltonian()
to apply e−iHt directly from a Pauli-string Hamiltonian, without
requiring a gate decomposition.
eng = client.circuit.engine(n_qubits=4, mode="hamiltonian")
eng.apply('h', 0).apply('h', 1) # initial state preparation
eng.evolve_hamiltonian(
pauli_terms=[
( 0.5, 'ZZII'), # ZZ coupling on sites 0-1
( 0.5, 'IZZI'), # ZZ coupling on sites 1-2
(-1.0, 'XIIX'), # transverse field
],
t=1.0, # evolution time
)
result = eng.run(shots=2048, return_entropy_map=True)
Pauli strings use I X Y Z per qubit; the leftmost character is qubit 0.
eng = client.circuit.engine(n_qubits=20, mode="gaussian")
for i in range(20):
eng.apply('h', i)
for i in range(0, 19, 2):
eng.apply('cz', [i, i+1])
eng.apply('t', 5) # non-Clifford gate
result = eng.run(shots=1024)
cert = result.gaussian_certificate
print(cert.rcs_certificate) # "LIKELY_GAUSSIAN"
print(cert.entanglement_regime) # "area_law"
print(cert.gaussian_fidelity) # 0.991
print(cert.wigner_negativity_estimate) # small positive float
| Certificate label | Meaning |
|---|---|
| GAUSSIAN_SIMULABLE | Purely Clifford circuit; Gaussian approximation is exact. |
| LIKELY_GAUSSIAN | Non-Clifford content is small; high-fidelity approximation. |
| NON_GAUSSIAN_CORRECTION_NEEDED | Substantial non-Clifford content; switch to "statevector" or "cluster_mps" for full accuracy. |
QumulatorBackend is a drop-in replacement for any Qiskit simulator backend.
Build your circuit in Qiskit as normal; the adapter transpiles and runs it on Qumulator.
from qumulator import QumulatorClient
from qumulator.backends.qiskit_backend import QumulatorBackend
from qiskit import QuantumCircuit
client = QumulatorClient(api_url="https://api.qumulator.com", api_key="qum_...")
backend = QumulatorBackend(client)
qc = QuantumCircuit(2)
qc.h(0)
qc.cx(0, 1)
qc.measure_all()
job = backend.run(qc, shots=2048)
result = job.result()
counts = result.get_counts()
print(counts) # {'00': ~1024, '11': ~1024}
get_counts() returns Qiskit-standard keys.
No changes to your existing code are needed.
# cluster_mps mode for a large variational circuit
backend = QumulatorBackend(client, mode="cluster_mps")
job = backend.run(qc, shots=8192)
Any Qiskit circuit can be sent to Qumulator. The adapter automatically transpiles to the supported
gate set. Gates that expose gate.to_matrix() are submitted as arbitrary
unitaries and simulated exactly.
# Run your parameterised ansatz on Qumulator instead of a local simulator
bound_circuit = ansatz.assign_parameters(theta_values)
bound_circuit.measure_all()
job = backend.run(bound_circuit, shots=4096)
counts = job.result().get_counts()
expectation_value = compute_energy(counts, hamiltonian)
QumulatorSimulator implements Cirq's Simulator
interface and supports both sampling and statevector simulation.
import cirq
from qumulator import QumulatorClient
from qumulator.backends.cirq_simulator import QumulatorSimulator
client = QumulatorClient(api_url="https://api.qumulator.com", api_key="qum_...")
sim = QumulatorSimulator(client)
q0, q1 = cirq.LineQubit.range(2)
circuit = cirq.Circuit(
cirq.H(q0),
cirq.CNOT(q0, q1),
cirq.measure(q0, q1, key='result'),
)
# Sampling
result = sim.run(circuit, repetitions=1024)
print(result.histogram(key='result')) # Counter({0: ~512, 3: ~512})
# Statevector
sv = sim.simulate(circuit)
print(sv.final_state_vector)
# array([0.707+0j, 0+0j, 0+0j, 0.707+0j])
cirq.unitary(), so any gate with a
unitary representation is supported — including custom operations and Sycamore-family gates.
q = cirq.LineQubit.range(4)
circuit = cirq.Circuit(
[cirq.H(qi) for qi in q],
cirq.SYC(q[0], q[1]),
cirq.SYC(q[2], q[3]),
[cirq.measure(qi, key=str(i)) for i, qi in enumerate(q)],
)
result = sim.run(circuit, repetitions=2048)
Compute molecular properties directly from SMILES strings or PySCF active-space integrals (1e/2e arrays). Three complementary methods are available: HOMO/LUMO frontier orbital energies via DFT (B3LYP/6-31G* default; any basis and functional supported); MPS/MPO ground-state energies for multi-fragment active spaces up to 50 orbitals; and DMRG for exact FCI-quality energies up to 30 orbitals with systematic bond-dimension convergence.
Compute HOMO and LUMO frontier orbital energies from a SMILES string. Results include the HOMO–LUMO gap and per-atom orbital density weights.
# Resveratrol
result = client.homo.run("Oc1ccc(/C=C/c2cc(O)cc(O)c2)cc1")
print(result.homo_E_eV) # -5.515 eV (B3LYP/6-31G*)
print(result.lumo_E_eV) # -0.821 eV
print(result.gap_eV) # HOMO-LUMO gap in eV
print(result.heavy_symbols) # ['C', 'C', ..., 'O', 'O']
print(result.homo_density) # per-heavy-atom HOMO weight
# Use a larger basis set and a different functional
result = client.homo.run(
"c1ccccc1", # benzene
basis="6-31g",
xc="pbe0",
)
| Field | Type | Description |
|---|---|---|
| homo_E_eV | float | HOMO energy in eV |
| lumo_E_eV | float | LUMO energy in eV |
| gap_eV | float | HOMO–LUMO gap in eV |
| homo_density | list[float] | Per-heavy-atom HOMO orbital density |
| lumo_density | list[float] | Per-heavy-atom LUMO orbital density |
| heavy_symbols | list[str] | Element symbol for each heavy atom |
| n_occ | int | Number of occupied orbitals |
| basis | str | Basis set used (default: 6-31g*) |
| xc | str | Exchange-correlation functional (default: b3lyp) |
Compute the quantum ground-state energy of an active-space Hamiltonian using the Givens-MPS / Matrix Product Operator (MPS/MPO) engine. Accepts one-body and two-body integrals extracted from any PySCF active-space calculation.
from pyscf import gto, scf, mcscf, ao2mo
# Build molecule and extract active-space integrals
mol = gto.M(atom="H 0 0 0; H 0 0 0.74", basis="sto-3g")
mf = scf.RHF(mol).run()
mc = mcscf.CASSCF(mf, ncas=2, nelecas=2).run()
h1e, e_core = mc.get_h1eff()
h2e = ao2mo.restore(1, mc.get_h2eff(), mc.ncas)
e_nuc = mc.energy_nuc() + e_core
# Call the MPS/MPO engine
result = client.molecular.energy(
h1e=h1e.tolist(),
h2e=h2e.tolist(),
n_elec=[1, 1],
e_nuc=float(e_nuc),
)
print(result.energy) # ground-state energy in Ha
print(result.n_qubits) # 2 × n_orb spin-orbitals
print(result.n_components) # MPS bond dimension (entanglement measure)
circuit = [
{"type": "givens", "i": 0, "j": 1, "theta": 0.3},
]
result = client.molecular.energy(
h1e=h1e.tolist(), h2e=h2e.tolist(),
n_elec=[1, 1], e_nuc=float(e_nuc),
circuit=circuit,
)
| Field | Type | Description |
|---|---|---|
| energy | float | Ground-state energy in Hartrees |
| n_qubits | int | Spin-orbitals = 2 × n_orb |
| n_orb | int | Active orbitals |
| n_components | int | MPS bond dimension |
| zz_correlators | list[list[float]] | None | ⟨ZiZj⟩ correlator matrix |
| Parameter | Limit |
|---|---|
| n_orb | ≤ 30 |
| Default timeout | 300 s |
Compute the quantum ground-state energy using the Density Matrix Renormalization Group
(DMRG) engine.
DMRG sweeps converge systematically to the exact FCI limit as the bond dimension
d_max increases.
result = client.dmrg.energy(
h1e=h1e.tolist(),
h2e=h2e.tolist(),
n_elec=[1, 1],
e_nuc=float(e_nuc),
d_max=64, # bond dimension — higher = more accurate
n_sweeps=8, # number of DMRG sweeps
)
print(result.energy) # ground-state energy in Ha
print(result.converged) # True if |ΔE| < tol
print(result.wall_time_s) # server-side runtime
| Active orbitals | d_max | n_sweeps |
|---|---|---|
| ≤ 6 | 16–32 | 8 |
| 6–12 | 64 | 8–12 |
| 12–20 | 128–256 | 10–20 |
| 20–30 | 256–512 | 15–50 |
| Field | Type | Description |
|---|---|---|
| energy | float | Ground-state energy in Hartrees |
| converged | bool | True if |ΔE| < tol |
| n_sweeps_run | int | Sweeps performed |
| d_max_used | int | Bond dimension used |
| n_orb | int | Active orbitals |
| n_so | int | Spin-orbitals = 2 × n_orb |
| wall_time_s | float | Server-side wall time (s) |
| Parameter | Limit |
|---|---|
| n_orb | ≤ 30 |
| d_max | ≤ 512 |
| n_sweeps | ≤ 50 |
| Default timeout | 900 s |
Compute ground states and real-time dynamics of lattice spin models via exact diagonalisation (Pauli-string Hamiltonian input) or TEBD (Time-Evolving Block Decimation). Supported Hamiltonian presets include the transverse-field Ising model (TFIM), XX free-fermion chain, Heisenberg XXX, Kuramoto–Ising, and the AKLT spin-1 chain. Observable outputs include per-bond von Neumann entropy, QFI density, magnetisation trajectory, Kibble–Zurek defect density, and the AKLT hidden string order parameter Ostring.
Compute ground-state energies for interacting spin systems or arbitrary Pauli-string Hamiltonians. Returns the minimum energy configuration plus a per-site entanglement entropy map.
Pass a dictionary of Pauli-string → coefficient entries. Each key is an N-character string
over {I, X, Y, Z}, one character per site.
# H2 molecule — STO-3G, Jordan-Wigner mapping (2 sites)
result = client.hamiltonian.run(
pauli_hamiltonian={
"II": -1.8572750, # constant / nuclear repulsion
"ZI": -0.3979374,
"IZ": -0.3979374,
"ZZ": 0.3980202,
"XX": 0.1809270,
"YY": 0.1809270,
},
)
print(result.energy) # ground-state energy in Hartree
print(result.entropy_list) # per-site entanglement entropy
import numpy as np
N = 16
J = np.random.randn(N, N)
J = (J + J.T) / 2 # symmetrize
np.fill_diagonal(J, 0)
result = client.hamiltonian.run(interaction_matrix=J.tolist())
print(result.energy) # ground-state energy
print(result.states) # per-site spin expectation values
print(result.max_S) # max bipartite entanglement entropy
| Field | Type | Description |
|---|---|---|
| energy | float | Ground-state energy |
| states | list[float] | Per-site expectation values |
| entropy_list | list[float] | Per-site entanglement entropy |
| max_S | float | Maximum bipartite entanglement entropy |
| mean_S | float | Mean entanglement entropy across all bipartitions |
The client.evolve sub-client provides Hamiltonian time evolution via
TEBD (Time-Evolving Block Decimation) and exact state preparation. Six endpoints are available:
| Method | Description |
|---|---|
client.evolve.run() |
Real-time TEBD evolution (Suzuki-Trotter 1st/2nd order). Returns a trajectory
list of observables (entropy, magnetization, QFI) at each timestep. |
client.evolve.quench() |
Sudden quench / collapse-and-revival protocol. Returns trajectory + optional
C_tR ZZ-correlator heatmap.
|
client.evolve.ground() |
Imaginary-time evolution to the ground state. Returns energy,
bond_entropy, and converged.
|
client.evolve.aklt() |
Exact AKLT Valence Bond Solid state preparation (depth-O(1), χ=2 MPS). Returns bond entropy, phase labels, and hidden string order parameter Ostring. |
client.evolve.qkzm() |
Kibble-Zurek quench protocol. Returns kzm_defect_density,
kzm_prediction, and tau_Q.
|
client.evolve.lattice() |
2D lattice regime classifier. Returns bond_entropy_2d heatmap
and phase_label. |
# 10-site transverse-field Ising model, critical point J=h=1
result = client.evolve.run(
n_qubits=10,
hamiltonian={"preset": "ising_1d", "J": 1.0, "h": 1.0},
t_max=2.0,
dt=0.1,
bond_dim=64,
observables=["entropy", "magnetization", "qfi"],
initial_state="ferromagnet",
order=2,
)
for pt in result.trajectory:
print(pt["t"], pt.get("max_entropy"), pt.get("f_Q_density"))
gs = client.evolve.ground(
n_qubits=10,
hamiltonian={"preset": "ising_1d", "J": 1.0, "h": 1.0},
bond_dim=64,
)
print(gs.energy) # ground-state energy
print(gs.bond_entropy) # per-bond von Neumann entropy
qkzm = client.evolve.qkzm(
n_qubits=20, J=1.0, h0=5.0, h_f=0.2, t_ramp=5.0,
)
print(qkzm.kzm_defect_density) # n_d ∝ τ_Q^{−1/2}
print(qkzm.kzm_prediction)
| Preset | Model | Parameters |
|---|---|---|
"ising_1d" |
Transverse-field Ising chain | J, h |
"xx_model" |
XX free-fermion chain | t |
"heisenberg" |
XXX Heisenberg chain | J |
"kuramoto_ising" |
Kuramoto-Ising H (DM coupling) | J, K |
"aklt" |
AKLT spin-1 chain (Haldane phase, 2 qubits per spin-1 site) | J_AF, J_FM |
Custom Pauli-sum Hamiltonians are also supported via terms:
each term is {"sites": [i, j], "operator": "ZZ", "strength": -1.0}.
The AKLT model (Affleck-Kennedy-Lieb-Tasaki, 1987) is a spin-1 chain with an exactly-known ground state called the Valence Bond Solid (VBS). It is the prototypical example of a symmetry-protected topological (SPT) phase — the Haldane phase — and a universal resource for measurement-based quantum computation (MBQC).
| Observable | Expected value | Meaning |
|---|---|---|
| Bond entropy S | 1.000 bit (inter-site bonds exact) | One singlet = one ebit per virtual bond; entanglement label "topological_class". Intra-site bonds S = 0 ("product_state"). |
| Max bond dimension χ | 2 (all chain lengths) | Minimum non-trivial MPS; area-law entanglement |
| String order Ostring | −1/4 = −0.250 (constant) | Hidden Z₂×Z₂ order in the 2-qubit virtual-bond encoding; constant for all site separations; vanishes outside the Haldane phase |
| Haldane gap | Δ ≈ 0.41 J | Finite gap protecting the SPT phase |
phase_labels is a list of per-bond entanglement regime identifiers,
derived from the von Neumann entropy S of each MPS bond's Schmidt decomposition.
These labels are standard quantum-information terminology and apply to all TEBD endpoints.
| Label | Entropy range | Description |
|---|---|---|
"product_state" |
S < 0.1 bits | Unentangled — qubits on either side of the bond are independent |
"area_law" |
0.1–0.6 bits | Bounded entanglement; MPS-tractable at any depth |
"topological_class" |
0.6–1.2 bits | SPT / topological phase regime — the AKLT VBS inter-site bond has S = 1 bit and lands here exactly |
"near_volume_law" |
1.2–2.5 bits | High entanglement, approaching volume-law |
"volume_law" |
S ≥ 2.5 bits | Near-maximal entanglement — Haar-random / deep circuit regime |
# Prepare exact AKLT VBS for 10 spin-1 sites (20 qubits), no TEBD needed
vbs = client.evolve.aklt(
n_sites=10,
observables=["entropy", "string_order", "qfi"],
string_order_pairs=[[0, 9], [1, 8], [2, 7]],
)
print(vbs.max_bond_dim) # 2 — exact χ=2 MPS
print(vbs.mean_bond_entropy) # ≈ 0.50 bits (inter-site=1.0, intra-site=0.0)
print(vbs.phase_labels[1]) # "topological_class" (inter-site bonds, S=1 bit — SPT/Haldane regime)
print(vbs.string_order) # {"O_string(0,9)": -0.250, ...}
# Use "aklt" preset: n_qubits = 2 × n_sites
# initial_state="neel" is required — the default |0…0⟩ is a fixed point
gs = client.evolve.ground(
n_qubits=20,
hamiltonian={"preset": "aklt", "J_AF": 1.0, "J_FM": 2.0},
initial_state="neel",
dtau=0.05,
n_steps=400,
bond_dim=4,
)
print(gs.energy) # converges to AKLT ground energy
print(gs.converged) # True
dyn = client.evolve.run(
n_qubits=20,
hamiltonian={"preset": "aklt"},
t_max=5.0,
dt=0.05,
observables=["entropy", "magnetization"],
)
Each spin-1 site is encoded in 2 qubits: qubit 2i is the left virtual spin-1/2 and qubit 2i+1 is the right virtual spin-1/2. The Hamiltonian contains only nearest-neighbour qubit interactions, fully compatible with the TEBD engine:
| Bond type | Qubits | Operator | Strength | Physics |
|---|---|---|---|---|
| Inter-site (AF) | (2i+1, 2i+2) | XX + YY + ZZ | JAF/4 | Singlet formation on virtual bond |
| Intra-site (FM) | (2i, 2i+1) | XX + YY + ZZ | −JFM/4 | Enforces symmetric (triplet) subspace |
Compute hafnian and permanent amplitudes for Gaussian boson sampling (GBS) circuits. Input is a symmetric
coupling matrix A of dimension 2m×2m for an m-mode GBS device.
Results are computed in arbitrary-precision arithmetic (configurable via mp_dps,
default 34 decimal digits) and verified against double-precision references to below
5×10−15 relative error. An 8-mode hafnian completes in 39 ms; 12-mode in
43 ms.
Compute the hafnian, permanent, or Gaussian boson sampling amplitudes from a symmetric coupling matrix. The result is a complex number computed to configurable precision.
import numpy as np
n = 8
A = np.random.randn(n, n)
A = (A + A.T) / 2
np.fill_diagonal(A, 0)
result = client.hafnian.run(matrix_real=A.tolist())
print(result.value) # complex: haf_real + 1j*haf_imag
print(result.elapsed) # server compute time in seconds
# Complex coupling matrix, 50 decimal digits of precision
result = client.hafnian.run(
matrix_real=A_real.tolist(),
matrix_imag=A_imag.tolist(),
mp_dps=50, # default: 34
)
| Field | Type | Description |
|---|---|---|
| haf_real | float | Real part of the hafnian |
| haf_imag | float | Imaginary part |
| value | complex | Property: haf_real + 1j*haf_imag |
| elapsed | float | Server-side compute time (seconds) |
| max_S | float | Maximum coupling entropy |
| n_edges | int | Number of non-trivial coupling pairs |
| est_matchings | float | Estimated number of perfect matchings |
Submit a Jupyter notebook (.ipynb) for remote execution. The notebook runs
in an isolated sandbox environment with qumulator-sdk and the full scientific
Python stack pre-installed.
# Submit and wait for completion
with open("my_experiment.ipynb", "rb") as f:
nb_bytes = f.read()
status = client.notebook.run(nb_bytes)
print(status.status) # "completed"
# status.result contains the executed notebook with outputs
import time
with open("my_experiment.ipynb", "rb") as f:
job_id = client.notebook.submit(f.read())
print("Job submitted:", job_id)
while True:
status = client.notebook.status(job_id)
if status.is_done:
break
time.sleep(3)
if status.ok:
executed_notebook = status.result
else:
print("Failed:", status.error)
numpy,
scipy, matplotlib,
pandas, qiskit,
cirq, and qumulator-sdk.
Additional packages can be installed at the top of your notebook with
!pip install ....
Gate-level circuit simulation, benchmarks against real quantum hardware, and algorithm demonstrations.
| Notebook | Description |
|---|---|
| Willow RCS Benchmark | 105-qubit exact simulation on a Willow-layout SYC grid — XEB fidelity validation |
| CHSH Bell Inequality | Bell state + CHSH correlator, S = 2√2 Tsirelson bound |
| Cluster Engine Demo | Exact simulation without 2N state vector — mode="cluster_statevector" |
| Prime Factorization | Shor’s algorithm — factors N=35 via quantum-inspired energy landscape |
| QUBO Optimisation | 100-variable dense combinatorial optimisation — QAOA / variational |
| Green’s Function Engine | Free-fermion circuits, O(N²) memory, entropy map — mode="greens" |
| Cluster Geometry | Entanglement growth in random H/CX/Rz brickwork circuits |
Ab-initio ground state energies, orbital visualisation, and DMRG solvers for real molecules.
| Notebook | Description |
|---|---|
| N₂ Ground State | 12-qubit exact simulation — CASCI(6,6), 79 kcal/mol correlation recovered (100%), 3.2 s |
| H₂ Ground State | Exact 4-qubit simulation — CASCI(2,2)/STO-3G, 100% correlation recovery |
| LiH Ground State | Pauli-Hamiltonian DMRG solver — 1.15 mHa error, chemical accuracy |
| H₁₂ Chain Ground State | 12-site Ising chain via Hamiltonian solver — client.hamiltonian |
Many-body physics: topological phases, non-Abelian anyons, Floquet dynamics, and holographic protocols.
| Notebook | Description |
|---|---|
| Holographic Wormhole | Traversable wormhole protocol (SYK model) — matches Google Sycamore 2022 |
| Anyon Braiding | Fibonacci anyons, SU(2)3 Chern–Simons non-Abelian braiding — matches
Microsoft topological target — mode="fibonacci_anyon" |
| Discrete Time Crystal | MBL Floquet dynamics, discrete time-translation symmetry breaking — matches Google Sycamore 2021 |
| Collapse & Revival / QKZM | TEBD Hamiltonian time evolution, Kibble-Zurek scaling — client.evolve |
| Kuramoto BEC | N=500 Bose-Hubbard superfluid–Mott transition — Kuramoto order parameter r, condensate
fraction — mode="kuramoto" |
| Sparse Circuit Engine | GHZ at N=500, Givens particle-conserving circuits — up to 78× speedup over dense
statevector — mode="sparse" |
Gaussian boson sampling, hafnian amplitudes, and photonic quantum advantage.
| Notebook | Description |
|---|---|
| Boson Sampling Demo | GBS correctness baseline, 8×8–12×12 hafnians, self-XEB at N=12, exact N=1,000 simulation — five independent capability demonstrations |
| Hafnian Benchmark | 4×4 → 16×16 GBS matrices — compute time scaling, verified against
thewalrus reference to <10&sup-10; relative error
|
| GBS Output Distribution | Full photon-number probability distribution for a 4-mode squeezed-vacuum GBS experiment — enumerates all patterns up to 6 photons, normalisation verified |
| Permanent vs Hafnian | Distinguishable vs identical photons through a linear optical network — Hong-Ou-Mandel dip confirmed: P(1,1)=0 for bosons, P(1,1)=0.5 classically |
| Quantum Advantage Threshold | Jiuzhang-style scaling analysis — classical spoofability crossover, log-scale extrapolation, Jiuzhang-2020 overlay at 50 photons, signed speedup certificate |
Quantum computing applied to everyday problems — no physics background required.
| Notebook | Description |
|---|---|
| European Call Option Pricer | Quantum amplitude estimation vs Black-Scholes — <1% error on a 5-qubit circuit |
| Fantasy Football Lineup Optimizer | DraftKings salary-cap QUBO solved with the Hamiltonian engine |
No authentication required.
| Field | Type | Description |
|---|---|---|
| name | string | Human-readable label |
# Response 201
{
"key": "qum_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx",
"name": "my-key",
"created_at": "2026-04-20T12:00:00Z"
}
Returns job_id immediately. Simulation runs asynchronously.
| Field | Type | Description | |
|---|---|---|---|
| qasm | string | OpenQASM 2 or 3 source. Provide either qasm or instructions. |
|
| instructions | array | JSON gate instruction list. Requires n_qubits. |
|
| n_qubits | int | Register width. Required when using instructions. |
|
| shots | int | Measurement samples. Default: 1024. Max: 1 000 000. | |
| mode | string | Simulation mode. Default: statevector. |
|
| seed | int | RNG seed for reproducible sampling. | |
| return_statevector | bool | Include complex amplitude vector in result. | |
| return_entropy_map | bool | Include per-qubit entropy values in result. | |
| bond_dim | int | Bond dimension cap for tensor-network modes. |
# Submit via cURL
curl -X POST https://api.qumulator.com/circuits \
-H "X-API-Key: qum_..." \
-H "Content-Type: application/json" \
-d '{
"qasm": "OPENQASM 3.0; include \"stdgates.inc\"; qubit[2] q; h q[0]; cx q[0],q[1]; bit[2] c; measure q->c;",
"shots": 1024,
"mode": "statevector"
}'
# Response 202
{ "job_id": "01HX8M7PVKTA..." }
Returns the most recent circuit jobs for your API key.
All simulation endpoints return a job_id immediately. Poll until
status is "completed" or
"failed".
# Poll a job
curl https://api.qumulator.com/circuits/01HX8M7PVKTA \
-H "X-API-Key: qum_..."
# While running
{ "job_id": "01HX...", "status": "running", "result": null }
# When complete
{
"job_id": "01HX...",
"status": "completed",
"entanglement_dof": 3.8124,
"dof_converged": true,
"result": {
"counts": { "00": 512, "11": 512 },
"n_qubits": 2,
"shots": 1024,
"entropy_map": [1.0, 1.0]
}
}
| Status | Meaning |
|---|---|
| queued | Accepted and waiting for a worker |
| running | Simulation in progress |
| completed | Result available in result field |
| failed | Error message in error field |
| Field | Type | Description |
|---|---|---|
| counts | dict[str, int] | Measurement outcome counts. Keys are MSB-first bitstrings (qubit 0 leftmost). |
| n_qubits | int | Register width |
| shots | int | Total measurement samples |
| statevector | ndarray|None | Complex amplitude vector of length 2N. Populated when return_statevector=True. |
| probabilities | ndarray|None | Probability vector. Populated when return_probabilities=True. |
| entropy_map | list[float]|None | Per-qubit entanglement entropy in bits. 1.0 = maximally entangled; 0.0 = product state. |
| f_Q_density | float|None | QFI density (Tóth–Gühne 2012). f_Q > k certifies genuine
(k+1)-partite entanglement. 0.0 for product states. |
| entanglement_depth | int|None | Certified entanglement depth = ⌊f_Q⌋. 0 = separable; k = genuine (k+1)-partite entanglement. |
| predicted_tvd | float|None | TVD upper bound to the exact distribution. 0.0 for unconditionally
exact modes ("statevector", "cluster_statevector").
|
| phase_label | str|None | Entanglement-phase label (Z1–Z5) returned when using mode="phase".
|
| gaussian_certificate | GaussianCertificate|None | Populated when mode="gaussian". |
| most_probable | str (property) | Bitstring with the highest count |
| Field | Type | Description |
|---|---|---|
| rcs_certificate | str | GAUSSIAN_SIMULABLE | LIKELY_GAUSSIAN | NON_GAUSSIAN_CORRECTION_NEEDED |
| entanglement_regime | str|None | area_law | transitional | volume_law |
| wigner_negativity_estimate | float|None | Estimated non-Clifford correction from T-gate content |
| gaussian_fidelity | float|None | Estimated fidelity of the Gaussian approximation (0–1) |
| xeb_lower_bound | float|None | Cross-entropy benchmark lower bound |
| Field | Type | Description |
|---|---|---|
| job_id | str | Job identifier |
| status | str | queued | running | completed | failed |
| result | dict|None | Engine result when completed |
| error | str|None | Error message when failed |
| is_done | bool | Property: True when completed or failed |
| ok | bool | Property: True when completed |
| entanglement_dof | float|None | Effective entanglement degrees of freedom at job completion. Computed as
(Σσi)² / Σσi²
from the singular-value spectrum of the off-diagonal 1-RDM block.
0.0 = product state;
N/2 = maximally entangled.
null for non-circuit jobs.
|
| dof_converged | bool|None | true when entanglement DOF has stopped growing between
layers (relative change < 1 %). Indicates the circuit has reached
entanglement saturation — additional depth will not increase correlation.
null when entanglement_dof
is not available.
|
Circuit depth, not qubit count, determines memory. Requests exceeding a tier limit return HTTP 422 with a self-documenting error message.
| Tier | Qubit range | Max depth | Peak memory | Notes |
|---|---|---|---|---|
| 1 | 1–20 | 20 layers | ~335 MB | Full-depth VQE, QAOA, variational ansätze at any structure. |
| 2 | 21–54 | 9 layers | ~216 MB | Covers IBM Eagle (27 q) and Osprey (54 q) layouts. |
| 3 | 55–105 | 8 layers | ~105 MB | Covers Willow-scale (105 q) near-term superconducting layouts. |
| 4 | 106–1000 | 7 layers | ~250 MB | At depth 7, a 1,000-qubit circuit uses ~250 MB — within the platform's 350 MB cap. |
| N > 1000 | Rejected (HTTP 422). Contact us for large-scale access. | |||
"statevector" mode is limited to N ≤ 20 (Tier 1 only). All modes follow
the tier depth limits above.
| Limit | Value |
|---|---|
| Circuit simulations per key per minute | 1 |
| Circuit simulations per key per day | 100 |
| Window type | Rolling 60-second window |
| HTTP status when exceeded | 429 with Retry-After header |
The Retry-After header tells you exactly how many seconds to wait.
The SDK surfaces this as QumulatorHTTPError(status_code=429).
from qumulator import QumulatorHTTPError
import time
try:
result = eng.run(shots=1024)
except QumulatorHTTPError as e:
if e.status_code == 429:
retry_after = int(e.response.headers.get("Retry-After", 10))
time.sleep(retry_after)
result = eng.run(shots=1024) # retry once
All error responses use the shape {"detail": "...message..."}.
| Status | Meaning |
|---|---|
| 400 | Malformed JSON or missing required field. |
| 401 | Missing or invalid X-API-Key header. |
| 422 | Validation error — circuit exceeds a tier limit, unknown gate, or unsupported mode. The response body includes a self-documenting message with the full tier table. |
| 429 | Rate limit exceeded. Check the Retry-After header. |
| 500 | Internal server error. Retry after a moment; contact us if it persists. |
# Example 422 response (circuit exceeds tier limit)
{
"detail": "Limit Exceeded: 30 qubits at depth 15. Tier 2 (21-54 q) max depth is 9.
Tiers: T1(1-20q,d≤20) T2(21-54q,d≤9) T3(55-105q,d≤8) T4(106-1000q,d≤7)"
}