Core quaternion, spinor, SU(2), and Bloch mathematics for the RQM Python ecosystem.
This repository is part of the RQM Technologies ecosystem.
→ Website: https://rqmtechnologies.com
→ Documentation: https://docs.rqmtechnologies.com
pip install rqm-corerqm-core is the mathematical foundation layer. It has no RQM-level dependencies — only numpy at runtime.
rqm-core → rqm-circuits → rqm-compiler → rqm-qiskit / rqm-braket
↓ (optional)
rqm-optimize
rqm-core provides the canonical mathematical layer of the RQM ecosystem —
quaternion, spinor, Bloch, and SU(2) foundations. It owns no circuit schema,
no compiler passes, and no backend execution logic.
Layer responsibilities:
| Package | Role |
|---|---|
| rqm-core | Mathematical spine — quaternion, spinor, SU(2), Bloch, coupling analysis |
| rqm-circuits | Canonical external circuit IR / wire format (API, Studio, interchange) |
| rqm-compiler | Optimization and rewriting engine — consumes rqm-circuits programs |
| rqm-qiskit | IBM / Qiskit lowering and execution bridge |
| rqm-braket | AWS / Braket lowering and execution bridge |
| rqm-optimize | Optional backend-adjacent optimization / compression layer |
rqm-circuits 0.2 is the canonical external circuit format for all API and Studio workflows.
rqm-compiler consumes and optimizes circuit programs but is not the primary public wire format.
Backend packages (rqm-qiskit, rqm-braket) translate optimized circuits into vendor-native objects.
rqm-optimize is optional and sits later in the execution flow, above the backend bridges.
- Documentation: https://docs.rqmtechnologies.com
- Website: https://rqmtechnologies.com
- Next package in the stack:
rqm-circuits— the canonical external circuit IR for API and Studio workflows (rqm-circuits 0.2+) - After circuits:
rqm-compiler— optimization and rewriting engine
Higher-level RQM libraries (simulators, compilers, hardware adapters) all require a
common, reliable layer of linear algebra and quantum geometry. rqm-core is that layer.
It provides a single, versioned source of truth for the mathematical primitives shared across the whole ecosystem: no duplication, no conflicting conventions, and no framework lock-in.
| Principle | What it means in practice |
|---|---|
| Tiny | Only implement primitives that are needed by ≥2 packages |
| Stable | Slow to change; breaking changes require a major version bump |
| Dependency-light | Only numpy at runtime |
| Canonical | One correct convention, clearly documented, used everywhere |
| Well-tested | Strong test coverage from the first commit |
- Quaternion primitives – Hamilton product, conjugate, inverse, axis-angle construction, SO(3) and SU(2) conversions
- Spinor helpers – normalization, norm, fidelity, spinor↔quaternion/SU(2) mappings
- SU(2) conversions – construction from quaternions and axis-angle, validation, round-trips
- Bloch sphere mappings – state↔Bloch, Bloch↔state, quaternion rotation to Bloch vector
- Matrix helpers – trace, determinant, conjugate transpose (dagger), norm, closeness checks
- Validation utilities – axis, complex pair, matrix shape, real number, tolerance checks
- Coupling / entanglement analysis – qualitative gate detection and measured 2-qubit entanglement metrics (concurrence, entropy, fidelity); see the Coupling Analysis section below
The full reference lives in CONVENTIONS.md.
The five items every downstream package needs to know:
A unit quaternion q = w + xi + yj + zk maps to SU(2) as:
U(q) = [[ w − iz , −y − ix ],
[ y − ix , w + iz ]]
Implemented in Quaternion.to_su2_matrix(); inverted by su2_to_quaternion().
States are written |ψ⟩ = α|0⟩ + β|1⟩ with |0⟩ as the north-pole
computational-basis ground state. Amplitudes are always passed as the ordered
pair (alpha, beta). Functions that require unit norm normalize internally.
|ψ⟩ = cos(θ/2)|0⟩ + e^{iφ} sin(θ/2)|1⟩
theta ∈ [0, π] (polar/colatitude), phi ∈ [0, 2π) (azimuthal).
|0⟩ → north pole (0, 0, +1); |1⟩ → south pole (0, 0, −1).
q and −q represent the same rotation. spinor_to_quaternion encodes
the rotation up to global phase — never rely on the sign of the scalar part.
All closeness checks default to atol = 1e-9 (absolute, no relative
component). Axis labels are "x", "y", "z" (case-insensitive);
all angles are in radians.
rqm_core includes an additive, production-ready analysis layer for measuring and qualifying multi-qubit coupling and entanglement.
The two layers are mathematically complementary and do not compete:
| Layer | Scope | Technology |
|---|---|---|
| Single-qubit local structure | Individual qubit rotations | Quaternionic / SU(2) (quaternion optimizer) |
| Multi-qubit entanglement | Cross-qubit coupling / correlation | Statevector simulation, concurrence, entropy |
The quaternionic single-qubit optimizer is the correct route for local SU(2) operations. The coupling analysis layer adds truthful multi-qubit analysis beside it.
from rqm_core import Circuit, GateOp, analyze_circuit_coupling
# Bell state: H q0, CNOT q0→q1
circuit = Circuit(
num_qubits=2,
operations=[
GateOp(name="H", qubits=[0]),
GateOp(name="CNOT", qubits=[0, 1]),
],
)
result = analyze_circuit_coupling(circuit)
print(result.mode) # "measured"
print(result.is_entangled) # True
print(result.pair_metrics[0].value) # 1.0 (concurrence)| Criterion | Scope |
|---|---|
| Qubits | Exactly 2 |
| Initial state | |00⟩ |
| Single-qubit gates | I, X, Y, Z, H, S, T, Rx(θ), Ry(θ), Rz(θ), U(θ,φ,λ) / U3 |
| Two-qubit gates | CNOT / CX, CZ, SWAP |
| Metrics | Concurrence, von Neumann entropy |
Circuits outside this scope receive an honest qualitative fallback (gate detection only) with explicit limitations in the result — no fabricated measured values.
@dataclass
class CouplingAnalysisResult:
mode: str # "measured" | "qualitative"
provenance: str # "rqm-core" | "parser"
qubit_count: int
analyzed_pairs: list[tuple[int, int]]
has_entangling_gates: bool
entangling_gate_count: int
entangling_gates_seen: list[str]
last_entangling_gate: str | None
is_entangled: bool | None # None in qualitative mode
pair_metrics: list[PairMetric] # empty in qualitative mode
fidelity_preserved: float | None
notes: list[str]
limitations: list[str]from rqm_core import analyze_optimization_preservation
result = analyze_optimization_preservation(original_circuit, optimized_circuit)
print(result.fidelity_preserved) # e.g. 1.0
print(result.preserved_entanglement_structure) # True / False / Nonerqm-core intentionally does not own:
- Qiskit / PennyLane / Cirq adapters
- Backend execution or hardware drivers
- Circuit transpilation or compilation
- Plotting or visualisation
- Cloud workflow integration
- Notebook tooling
- Algorithm frameworks or optimisation workflows
Those belong in higher-level packages.
pip install rqm-coreDevelopment install (includes pytest and pytest-cov):
pip install "rqm-core[dev]"rqm-core is the mathematical spine of the RQM Python ecosystem. It provides the
single canonical implementation of all shared mathematical primitives so that
downstream packages never need to re-implement or copy them.
What rqm-core owns:
- Quaternion primitives (Hamilton product, conjugate, inverse, axis-angle, SO(3)/SU(2) conversions)
- SU(2) / Bloch / spinor mathematics
- Shared linear algebra helpers
- Coupling / entanglement analysis primitives
What rqm-core does NOT own:
- Circuit IR or schema — that is
rqm-circuits - Compiler rewrites or optimization passes — that is
rqm-compiler - Backend execution or vendor-native objects — that is
rqm-qiskit/rqm-braket - API service boundaries or Studio wire formats — those live above
rqm-circuits
How downstream packages declare the dependency (example pyproject.toml excerpt):
[project]
dependencies = [
"rqm-core>=0.1.0",
]How downstream packages import:
# rqm-qiskit, rqm-circuits, rqm-compiler, etc.
from rqm_core import Quaternion, axis_angle_to_su2, state_to_blochContract for downstream maintainers:
- All conventions are defined in
CONVENTIONS.mdand must not be re-defined or overridden locally. - Breaking changes to
rqm-corerequire a major version bump (1.0.0, …). - Any primitive needed by two or more packages belongs here, not in the individual packages.
from rqm_core import Quaternion, state_to_bloch, axis_angle_to_su2
import math
# 90° rotation around Y
q = Quaternion.from_axis_angle("y", math.pi / 2)
print(q)
# Quaternion(0.7071..., 0.0, 0.7071..., 0.0)
# SU(2) matrix directly from axis-angle
print(axis_angle_to_su2("y", math.pi / 2))
# |+⟩ state on the Bloch sphere → equator at (1, 0, 0)
c = 1 / math.sqrt(2)
x, y, z = state_to_bloch(c, c)
print(x, y, z) # 1.0 0.0 0.0rqm-core/
CONVENTIONS.md – canonical mathematical conventions reference
pyproject.toml – package metadata and build config
src/rqm_core/
__init__.py – canonical public API (import everything from here)
py.typed – PEP 561 marker (enables type checking in downstream packages)
quaternion.py – Quaternion class (Hamilton algebra, SO(3)/SU(2) conversions)
spinor.py – spinor normalization, fidelity, spinor↔quaternion/SU(2)
su2.py – SU(2) construction, validation, quaternion round-trips
bloch.py – Bloch sphere mappings and validation
linalg.py – matrix helpers (dagger, trace, determinant, closeness)
validation.py – shared validation helpers (axis, matrix shape, tolerances)
types.py – shared type aliases (ComplexVector2, BlochVector, SU2Matrix, …)
utils.py – small math utilities (angle_wrap, safe_norm, is_finite_*)
analysis/
coupling/
types.py – Circuit IR + result contract dataclasses
detect_entangling_structure.py – qualitative gate-based detection
simulate_two_qubit_state.py – ideal 2-qubit pure-state simulator
metrics.py – concurrence, entropy, fidelity helpers
analyze_circuit_coupling.py – main public entry point
analyze_optimization_preservation.py – before/after compiler verification
tests/
test_quaternion.py
test_spinor.py
test_su2.py
test_bloch.py
test_linalg.py
test_utils.py
test_validation.py
test_public_api.py
analysis/
coupling/
test_detect_entangling_structure.py
test_simulate_two_qubit_state.py
test_metrics.py
test_analyze_circuit_coupling.py
test_analyze_optimization_preservation.py
examples/
quaternion_basics.py – quaternion construction, composition, conversion
spinor_basics.py – spinor normalization, Bloch mapping, fidelity
su2_bloch_demo.py – axis-angle → SU(2) → Bloch pipeline
bloch_mapping_demo.py – canonical Bloch vectors and round-trip checks
su2_rotation_demo.py – SU(2) construction and quaternion round-trip
# Install the package in editable mode with test dependencies
pip install -e ".[dev]"
# Run the full test suite
pytest
# Run with coverage report
pytest --cov=rqm_core --cov-report=term-missing
# Run a single test file
pytest tests/test_quaternion.py -v
# Run only the public-API contract tests
pytest tests/test_public_api.py -v-
su2.is_unitaryis a thin domain-scoped shim overlinalg.is_unitary. Both exist intentionally:linalg.is_unitaryis the general-purpose helper;su2.is_unitaryis the public entry point for SU(2)-context callers and is whatrqm_core.is_unitaryresolves to in the top-level API. -
qand−qrepresent the same rotation. Round-trip conversionsq → SU(2) → qare tested against bothqand−q. Downstream code must never compare quaternion scalar parts for sign equality. -
The
src/layout meansrqm_coreis only importable after installation (pip install -e .). Running tests directly without installing first will produceModuleNotFoundError. -
py.typedis included in the installed wheel (via[tool.setuptools.package-data]), enablingmypyandpyrightin any package that depends onrqm-core.
rqm-core is intended to remain small and stable while higher-level packages evolve around it.
Planned additions for future minor versions:
- Quaternion SLERP (spherical linear interpolation)
- SO(3) rotation-matrix ↔ quaternion round-trip helpers
- Mixed-state density matrix utilities
- SU(2) Lie-algebra generators and exponential map
- Type stub files (
.pyi) for IDE completions - Coupling analysis for >2 qubits (partial trace for n-qubit systems, mutual information)
- Support for additional gate sets in the 2-qubit simulator
No Qiskit or framework dependencies will ever be added to this package.