Skip to main content

SIA — Simplified Integrated Architecture

PyPI Python License

sia-script is the Python library of Sia Software Innovations Private Limited. It provides an offline quantum simulator, a client for the HDQS quantum server, a declarative entity module, and an ABAP-style enterprise logic interpreter, all behind short, chainable APIs.

from sia import hdqs

q = hdqs(2).h(0).cx(0, 1)
print(q.sample(1000))          # {'00': ~500, '11': ~500}

One import is all a program needs.


Contents


Installation

pip install sia-script

Requires Python 3.9 or newer. The install brings NumPy, Requests, Matplotlib and openqasm3, so figures, animations, paper figures, worksheets and QASM work straight away. Heavier features are extras:

pip install "sia-script[torch]"     # trainable quantum layers, CUDA acceleration
pip install "sia-script[full]"      # torch and SciPy
pip install "sia-script[all]"       # everything, including Qiskit/Aer/PennyLane adapters

Components

Import What it is Needs network
from sia import hdqs Offline quantum simulator (hdqs(n)), plus the server client through the same name No (simulator)
from sia import ntt SiaNTT declarative entities with safe, AST-checked expressions No
from sia import els SIA Enterprise Logic Studio, an ABAP-style interpreter No

The simulator runs entirely on your machine. Importing sia makes no network call; only the server client contacts the HDQS server, and only when you create a client.

Quantum simulation: hdqs

Chainable circuits

Every gate returns the register, so programs stay short:

from sia import hdqs

q = hdqs(3).h(0).cx(0, 1).cx(1, 2)          # GHZ state
q.show_state()                                    # amplitude table
print(q.sample(1000))                             # measurement counts
print(q.estimator("ZZI")["value"])                # <ZZI> = 1.0
print(q.resources()["depth"])                     # 3

Gates: h x y z s sdg t tdg rx ry rz p u3 cx cy cz cp crx cry crz swap ccx cswap mcx (cnot and toffoli are aliases), the cx_chain() ladder, plus barrier, reset_qubit, measure and custom unitary.

Noise

Density-matrix mode supports CPTP-verified channels:

from sia import hdqs

q = hdqs.dm(2).h(0).cx(0, 1).depolarizing(0, 0.05).amplitude_damping(1, 0.1)
print(q.purity(), q.concurrence())

noisy = hdqs(2).h(0).cx(0, 1).with_noise("depolarizing", 0.01)   # replay with noise

Channels: bit flip, phase flip, depolarizing, amplitude damping, phase damping, generalized amplitude damping, thermal relaxation, coherent over-rotation, amplitude–phase coupling, correlated two-qubit noise, and classical readout error.

Programs: replay, feed-forward, undo

The register remembers its own program, so the same object can be rerun, drawn, optimized, exported or undone:

from sia import hdqs

q = hdqs(3).h(0).cx(0, 1).ry(2, 0.4)
print(q.run(500).counts)                               # rerun as a program
print(q.copy().compose(q.inverse()).probability_of("000"))   # undo: 1.0

ff = hdqs(2).h(0).measure(0, key="m").if_x("m", 1)    # mid-circuit feed-forward
print(ff.records, ff.run(1000).counts)

measure(qubit, key="m") keeps the chain going and stores the outcome in q.records["m"]; if_x, if_z and if_gate record their condition, so run(), draw() and to_qasm3() reproduce the program exactly. Branch with these, not with a Python if. Plain measure(qubit) still returns the outcome as a string.

Large registers and simulation modes

A register too large for a full state (above the 1 GiB default budget) records its program instead of failing, and can run on the stabilizer or MPS simulator:

from sia import hdqs

print(hdqs(200).h(0).cx_chain().stabilizer().sample(5))       # 200-qubit GHZ
print(hdqs(40).h(0).cx_chain().mps().summary()["max_bond_dimension"])   # 2
Mode Call Use for
statevector hdqs(n) (default) Exact pure-state simulation
density matrix hdqs.dm(n) Exact mixed states and noise
trajectory q.run(mode="trajectory", noise=...) Sampled noise at statevector memory cost
stabilizer q.stabilizer() Large Clifford-only circuits
MPS q.mps(max_bond_dim=...) Low-entanglement circuits

For parameterized templates reused with different values, use hdqs.Circuit with hdqs.Parameter and run(bindings=...) or sweep(...).

Algorithms and protocols

