Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Research-grade quantum state machine and QSML interpreter for qubits, qudits, and oscillators with channels, algebra, and normal-ordering.

License

simulanics/QSML

Repository files navigation

QSM — Quantum State Machine (Research Prototype)

Author: Matthew A. Combatti · Organization: Simulanics Technologies
License: MIT

QSM is a research-grade interpreter for a minimalist quantum scripting language (QSML) that lets you prototype quantum algorithms, open-system noise, qudit (d-level) logic, and oscillator (bosonic) algebras quickly. It emphasizes clarity and hackability over low-level optimization.

⚠️ Scope: This is a dense, explicit linear-algebra engine for education, ideation, and early-stage research—not a full-stack accelerator or hardware runtime.


✨ Highlights

  • Qubits & Qudits: qudit d, init(|0>,|1>,|+>,|->), initd(|k>, d), Xd(d), Zd(d), Id(d).
  • Oscillators (bosons): oscillator N, ladder ops a(N), adag(N), number Nop(N), coherent(alpha, N), normal ordering for polynomials in a, a† with CCR.
  • Channels:
    • Built-in qubit: depolarize(p, n_qubits), amplitude_damp(gamma, n_qubits)
    • D-ary: depolarizeD(p, D) (affine map)
    • Custom: unitary(OP), kraus({K1, K2, ...})
  • Algebra & Rewrites: Declare algebras and relations (e.g., CCR), and have expressions rewritten before evaluation.
  • Measurements & Expectation: measure(state, A), expect(state, A).
  • QEC Demo: Didactic [[5,1,3]] toy recovery mapping for single-Pauli errors.

🔧 Installation

Requires Python 3.9+.

pip install numpy

Place qsm.py in a folder. Optionally create a scripts/ directory for examples.


🚀 Quickstart

Run the REPL:

python qsm.py

Run a script:

python qsm.py ./scripts/demo_bell.qsm

Batch (Bash):

PYTHON_BIN=python ./run_all_scripts.sh

Batch (Windows):

set PYTHON_BIN=python
run_all_scripts.bat

🧠 QSML Language Reference

Global settings

// Set default d for Xd/Zd/Id
qudit 3

// Set oscillator cutoff N for a/adag/Nop and normal_order
oscillator 20

// Seed RNG for reproducible measurement sampling
seed 42

States

state s  = init(|0>)              // qubit |0>
state t  = init(|+>)              // qubit |+> = H|0>
state u  = initd(|2>, 5)          // qudit d=5 in |2>
state coh = coherent(1.2, 30)     // bosonic coherent state |α=1.2>, cutoff=30
state s2 = s                      // copy state
psi = tensor(s, t)                // ρ_psi = ρ_s ⊗ ρ_t

All states are represented internally as density matrices and auto-normalized.

Operators

Operators are matrices. QSM includes:

  • Qubit single-qubit: I, X, Y, Z, H, S, T, parametric RX(θ), RY(θ), RZ(θ).
  • Two-qubit: CNOT (already 4×4; do not tensor an extra Id unless you truly want 3+ qubits).
  • Qudit: Xd(d) (shift), Zd(d) (clock), Id(d); bare Xd, Zd, Id use current qudit d.
  • Oscillator (cutoff N): a(N), adag(N), Nop(N); bare a, adag, Nop use current oscillator N.

Define operators:

operator U = H otimes Id                  // tensor product
operator R = RX(1.234)                    // parametric rotation
operator W = Xd(7) + 0.2 * Zd(7)          // sums & scalar multiples
operator NO = normal_order(adag(20)*a(20)*adag(20)*a(20), 20)

Token note: I is a scalar 1 (promotion to identity occurs in sums). For tensor products, use Id (or Id(d)), not I.

Operator Expressions (grammar)

  • Atoms: operator names or calls (H, CNOT, RX(θ), Xd(5), a(20)), reals/complex scalars, I (scalar).

  • Binary ops:

    • A * B (matrix product / scalar scaling)
    • A + B, A - B (sum/difference; auto-promotes scalar to identity of matching dim)
    • A ⊗ B or A otimes B (tensor product; both sides must be operators)
  • Parentheses for grouping.

Examples:

operator K = (RZ(0.3) * RX(0.7)) + 0.1 * Id
operator T3 = Xd(3) ⊗ Zd(3)

Normal Ordering (oscillator)

