Skip to main content

Thin Qiskit bridge layer for the RQM quantum ecosystem

Project description

rqm-qiskit

Thin Qiskit bridge layer for the RQM quantum ecosystem — translates canonical RQM circuits and gates (owned by rqm-compiler) into Qiskit primitives and runs them on Aer simulators or IBM Quantum hardware.


Architecture

rqm-qiskit occupies a single, well-defined layer in the RQM dependency spine:

rqm-core        (canonical math: Quaternion, SU(2), Bloch, spinor)
       ↓
rqm-compiler    (canonical gate/circuit IR: Circuit, Operation, compilation)
       ↓
rqm-qiskit      (Qiskit bridge: circuit lowering, IBM execution helpers)
       ↓
[rqm-optimize]  (optional: circuit optimization — see Optimization section)
       ↓
rqm-notebooks   (interactive notebooks and tutorials)

The full pipeline with optional optimization:

compile → lower → optimize → run

Layer responsibilities

Package Responsibility
rqm-core Quaternion algebra, SU(2) matrices, Bloch conversions, spinor helpers
rqm-compiler Canonical gate/circuit IR (Circuit, Operation), normalization, compilation pipeline
rqm-qiskit Lower rqm-compiler IR to Qiskit QuantumCircuit; Aer/IBM execution helpers; thin user-facing wrappers
rqm-notebooks Jupyter notebooks, tutorials, interactive demonstrations

What rqm-qiskit owns

  • compiled_circuit_to_qiskit() — the primary bridge: translates an rqm_compiler.Circuit or rqm_compiler.CompiledCircuit into a Qiskit QuantumCircuit.
  • RQMCircuit — a thin façade over rqm_compiler.Circuit that adds Qiskit-specific state preparation (initialize) and exposes .to_qiskit().
  • RQMGate — adds .to_operation() (→ rqm_compiler.Operation) and .to_qiskit_gate() (→ Qiskit gate object) on top of the rqm-core SU(2) matrix.
  • RQMState — adds Qiskit-facing helpers (.vector(), .as_statevector()) on top of rqm-core spinor/Bloch math.
  • run_on_aer_sampler() / IBM Runtime helpers in ibm.py.
  • Result formatting in results.py.

What rqm-qiskit does NOT own

rqm-qiskit does not implement canonical math. It delegates all math operations to rqm-core.

Specifically, rqm-qiskit contains no quaternion math, no spinor normalization, no Bloch conversions, and no SU(2) decomposition of its own. All canonical logic is delegated to rqm-core and rqm-compiler.

Architecture Guarantees

These invariants are stable and hold across all public helpers in this package:

Guarantee Detail
Canonical math lives in rqm-core Quaternion algebra, SU(2) matrices, Bloch-vector conversions, and spinor normalization are owned exclusively by rqm-core. rqm-qiskit never reimplements them.
Canonical circuit IR lives in rqm-compiler rqm_compiler.Circuit, rqm_compiler.Operation, and the compilation pipeline are the single source of truth for gate and circuit semantics.
compiled_circuit_to_qiskit() is the primary lowering path Every helper that converts a gate or circuit to a Qiskit QuantumCircuit routes through compiled_circuit_to_qiskit(). There is no second, parallel lowering path.
state_to_quantum_circuit() is the only documented exception State preparation uses Qiskit's initialize instruction, which has no equivalent in the rqm-compiler IR. It therefore cannot route through the main lowering path and is explicitly documented as the sole exception.

In practice this means:

  • RQMCircuit.to_qiskit() calls compiled_circuit_to_qiskit() internally.
  • gate_to_quantum_circuit() builds a 1-op rqm_compiler.Circuit and calls compiled_circuit_to_qiskit().
  • New helpers added in future versions must route through compiled_circuit_to_qiskit() unless there is an explicit, documented reason not to.

What Is This?

rqm-qiskit is a clean, beginner-friendly Python package that bridges rqm-compiler (the canonical RQM circuit layer) and Qiskit (the execution engine).

The key insight:

A single-qubit state lives on the Bloch sphere.
Rotations of the Bloch sphere are SU(2) transformations.
SU(2) is isomorphic to the group of unit quaternions.

Therefore, unit quaternions are the natural algebraic object for 1-qubit quantum states and gates. rqm-core owns that algebra; rqm-compiler owns circuit structure; rqm-qiskit exposes the geometry to Qiskit users and handles execution.

This package is not trying to replace Qiskit.
It is a thin bridge — Qiskit does all the heavy lifting under the hood.


Quaternion Intuition for Qubits

A unit quaternion q = w + x·i + y·j + z·k (with |q| = 1) corresponds to an SU(2) matrix via:

U = [[w − i·z,  −(y + i·x)],
     [y − i·x,   w + i·z  ]]

This means:

Operation Quaternion form
Identity (no rotation) q = 1
R_x(θ) q = cos(θ/2) + sin(θ/2)·i
R_y(θ) q = cos(θ/2) + sin(θ/2)·j
R_z(θ) q = cos(θ/2) + sin(θ/2)·k
Compose two gates q_total = q2 * q1 (right-to-left)