from sia import hdqs

print(hdqs.grover(3, ["101"])["best"])          # '101'
print(hdqs.simon("110")["recovered"])           # '110'
print(sorted(hdqs.shor_demo(15)["factors"]))    # [3, 5]
print(hdqs.teleport()["fidelity"])              # 1.0
print(hdqs.bb84(256, eavesdrop=True)["eavesdropping_suspected"])   # True

Included: Deutsch, Deutsch–Jozsa, Bernstein–Vazirani, Grover, Simon, QFT (qft_demo), phase estimation, order finding and a small Shor demonstration, teleportation, superdense coding, VQE, QAOA, a repetition code, and the BB84, E91 and QSS protocols (educational simulations, not production key distribution). Every result can animate itself with .draw() (see Algorithm visuals).

Analysis and mitigation

Observables and Pauli sums, sampled estimates with standard errors, Trotter evolution, entropy, concurrence, negativity, mutual information, state tomography, readout-error mitigation, zero-noise extrapolation, and CRIA interference accessibility (interference_report, interference_profile, recover_interference).

Machine learning (requires [torch])

import torch
from sia import hdqs

layer = hdqs.quantum_layer(4, layers=2)                 # an ordinary torch.nn.Module
out = layer(torch.rand(8, 4, dtype=torch.float64))     # (8, 4) Pauli-Z expectations

hdqs.quantum_layer(..., diff="parameter_shift") gives hardware-style gradients instead. The underlying classes are BackpropQuantumLayer, QuantumLayer, MidCircuitQuantumLayer, QASMQuantumLayer, and CircuitQuantumLayer (any Circuit, including exact gradients through mid-circuit measurement).

Visuals: one call, letter codes

from sia import hdqs

q = hdqs(3).h(0).cx(0, 1).ry(2, 0.7).cx(1, 2)
q.draw("b")                          # Bloch spheres, shown inline or in a window
q.draw("b,a,e", "state.png")         # several views in one figure
q.draw("all", "lesson.html")         # offline interactive page with a gate-by-gate slider
q.draw("a,b", "steps.gif")           # animation over the gates
q.draw("b,q,d", "model.glb")         # 3D for Blender
q.draw("b", "bloch.3mf")             # colour 3D print, with a print report
q.draw("c,b,a", "fig.pdf", preset="paper")   # journal figure + caption
q.draw("c", "circuit.tex")           # LaTeX (quantikz)
q.export_bundle("experiment.zip")    # everything needed to publish or reproduce it
q.code()                             # the hdqs chain that rebuilds q
Code View
c Circuit diagram (controls, targets, angles, measurements, conditions)
p Exact probabilities
h Measured counts (shots=), with ±1σ error bars and the exact values
a Amplitudes & phase: bar height = magnitude, colour and a clock hand = phase
b Bloch sphere for every qubit, with coordinates and purity
q Q-sphere: basis states by number of 1s, coloured by phase
d Density matrix, real and imaginary parts (up to 5 qubits, or qubits=[...])
e Entanglement map: mutual information and concurrence for every qubit pair
i CRIA interference profile with the best helper sets
s Step-through: the state after every gate
all Every 2D view (c p h a b q d e i)

Codes combine with commas ("b,a,e"), and several outputs can be written at once ("x.png,x.html,x.glb"). The file extension picks the output:

Extension Output Needs
.png .jpg .svg .pdf .webp Combined figure, light or dark (theme="dark"); preset="paper" for publications —
.gif Animation over the gates —
.html Interactive page: step slider, rotatable spheres, exact values on hover, table view, data download. One file, works offline and on phones —
.json .csv The numbers behind every view —
.tex The circuit as LaTeX quantikz (standalone=False for the bare environment) —
.glb .obj 3D scene for Blender, Maya, Unity or web viewers, with every part a named object —
.3mf Print-ready colour model in millimetres: one named, coloured part per piece, print report inside —
.stl Watertight, print-ready model in millimetres —

3D files are produced only when a 3D extension is named, so "all" never writes one by accident. The 3D views are b, q and d. q.draw("bell.png") still draws the circuit, and q.plot(...) still returns a Matplotlib figure.

3D printing