operator NO = normal_order(EXPR[, N])
  • Input EXPR may contain a(N), adag(N), I, scalars, + - * ( ).
  • Uses CCR ([a, adag] = I) to rewrite to normal-ordered form (all adag to the left of a), then evaluates as a matrix at cutoff N.
  • If N omitted, inferred from the first ladder term or current oscillator.

Algebras & Rewrites (symbolic)

Declare a named algebra with generators and relations:

algebra Osc = { a, adag, I | CCR }                     // expands to a*adag = adag*a + I
algebra MyAlg = { A, B | comm(A,B) = 2*I }             // A*B = B*A + 2*I
algebra Foo = { X, Y | X*Y = Y*X + Z, Z*X = X*Z }      // general equalities

These relations are turned into directional rewrite rules and applied to operator expressions before evaluation.

Channels

Define channels:

chan UH     = unitary(U)                        // U must be unitary
chan AD     = amplitude_damp(0.1, 2)            // qubit amplitude damping on first qubit of 2-qubit state
chan D1     = depolarize(0.2, 3)                // qubit depolarizing on first qubit of 3-qubit register
chan Dany   = depolarizeD(0.35, 7)              // D-ary (dimension=7) depolarizing ρ ↦ (1-p)ρ + p I/D

// Custom dephasing via Kraus (example p=0.25):
operator I1 = Id
operator Z1 = Z
chan PD = kraus({ 0.8660254037844386 * I1, 0.5 * Z1 }) // sqrt(0.75), sqrt(0.25)

Apply channels:

psi = apply(psi, UH)
psi = apply(psi, D1)

Dimensions must match the state. For Kraus, Σ K†K = I is validated.

Expectation & Measurement

expect val = expect(psi, Z otimes Z)   // prints [EXPECT] val := (x+yj)
r = measure(psi, Z)                    // Hermitian only; prints eigenvalue and probability

Error Correction (toy demo)

qrec = error_correct(q, [[5,1,3]])     // demo recovery for single-Pauli errors on 5-qubit register

📚 Examples

Bell + depolarizing on one qubit

// Build Bell state
seed 7
qudit 2
state a = init(|0>)
state b = init(|0>)
psi = tensor(a, b)

chan UH = unitary(H otimes Id)
psi = apply(psi, UH)
chan UCN = unitary(CNOT)               // CNOT is 4x4 already
psi = apply(psi, UCN)

// Baseline correlations
operator XX = X otimes X
operator ZZ = Z otimes Z
expect xx0 = expect(psi, XX)
expect zz0 = expect(psi, ZZ)

// Noise on qubit-1 (first in register)
chan D1 = depolarize(0.2, 2)
psi = apply(psi, D1)
expect xx1 = expect(psi, XX)
expect zz1 = expect(psi, ZZ)

Qutrit depolarizing (D-ary)

qudit 3
state s = initd(|1>, 3)
chan Dany = depolarizeD(0.35, 3)
s = apply(s, Dany)
expect z = expect(s, Zd(3))

Oscillator normal ordering

oscillator 25
operator NO = normal_order(adag(25)*a(25)*adag(25)*a(25), 25)
state coh = coherent(0.8, 25)
expect v = expect(coh, NO)

🧪 Script Runners

Windows (run_all_scripts.bat):

Bash (run_all_scripts.sh):


🧰 Troubleshooting

  • “Tensor product requires operators, not bare scalars.” You used I otimes .... Use Id (or Id(d)) for operator identity in tensors; I is scalar 1.

  • “Unitary dimension does not match state.” Check you didn’t write CNOT otimes Id for a 2-qubit state. CNOT is already 4×4.

  • “Kraus set is not trace-preserving.” Verify Σ K†K = I. Coefficients must be the square roots of probabilities.


🛣️ Roadmap Ideas

  • Sparse backends for larger Hilbert spaces.
  • Native stabilizer simulator for Clifford circuits.
  • Noise library expansion (phase damping, thermalization).
  • Symbolic engine improvements (non-commutative term ordering ↔ evaluator).

🔒 License

MIT — see LICENSE.

Copyright © 2025 Matthew A. Combatti — Simulanics Technologies

About

Research-grade quantum state machine and QSML interpreter for qubits, qudits, and oscillators with channels, algebra, and normal-ordering.

Resources

License

Code of conduct

Contributing

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published