rqm-circuits
Canonical external circuit IR for the RQM Technologies quantum software stack.
What is rqm-circuits?
rqm-circuits is the single source-of-truth wire format for API and Studio
traffic in the RQM Technologies quantum software stack. It defines the canonical
circuit object model that sits between the quaternion math layer and the internal
optimization engine.
Architecture
rqm-core – quaternion/math foundation
rqm-circuits – canonical external circuit IR ← you are here
rqm-compiler – internal optimization / canonicalization engine
rqm-qiskit – Qiskit translation/execution bridge
rqm-braket – Amazon Braket translation/execution bridge
rqm-api – hosted API (accepts rqm-circuits JSON payloads)
Studio – visual circuit editor (emits rqm-circuits JSON payloads)
Key roles:
rqm-circuits= canonical external circuit IR. API payloads and Studio traffic userqm-circuitsas the wire format. The JSON representation is versioned and stable.rqm-compiler= internal engine. Compiler descriptors are internal; they are not the public API payload.rqm-circuitsis lightweight and backend-neutral: no dependency on Qiskit, Braket, orrqm-compiler.
What it is NOT
- Not a backend adapter
- Not a transpiler to Qiskit / Braket / PennyLane
- Not a simulator
- Not a quaternion math library (
rqm-corehandles that) - Not the compiler's internal IR (
rqm-compilerhas its own descriptor types)
Quaternion connection
Every single-qubit SU(2) gate can be represented exactly as a unit quaternion
q = cos(θ/2) + u·sin(θ/2)
where u is the unit pure-imaginary quaternion (rotation axis) and θ is the
physical Bloch-sphere rotation angle. rqm-circuits annotates each standard
gate with its quaternion form (gate.quaternion_form) as an informational field.
The mathematical evaluation of those forms lives in rqm-core.
Rx(angle) → q = cos(angle/2) + i·sin(angle/2)
Ry(angle) → q = cos(angle/2) + j·sin(angle/2)
Rz(angle) → q = cos(angle/2) + k·sin(angle/2)
H → q = (i+k)/√2 (π-rotation about (x̂+ẑ)/√2)
X → q = i (π-rotation about x̂)
Y → q = j (π-rotation about ŷ)
Z → q = k (π-rotation about ẑ)
phaseshift(angle) has matrix diag(1, exp(i·angle)); its quaternion metadata
uses the determinant-one Rz(angle) representative, which is equivalent up to
global phase.
The universal single-qubit gate u1q is parameterised directly by the unit
quaternion components (w, x, y, z):
u1q(w, x, y, z) → q = w + xi + yj + zk (|q| = 1)
Standard two-qubit interaction rotations use the same half-angle convention:
c = Circuit(num_qubits=2)
c.rxx(0.25, 0, 1)
c.ryy(0.50, 0, 1)
c.rzz(0.75, 0, 1)
Their matrices are exp[-i·angle·P/2] for P = X⊗X, Y⊗Y, or Z⊗Z.
These families are entangling-capable, but a nonzero angle—especially for
rzz—does not imply that every input state becomes entangled.
Standard-Compatible Quaternion Coordinates
A complete quaternion and a complete conventional complex/SU(2) or matrix representation carry the same transformation information. RQM uses quaternions because they make ordered rotation composition, inverses, normalization, sign handling, residuals, canonicalization, and lowering explicit in one structured coordinate system.
Any claimed benefit must come from a measured implementation or workflow—not from additional physics or information in the representation. This package does not claim unique measurement, tomography, hardware-error, compression, or universal compiler advantages.
Install
pip install rqm-circuits
Or for development:
git clone https://github.com/RQM-Technologies-dev/rqm-circuits.git
cd rqm-circuits
pip install -e ".[dev]"
Quick start
Bell circuit
from rqm_circuits import Circuit, make_instruction
# Create a 2-qubit Bell circuit
c = Circuit(num_qubits=2, name="bell")
c.add(make_instruction("h", targets=[0]))
# cx: supply the control qubit via controls=, the target via targets=
c.add(make_instruction("cx", targets=[1], controls=[0]))
print(c.summary())
# Circuit 'bell': 2 qubit(s), 0 clbit(s), 2 instruction(s)
# [ 0] h q[0]
# [ 1] cx ctrl:q[0] q[1]
GHZ circuit
from rqm_circuits import Circuit, make_instruction
n = 3
c = Circuit(num_qubits=n, name="ghz")
c.add(make_instruction("h", [0]))
for i in range(1, n):
c.add(make_instruction("cx", targets=[i], controls=[0]))
Rotation gate with a parameter
import math
from rqm_circuits import Circuit, make_instruction, Parameter
c = Circuit(num_qubits=1, name="rotation")
# Canonical parameter name for all rotation gates is "angle"
c.add(make_instruction("rx", targets=[0], params=[Parameter("angle", value=math.pi / 2)]))
Phase-shift gate
from rqm_circuits import Circuit, make_instruction, Parameter
c = Circuit(num_qubits=1)
c.add(make_instruction("phaseshift", targets=[0], params=[Parameter("angle", value=0.5)]))
Universal single-qubit gate (u1q)
import math
from rqm_circuits import Circuit, make_instruction, Parameter
# Hadamard expressed as a unit quaternion
norm = 1.0 / math.sqrt(2)
c = Circuit(num_qubits=1)
c.add(make_instruction(
"u1q", targets=[0],
params=[
Parameter("w", value=0.0),
Parameter("x", value=norm),
Parameter("y", value=0.0),
Parameter("z", value=norm),
],
))
Symbolic (unbound) parameter
c = Circuit(num_qubits=1)
c.add(make_instruction("rz", targets=[0], params=[Parameter("angle")]))
from rqm_circuits import is_parametric
print(is_parametric(c)) # True
Measurement
c = Circuit(num_qubits=1, num_clbits=1)
c.add(make_instruction("x", targets=[0]))
c.add(make_instruction("measure", targets=[0], clbits=[0]))
JSON serialization
rqm-circuits is designed as an API-ready IR layer. Every circuit serializes
to a clean, deterministic JSON payload (schema version "0.2").
from rqm_circuits import Circuit, make_instruction
c = Circuit(num_qubits=2, name="bell")
c.add(make_instruction("h", [0]))
c.add(make_instruction("cx", targets=[1], controls=[0]))
# Serialize
json_str = c.to_json()
print(json_str)
# Deserialize
c2 = Circuit.from_json(json_str)
assert c == c2
Example JSON output:
{
"instructions": [
{
"gate": {
"arity": 1,
"categories": ["clifford", "single_qubit"],
"description": "Hadamard gate. π-rotation about the (x+z)/√2 axis.",
"name": "h",
"num_params": 0,
"quaternion_form": "q = (i+k)/√2 (axis = (x̂+ẑ)/√2, angle = π)"
},
"targets": [{"index": 0, "type": "qubit"}]
},
{
"controls": [{"index": 0, "type": "qubit"}],
"gate": {
"arity": 1,
"categories": ["clifford", "two_qubit"],
"description": "Controlled-X (CNOT) gate. One control qubit, one target qubit.",
"name": "cx",
"num_controls": 1,
"num_params": 0
},
"targets": [{"index": 1, "type": "qubit"}]
}
],
"name": "bell",
"num_qubits": 2,
"schema_version": "0.2"
}
Schema versioning
| Version | Description |
|---|---|
"0.1" |
Legacy. Controlled gates encoded as arity-2 with both qubits in targets. |
"0.2" |
Current. Controlled gates use arity=1, num_controls=1, explicit controls list. Gates include phaseshift, u1q, rxx, ryy, rzz. Canonical rotation param name "angle". |
Schema "0.1" payloads are accepted on ingestion and transparently normalized.
Adding the Pauli-pair rotations is backward-compatible, so no existing payload
shape or accepted schema version changes.
IR analysis helpers
from rqm_circuits import (
circuit_depth,
gate_counts,
has_measurements,
is_parametric,
qubit_usage,
filter_by_category,
GateCategory,
)
print(circuit_depth(c)) # 2
print(gate_counts(c)) # {'cx': 1, 'h': 1}
print(has_measurements(c)) # False
print(is_parametric(c)) # False
print(qubit_usage(c)) # {0: [0, 1], 1: [1]}
Standard gate set
| Gate | Arity | Controls | Params | Param names | Category | Quaternion form |
|---|---|---|---|---|---|---|
i |
1 | 0 | 0 | — | Clifford | q = 1 |
x |
1 | 0 | 0 | — | Clifford | q = i |
y |
1 | 0 | 0 | — | Clifford | q = j |
z |
1 | 0 | 0 | — | Clifford | q = k |
h |
1 | 0 | 0 | — | Clifford | q = (i+k)/√2 |
s |
1 | 0 | 0 | — | Clifford | q = cos(π/4) + k·sin(π/4) |
t |
1 | 0 | 0 | — | Non-Clifford | q = cos(π/8) + k·sin(π/8) |
rx |
1 | 0 | 1 | angle |
Rotation | q = cos(angle/2) + i·sin(angle/2) |
ry |
1 | 0 | 1 | angle |
Rotation | q = cos(angle/2) + j·sin(angle/2) |
rz |
1 | 0 | 1 | angle |
Rotation | q = cos(angle/2) + k·sin(angle/2) |
rxx |
2 | 0 | 1 | angle |
Rotation, two-qubit, entangling-capable | exp[-i angle XX/2] |
ryy |
2 | 0 | 1 | angle |
Rotation, two-qubit, entangling-capable | exp[-i angle YY/2] |
rzz |
2 | 0 | 1 | angle |
Rotation, two-qubit, entangling-capable | exp[-i angle ZZ/2] |
phaseshift |
1 | 0 | 1 | angle |
Rotation | q = cos(angle/2) + k·sin(angle/2) (up to global phase) |
u1q |
1 | 0 | 4 | w,x,y,z |
— | q = w + xi + yj + zk |
cx |
1 | 1 | 0 | — | Clifford | — |
cy |
1 | 1 | 0 | — | Clifford | — |
cz |
1 | 1 | 0 | — | Clifford | — |
swap |
2 | 0 | 0 | — | Clifford | — |
iswap |
2 | 0 | 0 | — | — | — |
measure |
1 | 0 | 0 | — | Measurement | — |
barrier |
* | 0 | 0 | — | Directive | — |
Controlled gates (
cx,cy,cz): supply the control qubit viacontrols=[{"index": ctrl}]and the target qubit viatargets=[{"index": tgt}]. The legacy encoding (both qubits intargets, arity=2) is still accepted on ingestion for schema"0.1"backward compatibility.
Rotation gates (
rx,ry,rz,phaseshift,rxx,ryy,rzz): the canonical parameter name is"angle". Legacy names"theta"and"phi"are silently normalized to"angle"on ingestion.
Package layout
src/rqm_circuits/
__init__.py Public API surface
circuit.py Circuit class
gates.py Gate definitions + standard registry
instructions.py Instruction model + make_instruction()
registers.py QubitRef / ClassicalBitRef
params.py Parameter (concrete + symbolic)
validators.py Validation rules
serialization.py JSON helpers + schema versioning
ir.py IR analysis utilities
errors.py Custom exceptions
types.py Type aliases and enumerations
schema.py JSON Schema + TypedDict definitions
tests/
test_circuit.py
test_gates.py
test_serialization.py
test_validation.py
test_schema.py
test_new_features.py
Error handling
All errors are structured and human-readable:
| Exception | When raised |
|---|---|
CircuitValidationError |
Invalid qubit indices, circuit structure, wrong clbit usage |
InstructionError |
Wrong arity, parameter count/name, duplicate targets, missing controls |
GateDefinitionError |
Unknown gate, invalid gate definition |
SerializationError |
Missing fields, wrong schema version, bad JSON |
Breaking changes (schema 0.1 → 0.2)
| Change | Schema 0.1 | Schema 0.2 |
|---|---|---|
cx/cy/cz arity |
2 (both qubits in targets) |
1 (target in targets, control in controls) |
| Rotation param name | "theta" or "phi" |
"angle" (legacy normalized on ingestion) |
| New gates | — | phaseshift, u1q |
Gate fields |
name, arity, num_params |
+ num_controls, param_names |
Schema "0.1" payloads remain accepted on ingestion; they are transparently
normalized to the "0.2" internal representation.
Development
pip install -e ".[dev]"
pytest
License
Apache License 2.0 — see LICENSE.
Metadata
Release files for rqm-circuits 0.2.1
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| rqm_circuits-0.2.1.tar.gz | 49.9 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rqm_circuits-0.2.1-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 90.6 kB
Release files / rqm_circuits-0.2.1.tar.gz
| Download URL | rqm_circuits-0.2.1.tar.gz |
|---|---|
| Size | 49.9 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
ce01532219153607aa37502c720ac2df8014ba865cd8d6d873be5cfe15bc359b
|
|
BLAKE2b-256 checksum How to use checksums |
0c58cab611448b6c3aa7f38c19d08a89d0b9268b56f5330c2c6d48db70af8cf7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 29, 2026.
Transparency logRelease files / rqm_circuits-0.2.1-py3-none-any.whl
| Download URL | rqm_circuits-0.2.1-py3-none-any.whl |
|---|---|
| Size | 40.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0e8c367cc5f2374435631ab10a8837b100ac89bccb0a39801d2912cf14aadd3b
|
|
BLAKE2b-256 checksum How to use checksums |
452922aca051119b62b74e2edb6950a63edec1ff7302c968e422b9148bc4d717
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.14
|
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
PyPI Publish Attestation
PyPI verified that this artifact, at this checksum, originated from the publisher listed below.
Signed by GitHub Actions, verified by PyPI on Jul 29, 2026.
Transparency log