q = hdqs(2).h(0).cx(0, 1).ry(1, 0.4)
q.draw("b", "bell.3mf", diameter=60)                  # 60 mm spheres, FDM settings
q.draw("b", "bell.stl", preset="resin", wall=0.6)     # finer resin print
q.last_print_report["min_feature_mm"]
3D print report — bell.3mf  (3MF, preset fdm)
  ✓ watertight / manifold
  ✓ minimum feature: 1.2 mm  (target wall 1.2 mm)
  • size: 153 × 66 × 76.4 mm
  • volume: ≤ 32.71 cm³ (overlapping parts are merged by the slicer)
  • 34 parts, 49,456 triangles, 6 colours
  • overhangs: 6.5% of surface — supports recommended
Option Meaning
diameter= Sphere diameter in mm (otherwise scale= × 60 mm)
wall= Thinnest printed feature in mm; tubes and letters are thickened to it
preset= "fdm" (wall 1.2 mm, medium detail, the default) or "resin" (0.5 mm, high detail)
detail= "low", "medium", "high": fewer or more triangles
base= Stand with an embossed label plate (False for none)
labels= True / "embossed" or "none"; labels too small for the wall are enlarged a little or left out with a note
report= False to skip printing the report (it is still in q.last_print_report)

3MF keeps units, colours and part names (bloch_q0_equator, bloch_q0_state_arrow, …), so multi-colour slicers can assign a filament per part. The report checks each part for closed, consistently oriented edges and measures the thinnest feature, size, volume and overhang share.

Publication figures

q.draw("c,b,a,e", "figure.pdf", preset="paper")                        # double column (7.16 in)
q.draw("a", "amps.png", preset="paper", column="single")               # 3.5 in, 600 dpi
q.draw("a,d", "bw.pdf", preset="paper", palette="grayscale")           # prints in black and white
print(q.last_caption)                                                    # also in figure.caption.txt

The paper preset uses serif (STIX) type, removes the dashboard header, scales lines and fonts to the real page size (never below 6 pt), uses a colour-blind-safe palette by default and writes a caption generated from the run: what is shown, the gates, exact versus sampled data and the version.

Research bundles

q = hdqs(2, seed=42).h(0).cx(0, 1)
q.export_bundle("bell_experiment")          # a folder, or "bell.zip"
hdqs.grover(3, ["101"], seed=3).export_bundle("grover.zip")

The two kinds of bundle differ, because an algorithm is told in stages rather than one figure:

Register bundle (q.export_bundle) Algorithm bundle (r.export_bundle)
Figures figure.pdf, figure.svg (paper preset), figure.caption.txt stages.pdf (one page per stage), summary.png (the answer)
Data data.json, data.csv: state, probabilities, Bloch vectors, entanglement data.json: every recorded stage
Circuit circuit.qasm, circuit.tex circuit.qasm, circuit.tex (sections boxed)
Re-run experiment.py: the hdqs chain with its seed experiment.py: the one-line algorithm call plus the explicit circuit
Interactive explorer.html player.html (live player)
Record metadata.json, environment.txt, README.md the same, with the algorithm's inputs and result

metadata.json holds the engine version, seed, shots, mode, inputs, circuit hash and the provenance of every file.

In notebooks

In Jupyter and VS Code a register or algorithm result shows itself: a summary card with the interactive explorer (or live player) embedded, no .draw() needed. hdqs.rich_display(False) switches it off.

Browser playground

hdqs.playground("playground.html")          # an empty playground with examples
hdqs.playground("mine.html", q)             # starts from q.code()

One offline HTML file with an editor that runs hdqs chains in the browser: gates, measure, if_x/if_z, unitary, load_state, for loops, lists, complex numbers and print, up to 10 qubits. The circuit, amplitudes, Bloch spheres, Q-sphere and entanglement update with a gate-by-gate slider, and errors point at the line. The same code runs unchanged in Python. Algorithm players have a Playground tab too: Edit & run in the playground loads r.code().

Algorithm visuals: how it works, not just the circuit

Every algorithm returns its usual result dictionary, which now also has .draw(), .code() and .circuit. The animation explains the idea behind the algorithm using the states recorded during that very run, so every picture matches the returned numbers, and it changes with whatever inputs you give it.

from sia import hdqs