Every RQMGate exposes its quaternion property. Every RQMState exposes to_quaternion() — the rotation that prepares it from |0>.


Why Does This Exist?

  • Geometric intuition: unit quaternions make SU(2) rotations concrete and composable.
  • Quaternionic quantum mechanics: a foundation for richer RQM educational tooling.
  • Educational clarity: fewer raw matrix operations, more geometric understanding.
  • IBM Quantum ready: built on Qiskit so the path to real hardware is direct.

Installation

Install from PyPI:

pip install rqm-qiskit

To also run local simulations (recommended):

pip install "rqm-qiskit[simulator]"

For development:

git clone https://github.com/RQM-Technologies-dev/rqm-qiskit.git
cd rqm-qiskit
python -m venv .venv
source .venv/bin/activate
pip install -e ".[dev,simulator]"

Quickstart

from rqm_qiskit import RQMState, RQMGate, RQMCircuit

state = RQMState.plus()
gate = RQMGate.ry(0.6)

circ = RQMCircuit(1)
circ.prepare_state(state)
circ.apply_gate(gate)
circ.measure_all()

print(circ.draw_text())

Inspect the quaternion geometry:

# State as a unit quaternion
q_state = state.to_quaternion()
print(q_state.pretty())           # Quaternion(0.7071 +0.0000i +0.7071j +0.0000k)  |q| = 1.000000

# Gate as a unit quaternion
q_gate = gate.quaternion
print(q_gate.pretty())

# Compose two gates as a single quaternion product
gate2 = RQMGate.rz(0.3)
q_composed = gate2.quaternion * gate.quaternion  # apply gate first, then gate2
print(q_composed.to_su2_matrix())  # the combined 2×2 SU(2) matrix

Use the rqm-compiler circuit directly:

from rqm_compiler import Circuit, compile_circuit
from rqm_qiskit.convert import compiled_circuit_to_qiskit

# Build a backend-neutral circuit in rqm-compiler
c = Circuit(2)
c.h(0)
c.cx(0, 1)
c.measure(0)
c.measure(1)

# Lower to Qiskit
qc = compiled_circuit_to_qiskit(c)
print(qc.draw(output="text"))

Run on the local Aer simulator:

from rqm_qiskit import format_counts_summary
from rqm_qiskit.ibm import run_on_aer_sampler

counts = run_on_aer_sampler(circ.to_qiskit(), shots=1024)
print(format_counts_summary(counts))

Package Structure

rqm-qiskit/
  src/
    rqm_qiskit/
      quaternion.py  – Quaternion: thin shim re-exporting from rqm-core
      state.py       – RQMState: Qiskit-bridge wrapper over rqm-core spinor math
      gates.py       – RQMGate: dual-mode gate; re-exports gate factories from rqm-core
      circuit.py     – RQMCircuit: façade over rqm_compiler.Circuit + to_qiskit()
      convert.py     – compiled_circuit_to_qiskit(); state/gate convenience wrappers
      translator.py  – QiskitTranslator, compile_to_qiskit_circuit
      execution.py   – run_local, run_backend
      backend.py     – QiskitBackend: unified entry point
      result.py      – QiskitResult: structured result wrapper
      bridges.py     – spinor_to_circuit, bloch_to_circuit (bridge functions)
      results.py     – summarize_counts, format_counts_summary
      ibm.py         – Aer sampler helper + IBM Runtime stub
      utils.py       – internal utilities
  tests/             – pytest test suite (256 tests)
  examples/          – runnable example scripts
  AGENTS.md          – coding agent rules

Convenience Bridges

Two thin bridge functions map physical state representations to Qiskit circuits. All physics is delegated to rqm-core; these functions own only the gate mapping.

spinor_to_circuit(alpha, beta, target=0)

Converts a spinor (α, β) to a QuantumCircuit that prepares qubit target in the corresponding state.

Steps:

  1. Normalize (α, β) via rqm_core.spinor.normalize_spinor
  2. Convert to Bloch vector via rqm_core.bloch.state_to_bloch
  3. Map (θ, φ)RY(θ) RZ(φ) Qiskit gates
from rqm_qiskit import spinor_to_circuit
import math

s = 1 / math.sqrt(2)
qc = spinor_to_circuit(s + 0j, s + 0j)   # |+⟩ state
print(qc.draw())

bloch_to_circuit(theta, phi, target=0)

Converts Bloch angles (θ, φ) directly to a QuantumCircuit:

  • RY(θ) sets the polar angle
  • RZ(φ) sets the azimuthal angle
from rqm_qiskit import bloch_to_circuit
import math

qc = bloch_to_circuit(math.pi / 2, 0.0)   # |+⟩ on Bloch equator
print(qc.draw())

Quaternion re-export

Quaternion is re-exported from rqm-core. Users can access it via either:

from rqm_qiskit import Quaternion
# or
from rqm_core import Quaternion

Both refer to the same canonical implementation.


Usage Modes

Mode 1 — Compiler-first (primary)

Use rqm_compiler.Circuit as the canonical circuit IR, then lower to Qiskit via QiskitBackend or compile_to_qiskit_circuit:

