rqm-entanglement
rqm-entanglement is the two-qubit / nonlocal layer of the RQM quantum stack.
It provides tensor-product state and operator helpers, arbitrary two-qubit
quaternion–Cartan decomposition, Weyl classification and local-equivalence
fingerprints, the canonical commuting nonlocal gate family, pure-state
entanglement measures, and operator Schmidt-rank classification. rqm-core
remains the authority for canonical quaternion/SU(2) conversion.
It uses ordinary complex tensor products and standard entanglement measures.
Local quaternion adapters provide equivalent SU(2) coordinates; they do not
define native quaternionic composite mechanics. See
RQM_TECHNICAL_CANON_V2.md.
Compiler 0.4 ownership boundary
For the 0.4 compiler line, rqm-entanglement remains the canonical owner of
nonlocal two-qubit mathematics: AxisHinge, CartanRelation,
QuaternionCartanBlock, canonical XX/YY/ZZ pair rotations, relational
promotion/demotion, SU(4) reconstruction, and Weyl classification.
rqm-compiler owns recognition, routing, query planning, complexity
accounting, and fallback policy. It must consume these mathematical semantics
rather than redefine them. See
docs/COMPILER_0_4_BOUNDARY.md.
Architecture boundary with rqm-core
| Layer | Owns |
|---|---|
rqm-core |
quaternion math, SU(2), single-qubit geometry, quat→2×2 unitary mapping |
rqm-entanglement |
two-qubit tensor structure, arbitrary SU(4) quaternion–Cartan decomposition, Weyl classification, nonlocal fingerprints, entanglement analysis |
All rqm-core integration lives in src/rqm_entanglement/adapters/rqm_core_adapter.py.
That adapter is the only place Entanglement imports Core, and the measured
circuit analyzers use it for canonical u1q quaternion gates emitted by
rqm-compiler.
Basis ordering
Computational basis: |00⟩, |01⟩, |10⟩, |11⟩
Qubit 0 is the more-significant (left) index.
CNOT: control = qubit 0, target = qubit 1.
The verified optional-Qiskit factor order is
qiskit-Klr:kron(q1=Kl,q0=Kr);circuit-little-endian.
Canonical entangler
U_ent(c1, c2, c3) = exp[-i/2 (c1 XX + c2 YY + c3 ZZ)]
Because XX, YY, ZZ mutually commute, this is computed analytically as
U_ent = xx_rotation(c1) @ yy_rotation(c2) @ zz_rotation(c3)
where exp[-i θ/2 P] = cos(θ/2) I4 - i sin(θ/2) P for P ∈ {XX, YY, ZZ}.
Quaternion–Cartan SU(4)
Version 0.2 promotes the tested EXP-012 representation:
from rqm_entanglement import QuaternionCartanBlock, classify_su4
block = QuaternionCartanBlock.from_unitary(unitary) # requires [qiskit]
assert block.validate()["valid"]
reconstructed = block.to_unitary()
classification = classify_su4(block)
Stored Weyl coordinates use exp[i(a XX + b YY + c ZZ)]. Existing
canonical_entangler(c1,c2,c3) uses
exp[-i/2(c1 XX + c2 YY + c3 ZZ)]; use weyl_to_rotation_coordinates and
rotation_to_weyl_coordinates for the exact conversion.
Reconstruction, serialization, hashes, classification of an existing block, and canonical-entangler construction do not import Qiskit. Generic arbitrary SU(4) decomposition uses the optional public Qiskit Weyl authority:
pip install -e ".[qiskit]"
The classifier distinguishes nonlocal operator, entangling-gate, perfect-entangler, and SWAP-like status. SWAP remains truthfully nonlocal while not being labeled as a gate that entangles product inputs.
Quick start
import numpy as np
from rqm_entanglement import (
I2, Y, CNOT,
ket00, local_unitary, apply_unitary,
concurrence_pure, entanglement_entropy_pure
)
def ry(theta: float) -> np.ndarray:
return np.cos(theta / 2) * I2 - 1j * np.sin(theta / 2) * Y
psi0 = ket00()
U = CNOT @ local_unitary(ry(np.pi / 2), I2)
psi = apply_unitary(U, psi0)
print(concurrence_pure(psi)) # ~1.0
print(entanglement_entropy_pure(psi)) # ~1.0
Stable entanglement analysis API (for rqm-api / Studio)
For integration points like rqm-api endpoint /v1/entanglement/analyze,
use the stable exported function:
from rqm_entanglement import analyze_entanglement
from rqm_entanglement import CNOT, I2, Y, ket00, local_unitary, apply_unitary, analyze_entanglement
import numpy as np
def ry(theta: float) -> np.ndarray:
return np.cos(theta / 2) * I2 - 1j * np.sin(theta / 2) * Y
psi0 = ket00()
psi_bell = apply_unitary(CNOT @ local_unitary(ry(np.pi / 2), I2), psi0)
result = analyze_entanglement(psi_bell)
print(result)
Result schema:
{
"has_entangling_gates": bool,
"entangled_pairs": [
{
"pair": [0, 1],
"metric_name": str,
"metric_value": float,
"interpretation": str, # optional
}
],
"last_entangling_gate": str, # optional
"fidelity_preserved": float | None,
"notes": [str],
}
Example (Bell-state-like input):
{
"has_entangling_gates": True,
"entangled_pairs": [
{"pair": [0, 1], "metric_name": "Concurrence", "metric_value": 1.0},
{"pair": [0, 1], "metric_name": "Entropy", "metric_value": 1.0},
{"pair": [0, 1], "metric_name": "Mutual Information", "metric_value": 2.0},
{"pair": [0, 1], "metric_name": "RQM Correlation", "metric_value": 1.0},
],
"fidelity_preserved": None,
"notes": [],
}
Input forms accepted by analyze_entanglement:
- pure state vector
(4,) - unitary / SU(4) matrix
(4,4) - gate sequence (list of
(4,4)matrices), including:- unnamed gates:
[U0, U1, ...] - named gates:
[("gate_name", U), ...] - dict-like entries:
[{"name": "...", "unitary": U}, ...]
- unnamed gates:
- RQM circuit payload (Studio/API contract style), e.g.:
{ "schema_version": "0.1", "num_qubits": 2, "instructions": [ { "gate": { "name": "h", "arity": 1 }, "targets": [{ "index": 0, "type": "qubit" }] }, { "gate": { "name": "cx", "arity": 2 }, "targets": [ { "index": 0, "type": "qubit" }, { "index": 1, "type": "qubit" } ] } ] }
Supported contract gate names currently include:- single-qubit:
i,x,y,z,h,s,sdg,t,tdg,rx,ry,rz,u1q - two-qubit:
cx/cnot,cz,swap,iswapUnsupported instructions are skipped with explanatorynoteswhile preserving the stable result schema.
- single-qubit:
For a finite unitary (4,4) input, the result additively includes su4 with
Cartan coordinates, Weyl class, both hashes, operator Schmidt rank, local
quaternion shells, global phase, reconstruction error, and convention version.
When the optional Qiskit dependency is absent, all legacy fields remain
available and notes explains why decomposition was omitted.
Metric formulas and conventions
Basis ordering is always |00>, |01>, |10>, |11> with qubit 0 as the
more-significant (left) index.
For a pure state
|psi> = [a00, a01, a10, a11]^T:
- Concurrence
C = 2 * |a00*a11 - a01*a10|- Range:
[0, 1] 0for product states,1for maximally entangled states
- Entanglement Entropy
S(rho_A) = -Tr(rho_A log2 rho_A)(bits), whererho_Ais reduced density matrix of either qubit for pure two-qubit states- Range:
[0, 1]
- Mutual Information
I(A:B) = S(rho_A) + S(rho_B) - S(rho_AB)(bits)- For pure two-qubit states,
S(rho_AB)=0, soI(A:B)=2*S(rho_A)and range is[0, 2]
- RQM Correlation (optional software summary metric, not new physics)
0.5 * (clamped_concurrence + clamped_entropy)- Range:
[0, 1]
Numerical conventions:
- tiny negative eigenvalues from floating-point roundoff are clipped to
0 - output metrics are clamped to physically valid ranges
- non-finite values (
NaN/Inf) are sanitized to stable values with notes - metric ordering is deterministic for identical input
Scope and current limits
- Primary support: 2-qubit SU(4)/state analysis
- Inputs that appear to represent
>2qubits are handled gracefully:- no crash
- stable output schema
- explanatory
notes
- Full generic multi-qubit entanglement analysis is out of scope.
The tested quaternion–Cartan representation is standard complex quantum
mechanics. It is not unique quantum information or native quaternionic
composite mechanics, and it carries no general synthesis, runtime, or IBM
hardware superiority claim. See
docs/EXP012_PROMOTION_PROVENANCE.md.
Installation
pip install -e ".[dev]"
Run tests:
pytest
Metadata
Release files for rqm-entanglement 0.2.2
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_entanglement-0.2.2.tar.gz | 50.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| rqm_entanglement-0.2.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 95.3 kB
Release files / rqm_entanglement-0.2.2.tar.gz
| Download URL | rqm_entanglement-0.2.2.tar.gz |
|---|---|
| Size | 50.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
b0d3bdebe0260a8d56127381be77d56853f91a9b09bf2dc69b78ee70685c8f6a
|
|
BLAKE2b-256 checksum How to use checksums |
f084f8e3eba342be5ce9ad5bbee36dee18f6590a3812ca7b623be7ffe2591e37
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.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 Sep 20, 2026.
Transparency logRelease files / rqm_entanglement-0.2.2-py3-none-any.whl
| Download URL | rqm_entanglement-0.2.2-py3-none-any.whl |
|---|---|
| Size | 44.5 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
d7024c94d878d514da6ed1702f766dfec8b51364cc388f3073d7088cc1b3e7b5
|
|
BLAKE2b-256 checksum How to use checksums |
451c770a28245c7a3980ac64e91d3baed9e03164223d6d56ab17bce3e1cd5486
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/7.0.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 Sep 20, 2026.
Transparency log