r = hdqs.grover(3, ["101"])
r.draw("grover.gif")              # the circuit, then inversion about the mean and the rotation picture
r.draw("grover.html")             # live player: change the inputs and re-run, right in the browser
r.draw("grover.png", summary=True)   # one slide with the answer
r.code()                          # the hdqs chain that builds this run's circuit
r.draw("grover.tex")              # the circuit in LaTeX, sections boxed (standalone=False: bare environment)
r.lesson("grover.html")           # predict, then reveal: a question before each key stage
r.worksheet("grover.pdf")         # printable worksheet with a solutions page
r.export_frames("frames", "svg")  # every stage as a numbered image

Each animation opens with the circuit built for your input, with the oracle and other parts labelled. Grover, Deutsch–Jozsa and Simon use real gate-level oracles (X gates around a multi-controlled Z; one Z per bit when f is linear; CNOT copies for Simon). r.code() prints that circuit as a runnable one-import chain (repeated Grover iterations become a loop), and r.circuit is the program itself.

The last frame carries a result banner (FOUND 101, 15 = 3 × 5, ABORT · QBER 25%) and every panel says where its numbers come from: EXACT (from the state), SAMPLED (measurement shots), CLASSICAL (ordinary computation) or THEORY (a formula).

Algorithm What the animation shows
grover Amplitudes reflected about the mean, the 2D rotation picture with its mirrors, success probability
deutsch, deutsch_jozsa Phase kickback turning f(x) into signs, then interference deciding constant vs balanced
bernstein_vazirani Each oracle CNOT flipping one qubit to |−⟩; Hadamards turning the phases into the hidden bits
simon Equations y·s = 0 accumulating while the candidate secrets are crossed out
qft_demo Output qubits turning at ½, ¼, ⅛ … turn per +1, and the output phasors
phase_estimation Kickback onto each counting qubit, the outcome distribution sharpening with precision
order_finding, shor_demo The period of aˣ mod N, QPE peaks at s/r, continued fractions, gcd to the factors
teleport Three Bloch spheres, entanglement links, two classical bits travelling, Bob's correction
superdense Alice's operation choosing one of four Bell states, Bob decoding two bits
vqe Energy converging towards the exact ground energy, the path over the energy landscape
qaoa_maxcut The (γ, β) landscape search, sampled cut sizes, the best cut drawn on the graph
bb84, e91, qss Bases and photons, sifting and the QBER alarm; the CHSH value passing 2; GHZ parity
repetition_code_demo Encoding, a bit flip, the syndrome lighting up, correction and decoding
interference_report (CRIA) Interference recovered as more helper qubits are read
Extension Output Needs
.html Live player: plays the run; the reader can change the inputs and re-run the algorithm in the browser (a built-in simulator, no internet, no Python); Code and Playground tabs; light/dark; SVG and JSON download —
.gif Animation (speed=, tween= for in-between frames) —
.png .jpg .webp Storyboard of every stage, one stage with scene=k, or one slide with summary=True —
.pdf One page per stage —
.json The recorded stages as data —
.tex The executed circuit as LaTeX quantikz, sections as labelled boxes —
.mp4 Video, when ffmpeg is installed ffmpeg