from rqm_compiler import Circuit
from rqm_qiskit import QiskitBackend

c = Circuit(2)
c.h(0)
c.cx(0, 1)
c.measure(0)
c.measure(1)

backend = QiskitBackend()
result = backend.run_local(c, shots=1024)
print(result.counts)            # {"00": 512, "11": 512}
print(result.most_likely_bitstring())

Mode 2 — Bridge functions (educational / experimental)

Use spinor_to_circuit or bloch_to_circuit for state preparation directly from physical parameters:

from rqm_qiskit import spinor_to_circuit, QiskitBackend
import math

# Prepare |+⟩ state from spinor
s = 1 / math.sqrt(2)
qc = spinor_to_circuit(s + 0j, s + 0j)
qc.measure_all()

backend = QiskitBackend()
counts = backend.run_local(qc, shots=1024).counts
print(counts)    # approximately {"0": 512, "1": 512}

Current Scope (v0.1.0)

  • Quaternion — thin re-export from rqm-core with pretty() convenience
  • RQMState — normalized 1-qubit states; delegates math to rqm-core
  • RQMGate — dual-mode: rotation (R_x, R_y, R_z) or named gate (H, CNOT, …)
  • RQMCircuit — façade over rqm-compiler Circuit; to_qiskit() lowers to Qiskit
  • QiskitBackend — unified entry point: compile + run
  • QiskitTranslator — rqm-compiler IR → Qiskit QuantumCircuit
  • compile_to_qiskit_circuit() — convenience function
  • run_local() / run_backend() — execution helpers
  • QiskitResult — structured result wrapper (counts, probabilities, most-likely)
  • spinor_to_circuit / bloch_to_circuit — bridge functions (delegate to rqm-core)
  • compiled_circuit_to_qiskit() — primary bridge: rqm-compiler IR → QuantumCircuit
  • ✅ Local Aer simulation via run_on_aer_sampler() and run_local()
  • 🚧 IBM Runtime execution (placeholder, not yet implemented)

Roadmap

Version Features
0.1.0 Full architecture; compiler-first design; bridge functions; QiskitBackend/Translator/Result
0.2.0 IBM Runtime SamplerV2 integration
0.3.0 Noise models, density matrices
1.0.0 Stable public API, full documentation

Running Tests

# Install development dependencies
pip install -e ".[dev]"
pytest

Running Examples

python examples/quaternion_state_demo.py
python examples/bloch_vs_quaternion_demo.py
python examples/simulator_counts_demo.py

Optimization (Optional)

For improved circuit performance, use rqm-optimize:

from rqm_compiler import Circuit, compile_circuit
from rqm_qiskit.convert import compiled_circuit_to_qiskit
from rqm_optimize import optimize  # installed separately — not a dependency of rqm-qiskit

compiled = compile_circuit(my_circuit)
qc = compiled_circuit_to_qiskit(compiled)
qc = optimize(qc)

rqm-optimize is a completely separate, optional package. rqm-qiskit does not depend on it, import it, or couple to it in any way. Install it only when you need it:

pip install "git+https://github.com/RQM-Technologies-dev/rqm-optimize.git"

Important boundaries:

  • ❌ Do not add rqm-optimize as a dependency of rqm-qiskit
  • ❌ Do not import rqm_optimize inside rqm-qiskit source code
  • ❌ Do not couple the two repositories

Keep optimization optional and external.


License

MIT — see LICENSE.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

rqm_qiskit-0.1.2.tar.gz (53.2 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

rqm_qiskit-0.1.2-py3-none-any.whl (30.9 kB view details)

Uploaded Python 3

File details

Details for the file rqm_qiskit-0.1.2.tar.gz.

File metadata

  • Download URL: rqm_qiskit-0.1.2.tar.gz
  • Upload date:
  • Size: 53.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for rqm_qiskit-0.1.2.tar.gz
Algorithm Hash digest
SHA256 d05a096ed147dbc46c3813c9b1db89d913ceed288e16c86fb5daf75cbf4d20f7
MD5 80d6d13fa611f350bd463b857cefa6fc
BLAKE2b-256 9acc6fc086d2e596301a25210630757fec51b2d39df8be2e979ffbf3309da357

See more details on using hashes here.

Provenance

The following attestation bundles were made for rqm_qiskit-0.1.2.tar.gz:

Publisher: publish.yml on RQM-Technologies-dev/rqm-qiskit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file rqm_qiskit-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: rqm_qiskit-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 30.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for rqm_qiskit-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 98f4c2dc61c1a50a17f3d0cb37890dcb433e60d93449fce4f76c0fca13b31006
MD5 b352e1ae3268bfe1768b247fe3e65e7c
BLAKE2b-256 70a7c0e3a5011810156451cb5b0b3ff601a428fab9913694260d87c5b8abef95

See more details on using hashes here.

Provenance

The following attestation bundles were made for rqm_qiskit-0.1.2-py3-none-any.whl:

Publisher: publish.yml on RQM-Technologies-dev/rqm-qiskit

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page