Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Conventions

Qubit order

Qubit 0 is the least significant bit of a basis index, as in Qiskit. The amplitude at index k belongs to the basis state with bit q of k on qubit q. Bit strings are printed with qubit n−1 first, so "001" means qubit 0 is 1.

import metatron_qso as q

state = q.simulate(q.Circuit(3).x(0))
assert abs(state.amplitudes[1]) == 1.0      # index 1 = 0b001
assert q.bitstring(1, 3) == "001"

Cirq and PennyLane order qubits the other way. The cross-framework comparison reverses the qubits when it compares their states with QSO’s.

Gates and time evolution

ObjectConvention
RotationsR_P(θ) = exp(−iθP/2) for P ∈ {X, Y, Z}
Two-qubit rotationsR_PP(θ) = exp(−iθ P⊗P/2)
Phase gateP(λ) = diag(1, e^{iλ})
U(θ, φ, λ)as in OpenQASM 2
Time evolutionexp(−iHt)
Quantum walksH = γL (Laplacian) or H = −γA (adjacency)

Randomness

All randomness goes through one portable, seeded generator (xoshiro256++). Functions that sample or restart take a seed. The same seed gives the same result on every platform and for every thread count.

Errors

Invalid input raises ValueError in Python and returns QsoError in Rust, never a panic. This covers, among others, out-of-range qubits, wrong parameter counts, non-finite values, unsupported OpenQASM and oversized requests. The fuzz tests check this for the parsers.

import metatron_qso as q

try:
    q.Circuit(2).cx(0, 2)
except ValueError as e:
    print(e)

Limits

LimitValue
Pure-state register34 qubits (16 bytes per amplitude)
Density-matrix register14 qubits
Pauli stringsqubits 0–63
Custom unitary gatesup to 6 target qubits
Exact walk analysisup to 2048 nodes (Krylov propagation beyond)
Graphs from specifications and Python constructors2²⁰ nodes, 2²² edges (hypercubes up to dimension 20)
OpenQASM importversion 2.0, up to 2¹⁴ qubits and 2²² gates