Teaching. r.lesson("x.html") turns the live player into a lesson: before each key stage the student predicts what happens (multiple choice, built from this run's numbers), reads why, and only then sees the stage; the inputs tab unlocks at the end. r.worksheet("x.pdf") prints the same questions on A4 with the stage before each one, answer space and a solutions section (solutions=False for the student copy).

The recording costs only a few numbers per stage; the pictures are made when .draw() is called. In the browser player, a seed gives a repeatable run, but sampled results use the browser's own random numbers, not Python's.

Interoperability

OpenQASM 3 via hdqs.from_qasm3(source) and q.to_qasm3(). Optional adapters: hdqs.to_qiskit, hdqs.run_aer, hdqs.to_pennylane.

HDQS server client

The same hdqs name reaches the HDQS quantum server. A whole number builds the local simulator; any other call connects to the server:

from sia import hdqs

client = hdqs(api_key="YOUR_TOKEN")
client.qbt_create(num_qubits=2)
client.qbt_run(["h 0", "cnot 0 1"])
print(client.qbt_measure([0, 1]))

An API token is issued by Sia Software Innovations. The server address can be changed without reinstalling, using the SIA_HDQS_HOST and SIA_HDQS_PORT environment variables. If the server is unreachable, client calls raise hdqs.HDQSError; the offline simulator is unaffected.

Entities: ntt

from sia import ntt

Person = ntt("name", "age").computed("group", "if (1) > 17: adult | else: minor")
p = Person("Ravi", 20)
print(p.name, p.group)          # Ravi adult

Templates refer to attributes by position, (0), (1), and so on. Conditions and validators are evaluated through a restricted expression checker, never eval.

Enterprise logic: els

from sia import els

program = """
*sia
  DATA total TYPE I.
  total = 40 + 2.
  WRITE total.
sia*
"""
print(els(program))             # 42

For multi-block programs, share state with env = els.make_env() and call els(block, env). An interactive prompt is available through els.repl().

Optional dependencies

Extra Installs Enables
torch PyTorch Trainable layers, CUDA acceleration
scipy SciPy Sparse observable matrices
interop Qiskit, Qiskit Aer, PennyLane Adapters
full torch, scipy Everything except the adapters
all Everything above Everything

Matplotlib and openqasm3 are regular dependencies since 1.5.4; the old [plot] and [qasm] extras still install without error.

A feature whose dependency is missing raises an ImportError naming the package to install. hdqs.capabilities() reports what is available.

Conventions

  • Qubit 0 is the most significant bit: in '01', qubit 0 is 0. Qiskit uses the opposite order; the adapters convert automatically.
  • measure() collapses the state; sample() and probabilities() do not.
  • Memory grows exponentially with qubit count in the statevector and density-matrix modes. Above the 1 GiB default budget a register becomes program-only (q.is_lazy): use q.stabilizer() or q.mps(), or pass max_memory_mb= to allow a larger full state.

Licensing

sia-script is proprietary software of Sia Software Innovations Private Limited, with one exception: the quantum simulator, sia/hdqs_engine.py, is released under the MIT License. See LICENSE.md for the full terms of both.

Citation

If you use the CRIA interference-accessibility tools in research, please cite:

Seshabattara Venkata, N. S. D. N. Cardinality-Resolved Interference Accessibility in Multipartite Quantum Systems. Zenodo (2026). https://doi.org/10.5281/zenodo.23180889

Support

Sia Software Innovations Private Limited
Email: info@siasoftwareinnovations.com
Website: https://www.siasoftwareinnovations.com

Metadata

Release files for sia-script 1.5.5

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for sia-script 1.5.5
File Size Uploaded
sia_script-1.5.5.tar.gz 327.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for sia-script 1.5.5
File Interpreter ABI Platform
sia_script-1.5.5-py3-none-any.whl Python 3 none any Details

Total release size: 645.3 kB

Release files / sia_script-1.5.5.tar.gz

Download URL sia_script-1.5.5.tar.gz
Size 327.1 kB
Tags Source
SHA-256 checksum
How to use checksums
0cebebeac7830eb4a5c6077bd69de4202f0d2e1ff60ad92981b8302f90f05bb9
BLAKE2b-256 checksum
How to use checksums
27840b16e2cec0086e5a2cc77f13de360ae603649fb180847bc40972c447191e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.4

Release files / sia_script-1.5.5-py3-none-any.whl

Download URL sia_script-1.5.5-py3-none-any.whl
Size 318.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
af18260f062847a6980ffdc7c933c78b246d6c6ea0aaf0f5a10db8668319a7d5
BLAKE2b-256 checksum
How to use checksums
2032c4820629ab637541e68774f2d757c1614926b77626b0e4b31ca41b6b69fe
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/6.2.0 CPython/3.13.4

Release history Release notifications | RSS feed

1.5.7

2 release files

1.5.6

2 release files

This release

1.5.5 This release

2 release files

1.5.4

2 release files

1.5.3

2 release files

1.5.2

2 release files

1.5.1

2 release files

1.3.0

2 release files

1.1.0

2 release files

1.0.3

2 release files

1.0.2

2 release files

1.0.0

2 release files

0.8.7

2 release files

0.8.6

2 release files

0.8.5

2 release files

0.8.4

2 release files

0.8.3

2 release files

0.8.2

2 release files

0.8.1

2 release files

0.8.0

2 release files

0.7.0

2 release files

0.6.9

2 release files

0.6.7

2 release files

0.6.6

2 release files

0.6.5

2 release files

0.6.4

2 release files

0.6.3

2 release files

0.6.2

2 release files

0.6.1

2 release files

0.6.0

2 release files

0.5.9

2 release files

0.5.8

2 release files

0.5.7

2 release files

0.5.4

2 release files

0.5.3

2 release files

0.5.2

2 release files

0.5.1

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.0

2 release files

0.2.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page