Reference implementation and computational toolkit for:
V. H. Monteverde, "The Qang (qg): A Unified Angular-Probability Unit and Metric for Parametric Quantum Circuit Design." ORCID: 0000-0001-8884-4811 · DOI: 10.5281/zenodo.22832150
qang bridges the gap between continuous Bloch-sphere rotation angles (θ ∈ [0, π]) and projective measurement spaces in parameterized quantum circuits (PQCs). It provides native representations for:
- Polar Bias Qang (qg_Z): qg_Z(θ) = cos θ = ⟨σ_z⟩ ∈ [−1, 1].
- Measurement-Outcome Entropy Qang (qg_S): qg_S(θ) = H(cos²(θ/2)) ∈ [0, 1] (Shannon entropy of computational-basis outcomes).
- Native SDK gate classes for Qiskit, Cirq and PennyLane (differentiable in qg_Z), regularized gradient optimizers, shot-noise error propagation, and density matrix/POVM metrics.
- qg read-outs from Qiskit, Cirq, PennyLane, Braket and pytket results with one qubit order, including the Qiskit V2 primitives.
- IBM Quantum through IBM Runtime (transpiler pass, calibrated readout correction, qubit selection) and qiskit-machine-learning integration.
- IQM devices (
qang.iqm): readout correction from the two poles or the error profile, qg read-outs ofIQMBackendcounts, chain choice; the project's first real-hardware runs were on IQM Garnet. - A bilingual book, Quantum Computing, Information and Physics in qang Space: English · Español.
qang.qga: the thousand-based angle scale of the Geometric and Dimensional Foundation of the Qang System, 1 turn = 2π rad = 1000 qga = 10⁶ m-qga. The milli-qang keeps its meaning: m-qg is the reading m = 1000·qg_Z, linear in the probability and not an angle; qga is the angle, uniform in the angle. Conversions between qga, radians, degrees, p₀ and m-qg (p0_from_qga(250) == 0.5,milliqang_from_qga(500) == -1000), the azimuthazimuth_qga, the Fisher informationFISHER_PER_QGA2= 4π²·10⁻⁶ qga⁻² (so the qang angle from N shots hasangle_sigma_qga(N)= 159.15/√N qga for any state), the Fubini–Study metric in qga and the Berry phase of a loop at constant height,cone_phase_qga= 1000·p₀ qga. A change of unit rescales every gradient by a constant: it does not change barren plateaus.- The book, rebuilt on the angular scale. Chapter 1 has a new section on qga, with three claims of the source
document corrected (p₀ = 0.5 is at 250 qga, not 125; the metric ¼dθ² has curvature 4, not 1; (mc²/E)² is not p₀ of the
same angle) and its relativistic and antimatter extension written up as an unverified proposal; chapters 2–24 and
30–34 and appendices A–B give their angles in qga where it helps. Each addition has a check script in
tools/(verify_cap01.py…verify_cap08.py,verify_qga_lecturas.py). Comparing with the author's working drafts also fixed one figure of chapter 10 (0.038, not 0.039).
qang.iqm(book chapter 31, §169): whatqang.ibmdoes, for IQM devices.readout_errorsreads a fake backend's error profile;pole_circuits/readout_from_polesmeasure the readout on a real device with two circuits (they give e0 = 0.0055, e1 = 0.029 on the stored Garnet run of §168);iqm_qggives qg_Z raw, readout-corrected, filtered and filtered after correction fromIQMBackend.runcounts;predict_kept_fraction,best_chainandcheck_weightcomplete it. On IQM's Garnet model the §165 circuits read 0.124 raw, 0.055 filtered and 0.047 filtered after readout correction (examples/iqm_readout_chain_qg.py). Not yet run on the chip. Install it in its own environment,pip install "qang[iqm]": iqm-client pins its own Qiskit.- First real-hardware data, IQM Garnet, both pre-registered. Three-flavour neutrinos (§165): the qg filter lowered the error 1.59× (0.0615 → 0.0386) and put the oscillation maximum at 2.6 GeV (exact 2.63; raw: 0.8 GeV), 4 of 4 predictions passed. The milli-qang (§168): the X gate of one qubit costs 1.64 m-qg, linear in the number of gates; 3 of 4 predictions passed, and M2 (the equator scatters half the binomial level) is open.
- The book is complete: 35 chapters and appendices A–F, in Spanish and English
(Español · English). The appendices are
generated from the code by
tools/make_appendices.py. Appendix E is the falsification register: 148 predictions stored with their verdicts (94 passed, 54 failed), 54 of 54 commit pre-registrations consistent, 8 of 16 sha256 pre-registrations checkable in git. - Upstream proposals from chapter 35, posted: qiskit-experiments#1662
(heralded readout), mitiq#3173 (weight post-selection with
ZNE and its cost rule), and a PyMatching discussion
(T1-aware reweighting). Drafts and the pre-send check are in
docs/upstream/.
- One module per library, imported only on demand, each with its test (
tests/test_integrations.py): mitiq (qg readings ofMeasurementResult, weight post-selection as an executor, ZNE of filtered readings and the chapter 21 cost rule), qiskit-experiments (HeraldedReadout: the §31 closed form that separates thermal population from readout error), Qiskit Dynamics (pulse-level qg_Z = cos A), QuTiP (readings ofQobj/mesolve, the filter on density matrices), Stim (detectors, observables and decoded logicals in qg), scikit-learn (WeightQNNClassifier,MultiClassQNNClassifier), JAX (jit/grad-able filtered readout), PyTorch (WeightQNNTorch), and Qibo, pytket, Amazon Braket and NVIDIA CUDA-Q (the qang rotation and the canonical, filtered readout). - Under T1 plus dephasing, ZNE of the filtered reading leaves 1.1 m-qg of error where ZNE of the raw reading leaves 55.9; heralded calibration recovers e01, the thermal population and T_eff where the standard calibration reads the qubit as cold.
- Known environment constraints: qiskit-dynamics 0.6 needs
qiskit<=1.3; PennyLane 0.45 needsjax<0.9; CUDA-Q has no native Windows wheels (use WSL).
What's new in 0.12 — compiling, kernels, dynamics, postselection and what neutrino circuits cannot see
- Minimal pulse area (
qang.pulse_area, §160): every fractional gate moved to its shortest equivalent (RX period 2π, RZZ period π via virtual Z), with the unitary preserved. The error follows the area, and the qg damping is cos θ e^(−θ²σ²/2). - Quantum kernels with the qg filter (
qang.kernels, §161): for a weight-preserving fidelity kernel the filter repairs the Gram matrix 2.4–6× and beats the diagonal normalization without its extra circuits. - Channels and fixed-depth time evolution (
qang.channels,qang.varqte, §162): every channel is an affine map of (qg_X, qg_Y, qg_Z), and McLachlan evolution at fixed depth beats the best Trotter circuit at late times. - Neutrinos, part two (§163): the mass ordering is read through matter (
NUFIT_IO). Majorana phases change no oscillation probability (majorana_invisible; the transpiler deletes them) but set m_ββ (m_bb). A sterile neutrino is a fourth qubit in the weight-1 sector (sterile_circuit, 5.5× filter gain). - Time loops and black holes as postselected teleportation (
qang.postselection, §164): P-CTC success is cos²(φ/2), whose qang angle is φ, and the grandfather paradox has probability 0. The Yoshida–Kitaev decoder recovers a message from a scrambling 3-qubit black hole (fidelity 0.55–0.74 on device models). - Neutrino paper (EN/ES):
manuscript/qang_neutrinos.pdf,manuscript/qang_neutrinos_es.pdf. Summary of every line, in Spanish:docs/RESUMEN_PUNTOS_QANG.md.
Notebooks: Methods §159–§164 ·
Métodos ·
QPON teleportation ·
Teleportación QPON
- Neutrinos (
qang.neutrino, §151–§156): flavour oscillation is a rotation. In vacuum qg_Z = cos²2θ + sin²2θ cos Δ, and at the maximum the mixing angle is a quarter of the qang angle, with a θ-independent error bar. Three flavours fit the weight-1 sector, so the qg filter applies (error 3× lower on device noise models). Also included: Earth matter (MSW) as a weight-preserving Trotter circuit, collective oscillations, where the conserved number is the mass number (qang.sectors.reweight_sectors), and solar neutrinos (solar_circuit). The whole Sun is one rotation in the mass basis. - The four quantum numbers in qg terms (
qang.angular, §155): m_s is one qubit's qg_Z, and m_l is the Hamming weight of a symmetric register, so the weight filter is the m_l projection. l comes from the qang value of SWAP, and the shell n is two spins (n−1)/2. The qang angle of |l, m⟩ is arccos(m/l), not the vector-model angle. Λ as a third filter on LiH (§153). - Teleportation through a quantum passive optical network (
qang.qpon, §157–§158): the optimal resource is not a Bell pair. tan α* = √η/κ, F* = (2 + η/κ)/3, and its qg_Z is the whole design rule. When the other users herald, that is a sector filter. The fidelity is a linear qg read-out of the resource, (3 + qg_XX − qg_YY + qg_ZZ)/6. In dual rail the filter heralds every loss, and at 20 km it beats the noiseless single-rail optimum on two of three device models. - Fisher information and the natural gradient (
qang.fisher, §159): the angle is the Fisher-flat coordinate and qg_Z the curved one. No shift rule needs fewer than 2 evaluations per parameter in any coordinate. In a real RY + CZ ansatz every metric diagonal is exactly 1/4, and the block metric is a set of qg_Y correlators read from one circuit per layer. Descent in qg coordinates does not converge, and the qg_YY natural gradient is 1.3× faster than descent in θ. - Always-on ZZ crosstalk (
ibm.add_static_zz, §150).
Notebooks: Neutrinos ·
Neutrinos (ES) ·
Quantum numbers ·
Números cuánticos ·
IBM §145–§150
- A PCA spectrum in the weight-1 sector (
unary_loader,unary_orthogonal,pca_rotation,unary_spectrum): the loaded data form the density matrix that quantum PCA diagonalizes, and a nearest-neighbour RBS rotation puts each eigenvalue on one qubit. On 21 IBM device noise models filter plus readout cut the spectrum error 4.6× (median) and order all five eigenvalues on 18 of 21 (raw: 13) (§146). No quantum speed-up is claimed. - Hamiltonian simulation and quantum walks (
xy_trotter,xy_exact_occupations,occupations): Trotter circuits of the XY chain, all weight-preserving. The filter halves the best simulation error and moves the optimal number of Trotter steps deeper (median 12 against 8); in a quantum walk raw data spread like a classical random walk (exponent 0.87) and filtered data ballistically (1.84; noiseless 1.94) (§147). - Interacting excitations (
xxz_trotter,xxz_exact_occupations): the XXZ chain with 1, 2 or 3 excitations, first- or second-order Trotter. The filter's benefit falls from 5.6× with one excitation to 2.6× with two or three: larger sectors let more noise through (§148). - Swap test and inversion test (
swap_test_circuit,unary_overlap_circuit,swap_test_fidelity,overlap_fidelity): the fidelity of two states. The weight-preserving inversion test with the filter reads it to 0.010–0.036 on six device noise models (3.8–11.2× better than raw); the swap test needs 11 qubits, and since its answer sits on an ancilla outside the symmetry the filter gains only 1.4–1.8×. A fidelity classifier keeps its noiseless score (§149).
- IBM devices through IBM Runtime (
qang.ibm): a Qiskit transpiler analysis pass that says whether the qg filter applies (every gate conserves the Hamming weight) and on which sector; readout correction from the device's published per-qubit errors; qg_Z from IBM Runtime Sampler and Estimator results, raw, readout-corrected, filtered, or both. On three IBM device noise models the qg_Z error falls from 0.065–0.104 raw to 0.013–0.022 with filter plus readout correction (§137). - Choose the qubits before spending device time:
predict_kept_fractionpredicts from the calibration how many shots the filter will keep;best_chainpicks the chain of physical qubits with the most, 6–17 points above Qiskit's default layout (§138). - qang's QNN on IBM in one job:
qnn_templateis the weight-conserving QNN as one parameterized circuit of native XX+YY gates;run_qnnsends a whole test set as a single Sampler pub (§139). - qiskit-machine-learning (
qang.qiskit_ml): qang's QNN as aSamplerQNN, with raw and filtered qg_Z features, on any of its samplers (§140).pip install "qang[ml]".
from qiskit import transpile
from qiskit_ibm_runtime.executor_sampler import Sampler
from qang import ibm
t = transpile(qc, backend) # qc: weight-preserving circuit, measured
res = Sampler(mode=backend).run([t]).result()[0]
ibm.ibm_qg(res, t, backend, weight=1)["filtered_readout"] # qg filter + calibrated readout correction
layout, pred, t = ibm.best_chain(qc, backend, weight=1) # qubits with the most shots kept (predicted)
r = ibm.run_qnn(model, X_test, backend) # qang's QNN: whole test set in one jobNotebook with §145–§150 on local IBM device simulators (no account needed):
Step by step: docs/ibm_quickstart.md. Paper (§137–§150): manuscript/qang_ibm.pdf (Spanish: manuscript/qang_ibm_es.pdf; Word: qang_ibm.docx, qang_ibm_es.docx).
- Every SDK, one qubit order (
qang.interop): per-qubit qg_Z with error bars, the qg (Hamming-weight) filter and the register entropy with its standard error, from Qiskit, Cirq, PennyLane, Braket and pytket results. - Qiskit V2 primitives:
IO.sampler_qgreads a whole SamplerV2 parameter sweep;IO.filtered_observablesmakes EstimatorV2 return the filtered read-out directly. - Differentiable filter in PennyLane:
pennylane_gate.filtered_qg_z(qml.probs(...), weight)can be part of the loss. - Quantum signal processing in qg terms (
qang.qsp): QSP and weighted QSP, Hadamard-test read-out as qg_Z, phase fitting in the arcsine (qg) scale.
Full list in CHANGELOG.md.
| module | what it does |
|---|---|
qang.core |
the qg_Z / qg_S unit, Bloch-sphere round trips |
qang.formulation |
the 15 main gates and 14 main algorithms in qg units (qg'P = qg{U†PU}), and the local radius r² = qg_X² + qg_Y² + qg_Z² |
qang.sectors |
the qg symmetry filter and Hamming-weight tools; echo calibration of in-sector errors |
qang.statistics |
qg_Z intervals from shot counts (Bayesian, Wilson, delta method); unbiased qg² and r² |
qang.qml |
weight-conserving QNN classifiers (binary and multiclass) read with and without the qg filter |
qang.polarization |
polarized light: Stokes parameters are qg values, Mueller matrices are the qg gate rule |
qang.geometric |
geometric (Berry/Pancharatnam) phase in qg units, Stokes' theorem on the Bloch sphere |
qang.interop |
one qubit order for Qiskit, Cirq, PennyLane, Braket and pytket results; qg_Z profile, qg filter, register entropy and its error; Qiskit SamplerV2 / EstimatorV2 read-outs |
qang.ibm |
IBM devices: transpiler pass that checks weight conservation, calibrated readout correction, qg read-out of IBM Runtime Sampler and Estimator results, kept-fraction prediction and qubit selection, ZNE, shot planning, the QNN, PCA spectra, and Trotter simulation of the XY and XXZ chains |
qang.qiskit_ml |
qang's weight-conserving QNN as a qiskit-machine-learning SamplerQNN, with raw and filtered qg_Z features |
qang.qsp |
quantum signal processing and weighted QSP in qg terms; Hadamard-test read-out; phase fitting in the arcsine scale |
qang.proportions |
the qg angle as the arcsine transform of any binomial proportion: intervals, Cohen's h |
qang.clock_comparison |
differential phase of two clocks from the ellipse of their qg pairs |
qang.complementarity |
wave-particle duality as the Bloch radius; entropic uncertainty with qg_S |
qang.qiskit_gate, qang.cirq_gate, qang.pennylane_gate |
native gates for the three SDKs (optional); parameterized qg_Z gates; differentiable filtered qg_Z in PennyLane |
qang.algebra |
Closed-form qg algebra: the universal gate, reflections and transition probabilities; Cartan subalgebra (§166) |
qang.algorithms |
Textbook algorithms in Qiskit: teleportation, superdense coding, Grover |
qang.angular |
The four quantum numbers of an electron in qg (§155) |
qang.ansatze |
Reusable variational ansätze, including qg layers |
qang.channels |
Single-qubit channels as affine maps of the qg vector (§162) |
qang.circuits |
Circuit constructors (Bell, GHZ, W, graph, Dicke) and their readings |
qang.fisher |
Fisher information, shift rules and the natural gradient in qg (§159) |
qang.gradients |
The coordinate singularity at the poles and its regularizations |
qang.integrations |
qang inside other libraries: one submodule per library (Chapter 35) |
qang.iqm |
qg readings on IQM: readout from the poles or the error profile, filter, chain choice (Chapter 31) |
qang.kernels |
Quantum kernels with the qg filter (§161) |
qang.knitting |
Sampling cost of circuit cutting |
qang.mixed |
The qang unit for mixed states and POVMs |
qang.multiqubit |
The qang unit for multi-qubit registers: marginals, entropies, correlations |
qang.neutrino |
Neutrino flavour oscillations in qg (§151; Chapters 9–11) |
qang.phase |
The deferred qg_Φ phase unit |
qang.postselection |
Teleportation with postselection: closed timelike curves and black-hole decoding (Chapters 14–15) |
qang.probability |
The qang probability equation and the milli-qang (§167; Chapter 1) |
qang.pulse_area |
Pulse area of fractional gates: the minimal-area rule (§160) |
qang.qec |
The 3-qubit bit-flip code with syndromes read in qg |
qang.qga |
The angular qang: 1000 qga per turn, conversions to radians, p₀ and m-qg, Fisher and Berry phase in qga (Chapter 1) |
qang.measures |
Catalogue of qang sub-measures: definition, equivalent quantity, the decision each improves, status and evidence (appendix H) |
qang.qpon |
Teleportation through a passive optical network, discrete variables (§157; Chapters 12–13) |
qang.transformations |
Closed-form transformations between qang-parameterized states |
qang.varqte |
Variational real-time evolution (McLachlan) with a weight-preserving ansatz (§162) |
Every public name of every module: Appendix D of the book (English, generated from the code).
A state at polar angle θ projects to qg_Z = cos θ, as on the unit circle; the
probability of measuring 0 uses the half angle, p₀ = cos²(θ/2) = (1 + qg_Z)/2,
and qg_S is the entropy of that outcome (examples/unit_circle_qg.py).
Quantum Computing, Information and Physics in qang Space (in Spanish, Computación, información y física cuántica en el
espacio qang): 35 chapters in thirteen parts, from the unit and the milli-qang to real hardware, cross-domain
applications and qang as a module of other libraries, plus six appendices. Every chapter compares the same task without
qang and with qang and states the difference, and every number in it comes from a script in tools/ or examples/.
Read it at viny2030.github.io/qang (Español ·
English); the source is in book/.
Install the minimal core library (NumPy only):
pip install qang # from PyPI
pip install "qang @ git+https://github.com/Viny2030/qang.git" # or from GitHub (latest main)
pip install . # or from a local clonepip install "qang[qiskit]" # Native Qiskit gate integration (from a clone: pip install ".[qiskit]")
pip install ".[cirq]" # Native Cirq gate integration
pip install ".[pennylane]" # Native PennyLane operations (autodiff in qg_Z)
pip install ".[hardware]" # IBM Quantum hardware / calibrated fake backends
pip install ".[ionq]" # IonQ simulator / hardware scripts (qiskit-ionq)
pip install ".[iqm]" # IQM devices and fake backends (qang.iqm); its own environment: iqm-client pins Qiskit
pip install ".[qec]" # Surface-code decoding examples (pymatching)
pip install ".[ml]" # qiskit-machine-learning integration (qang.qiskit_ml)
pip install ".[chemistry]" # PySCF/OpenFermion molecules (Linux/macOS or WSL)
pip install ".[mitiq]" # qang.integrations: also experiments, dynamics, qutip, stim, sklearn, jax, torch,
# qibo, pytket, braket, cudaq, or ".[integrations]" for all that share one environment
pip install ".[all]" # Everything except chemistry (Qiskit, IBM Runtime, IonQ, pymatching, Cirq, PennyLane, SciPy, Pytest, Matplotlib)
pip install -r requirements.txt # same as .[all], without installing qang itselfqang.interop reads qg quantities from the results of any of these SDKs with one
qubit order (qubit 0 first), so the same code gives the same numbers whatever
produced the counts: per-qubit qg_Z with error bars, the qg filter (keep one
Hamming weight) and the register entropy.
from qang import interop as IO
c = IO.canonical_counts(result.get_counts(), sdk="qiskit") # or a cirq.Result, a Qiskit BitArray,
# qml.counts() with sdk="pennylane",
# a Braket or pytket result
IO.qg_z_profile(c) # [(qg_Z, standard error)] per qubit
IO.weight_filter(c, 1) # (kept counts, kept fraction)
IO.joint_qg_s(c) # Miller-Madow corrected register entropy, in qg unitsParameterized circuits: qang.qiskit_gate.append_rqang_parameter(qc, Parameter("qg"), q) and
qang.cirq_gate.rqang_symbol(sympy.Symbol("qg")) put the qg_Z gate in circuits bound later;
qang.pennylane_gate.rqang is differentiable in qg_Z. Example: examples/interop_sdks_qg.py.
Qiskit primitives and a differentiable filter in PennyLane:
IO.sampler_qg(sampler.run([(qc, values)]).result()[0], weight=1) # arrays over the whole sweep:
# "qg", "se", "kept"
obs = IO.filtered_observables(n, 1) # P_w and P_w Z_i for EstimatorV2
kept, qg = IO.estimator_filtered_qg(estimator.run([(qc, obs, values)]).result()[0].data.evs)
from qang.pennylane_gate import filtered_qg_z # on qml.probs(), differentiable:
loss = lambda x: filtered_qg_z(circuit(x), 1)[0] # qml.grad(loss) worksfrom qang import Qang
# Anchor values
q_zero = Qang.from_angles(0.0, mode="polar")
print(q_zero.value) # +1.0 (|0>)
q_max_ent = Qang.from_angles(1.5707963, mode="entropic")
print(q_max_ent.value) # 1.0 (Maximum measurement uncertainty)
# Full Bloch sphere and statevector round-trip
q = Qang.from_angles(theta=0.9, phi=1.1, mode="polar")
bx, by, bz = q.to_bloch_vector()
alpha, beta = q.to_statevector()
# Engineering subunit (milliqang)
print(Qang(0.5).milliqang) # 500.0 m-qgfrom qang import Qang
from qang.qiskit_gate import FullRQangGate
from qiskit import QuantumCircuit
qc = QuantumCircuit(1, 1)
# Append gate directly parameterized in qg_Z without manual arccos conversion
qc.append(FullRQangGate(Qang(0.5, phi=0.3)), [0])
qc.measure(0, 0)import cirq
from qang import Qang
from qang.cirq_gate import full_rqang_gate
q = cirq.LineQubit(0)
circuit = cirq.Circuit(
full_rqang_gate(Qang(0.5, phi=0.3)).on(q),
cirq.measure(q, key="m")
)import pennylane as qml
from pennylane import numpy as pnp
from qang.pennylane_gate import rqang
dev = qml.device("default.qubit", wires=1)
@qml.qnode(dev)
def z_expval(qg):
rqang(qg, wires=0) # RY(arccos(qg)), differentiable in qg
return qml.expval(qml.PauliZ(0))
qg = pnp.array(0.3, requires_grad=True)
print(qml.grad(z_expval)(qg)) # 1.0: <Z> = qg_Z exactlyfrom qang.statistics import propagated_theta_std, confidence_interval_theta
# First-order delta-method uncertainty: invariant across the Bloch sphere (~1/sqrt(N))
std_theta = propagated_theta_std(theta=1.0, n_shots=10000)
ci_lower, ci_upper = confidence_interval_theta(theta_hat=1.0, n_shots=10000, confidence=0.95)
print(f"Theta 95% CI: [{ci_lower:.4f}, {ci_upper:.4f}] rad")notebooks/qang_start_here.ipynb (English; Spanish: qang_inicio_formulacion.ipynb) installs qang from PyPI
and walks through the 15 main gates and 14 main algorithms in qg language with qang.formulation: a state is
described by its qg values (qg_P =
for every Pauli string) and a gate acts as qg'P = qg{U^dag P U}.
Sections 5–7 of the notebooks add the local radius, the angle in radians separated from the radius, and the echo
calibration of the errors the filter keeps (with the check for when not to use it).
Article: manuscript/qang_formulation.pdf (Spanish draft: manuscript/qang_teoria_es.pdf).
from qang import formulation as F
bell = F.apply_gate(F.apply_gate(F.qg_values([1, 0, 0, 0]), F.kron(F.H, F.I2)), F.CX)
# {'II': 1.0, 'XX': 1.0, 'YY': -1.0, 'ZZ': 1.0} (qang >= 0.5.1)
F.radius_profile(bell) # [0.0, 0.0]: both qubits at the centre of the sphere (qang >= 0.6.4)The local radius (§97). Each qubit lives on a sphere of squared radius r² = qg_X² + qg_Y² + qg_Z² = 2 Tr ρ² − 1
(area 4π r², surface deficit 4π(1 − r²)). One-qubit gates rotate the sphere and keep r; SWAP exchanges radii; CNOT,
CZ, iSWAP, Toffoli and Fredkin can move a qubit to the centre. For a pure global state 1 − r² is the one-tangle
(known physics: Coffman–Kundu–Wootters, Meyer–Wallach); for a noisy state it mixes entanglement and noise. In a
definite-weight state r = |qg_Z|, so after the qg filter (equal T1) the deficit is an entanglement measure read
from Z-basis shots alone (§98). On five device noise models (IBM, IonQ) the filter cuts the deficit error 3.2–4.0×,
but in-sector gate errors still make product states look entangled (§100). F.algorithm_radii() gives the radius of
the readout qubits of the 14 algorithms. The angle in radians separates from the radius,
θ = atan2(√(qg_X² + qg_Y²), qg_Z) = arccos(qg_Z / r) (F.direction_from_qg): it is exact under depolarizing noise,
where arccos(qg_Z) drifts towards π/2 (§102, §103). Short note: manuscript/qang_radius.pdf (Spanish: manuscript/qang_radio_es.pdf).
qang.qml (qang >= 0.6.4; MultiClassQNN and block_unitaries from 0.6.17) trains weight-conserving QNN classifiers and reads every result with qang (the qg
filter keeps only the shots that stayed in the input's Hamming-weight sector) and without it. These models are
classically simulable: a robustness tool, not a quantum advantage. Every prediction was committed before its run
(176 judged so far in this line, §75–§123: 123 passed, 53 failed, all reported; 4 more wait for the IonQ hardware run, §116). Note (with §104–§123): manuscript/qang_qml.pdf (Spanish:
manuscript/qang_qml_es.pdf).
Results so far (simulation; RESEARCH_NOTES §75–§98):
| question | result |
|---|---|
| trained on a simulator, run under T1 (60 runs, §80) | with qang the noiseless accuracy is recovered exactly: +2.5 points at weight 1, +16.5 at weight 2 |
| trained under the calibrated noise (§80, §81, §101) | without qang the model catches up; the one case where it was ahead (§81, pair-product encoding, rich readout, +1.2 points) shrank to +0.5, not significant, over 60 new runs (§101), and with the simple readout the filter is 0.6 points better |
two channels, filtered + raw features (§95, 60 runs, qang="both") |
with the dual encoding the 1.2-point effect does not replicate: trained under T1 the filtered model equals the noiseless one (0.953), raw 0.950, both channels 0.950; the two channels are safe but add nothing |
| T1 spread across qubits (§82) | the filter alone loses < 1 point up to a ±80% spread of 1/T1 |
| weight 2 (§87, §90) | the pair-product encoding limited it; with the "dual" encoding and readout="zz" weight 2 matches weight 1 (0.947 = 0.947) |
| device noise models (§85, §91) | IBM fake backends and the IonQ simulator (Aria-1, Forte-1): qg_Z error 2.7–3.6× smaller with qang; 189 inputs on Forte-1: 0.968 with vs 0.958 without (noiseless 0.979) |
| scaling (§94, 108 configurations, 4–8 qubits, weight 1–4, depth 3–24) | the filter has the lower readout error in 106 of 108 (up to 1000×); a closed-form rule, MSE ≈ (1 − z²)/(K·S) with K = (1 − γ)^(weight·depth), predicts the winner in 99% |
| low kept fraction, unequal T1, dephasing (§96, 405 configurations, K down to 2.6·10⁻⁷) | the filter wins in 399 of 405 and in every configuration with at least 20 kept shots (MSE up to 1871× lower with equal T1, 94× with unequal T1, 58× with dephasing); the rule picks the winner in 342 of 342 with K·S ≥ 5 |
| the local radius as an entanglement measure (§98) | under equal T1 the filtered deficit 1 − qg_Z² is the noiseless tangle to 3·10⁻¹⁵; on product states it is exactly 0, while the raw readout shows false entanglement of 0.60–0.95 |
| distorting against faithful encoding (§101, 60 runs, weight 2) | no readout trained under T1 beats the filter significantly; the best weight-2 model is the dual encoding with the filter (0.955) |
| the radius on device noise models (§100, §104 in IonQ's native gate set, 3 IBM fake backends, IonQ aria-1 and forte-1) | deficit error of trained circuits 0.05–0.08 with qang against 0.20–0.27 without; on product states the filter removes only 15–33% of the false entanglement (in-sector errors pass it) |
| the angle in radians separated from the radius (§102, §103) | exact under depolarizing noise (arccos(qg_Z) errs 0.12–0.29 rad); 5–9× more accurate on the IBM noise models and, once the noise gates are sent in IonQ's native gate set, on the IonQ ones (8.7–9.0×); loses under pure dephasing and without noise (three bases cost shots) |
| echo calibration of in-sector errors (§105, five device noise models) | five echo circuits measure where the filter's kept shots land; inverting that 5×5 matrix removes 38–47% of the remaining deficit error; filter + echo is 6–7× more accurate than the raw readout (qang.sectors.echo_transfer_matrix, unmix_sector) |
| echo calibration and the classifier (§106, 189 inputs, five device noise models) | decisions that differ from the noiseless model: 15 without qang, 7 with the filter, 3 with filter + echo; on the IBM noise models filter + echo reaches the noiseless accuracy (0.979) |
| echo calibration at weight 2 (§107, 10 × 10 transfer matrix) | removes 37–43% of the qg_Z error and 39–48% of the qg_ZZ error left by the filter on five device noise models; filter + echo 3.4–4.0× below raw |
| echo calibration on narrow-margin inputs (§108, 600 readings) | the filter cuts flipped decisions from 47 to 17; the echo adds nothing there (19), because the filtered error is close to shot noise: use the echo only when the filtered error is well above its shot-noise level |
| training from shots (§109, SPSA, 100 or 1000 shots per evaluation, T1) | trained with qang 0.939 / 0.930, without 0.929 / 0.915; the filter's shot cost did not show; noiseless training + filter at run time 0.945 |
multiclass, each qubit a class (§110, MultiClassQNN, 30 runs) |
with qang exactly the noiseless accuracy; without qang −5.3 points (qubit readout) and −9.1 (linear head), −15 to −18 on 5-class digits |
| 5, 6 and 8 qubits (§111, weight 1 and 2, 54 runs) | with qang exactly the noiseless accuracy at every size; without qang −3 points at weight 1 (flat in n at fixed depth) and −9 to −26 at weight 2 (8 qubits: 0.965 against 0.705) |
| trainability under T1 (§112, 4-8 qubits, 2400 gradient draws) | with qang the gradient is exactly the noiseless one (without: K times smaller at weight 1); fewer shots to resolve it in 10 of 12 cells, more when the kept fraction drops below about 0.15 |
| multiclass on device noise models with echo (§113, 5-class digits, 500 readings per readout) | flipped decisions: 46 raw / 19 filter / 15 filter + echo (qubit readout), 51 / 24 / 15 (head); head accuracy 0.858 / 0.890 / 0.900, noiseless 0.91 |
| multiclass at 8 qubits (§114, 3, 5 and 8 classes of digits, 30 runs) | with qang exactly the noiseless accuracy; without qang the head readout loses 0.7 / 15.9 / 11.1 points (3 / 5 / 8 classes), the qubit readout 5.1 / 4.4 / 3.4; trained under the noise without qang, 2–3 points behind with 5 and 8 classes |
| echo calibration at 8 qubits, weight 2 (§115, 28 × 28 transfer matrix, five device noise models) | removes 27–38% of the qg_Z error left by the filter (32% on average, against 40% at 5 qubits); filter + echo 3.4–4.1× below raw |
| unequal T1 corrected (§117, spread ±100%, 40 runs) | training with qang under the calibrated decay rates: 0.951 / 0.940 against noiseless 0.950 / 0.945 (filter alone 0.931 / 0.918), unaffected by a 10% calibration error; the filtered readout depends only on the ratios of the rates, so at weight 2 it survives a 1.5× drift of all T1 (−0.7 points) that costs the raw noise-aware model 10 |
| dephasing: filter + zero-noise extrapolation (§118, T1 0.08 + dephasing 0.03/0.06, 40 runs) | the filter turns T1 + dephasing into dephasing alone (exact), so ZNE of the filtered features cuts their error to 50–58% (linear) or 27–35% (Richardson) of the filter's and beats ZNE of the raw readout by 3–10 points; with 1000 shots per scale the gain is lost at weight 2; training with the filter under the calibrated noise recovers the noiseless accuracy (0.951–0.956) |
| the whole pipeline on device noise models (§119, IBM fake backends, 189 inputs, calibration from published T1/T2) | the filter lifts 0.958 to 0.972 (noiseless 0.979); calibrated training from T1/T2 adds nothing there (0.968), because gate errors dominate and decay is only 0.002–0.017 per sublayer: train noiselessly and filter, and keep calibrated training for strong decay or dephasing |
| calibrating with the device itself (§120, echo-aware training and a readout refit on 40 device inputs, IBM noise models) | neither beats noiseless training plus the filter (0.970 and 0.965 against 0.972; noiseless 0.979) |
| why the multiclass loss without qang varies between seeds (§121, 40 runs) | without the filter the raw logits are K L + (1 − K) v (exact): every input is pulled toward the class with the largest trained constant v_c; a pull index from the trained readout ranks the seeds by loss (Spearman 0.98 qubit, 0.65 head; losses 3–42 points); with qang the pull is gone |
| dephasing with filter + ZNE at 8 qubits (§122, 18 runs) | as at 5 qubits: linear ZNE leaves 50–56% of the filter's feature error and reaches 0.955 / 0.962 (noiseless 0.959 / 0.964) with exact probabilities; at 1000 shots, weight 2, it falls below the filter alone (0.879 against 0.915); training with the filter under the noise gives 0.963 / 0.961 |
| a pull-free multiclass readout (§123, 40 runs) | logits linear in the excitation probabilities with no bias: raw and filtered decisions coincide exactly (decayed shots only rescale the logits), so without any filter the head readout keeps 0.938 / 0.928 under equal / unequal T1 against 0.653 / 0.624 for the standard readout, at no cost in noiseless accuracy |
| not corrected exactly | dephasing; unequal T1 (the filter still has the lower error, but is biased); errors that move an excitation inside the sector |
Hardware runs are prepared, with explicit cost confirmation, and pending:
examples/qnn_hardware_qg.py --mode ionq_qpu (IonQ Forte-1) or --mode ibm, and
examples/qec_syndrome_destructive_qg.py --mode ibm (T1 and dephasing from Leung-code syndromes; within 1–4% of the
calibration on IBM noise models, §93; the dephasing reads the product mean over the four qubits, §99).
from qang.qml import WeightQNN
m = WeightQNN(n_qubits=5, weight=2, encoding="dual", readout="zz").fit(X_train, y_train) # 4 features in [-1, 1]
m.score(X_test, y_test, gamma=0.08, qang=True) # = noiseless accuracy (equal T1)
m.score(X_test, y_test, gamma=0.08, qang=False) # raw readout, biased by T1qang.polarization and qang.geometric (qang >= 0.6.0): the normalized Stokes parameters are qg values (the
Poincare sphere is the Bloch sphere), a lossless Mueller matrix is the qg gate rule, Malus's law reads
I = I0 (1 + qg_Z cos 2theta + qg_X sin 2theta)/2, and the geometric phase of a loop at constant qg_Z is
(qg_Z - 1)/2 of a turn (Stokes' theorem on the sphere). Note: manuscript/qang_optics.pdf (Spanish:
manuscript/qang_optics_es.pdf).
notebooks/qang_full_reference.ipynb is the single canonical, self-contained walkthrough
of the whole project — the Qang class, the Section 4.1 gradient singularity (regularized
and benchmarked), mixed states/POVMs, multi-qubit profiles, the native Qiskit and Cirq
gates, shot-noise error propagation, Quantum Natural Gradient, a live round-trip against
IonQ's cloud simulator, and a closing section that reformulates every result above into
concrete, measured speed/cost comparisons (including one negative result, kept in on
purpose). Open it directly in Colab with the badge above.
Three further notebooks (in Spanish) cover the research notes:
notebooks/qang_verificado.ipynb— §1–§19: exact identities, blind spots, noise diagnostics, optimization, knitting, few-shot estimation, QML, control quantization.notebooks/qang_avances_colab.ipynb— §20–§93: the qg symmetry witness and filter (chemistry, Hubbard, constrained QAOA), filter vs ZNE, qubit characterization, error correction (Leung code, syndrome tracking), coherence, few-shot estimation, and the recorded IonQ noisy-simulator runs, each with an honest "for / against" reading.notebooks/qang_criptografia_colab.ipynb— cryptography line, kept separate: why qg does not apply to post-quantum cryptography, BB84 drift-vs-eavesdropper monitoring (§40) and certified quantum random numbers (§41); companion PDFmanuscript/qang_criptografia.pdf.
The package includes an extensive test suite (1445 tests, run in CI on Python 3.9–3.12; those that need an optional SDK are skipped when it is absent) verifying analytical anchors, numerical stability, gradient regularizations, backend fidelity, and every numerical finding quoted in RESEARCH_NOTES.md:
pytest -vWe welcome contributions, bug reports, and suggestions!
Issues: Please use the GitHub Issue Tracker to report bugs or request features.
Contributions: See CONTRIBUTING.md for local development and pull request guidelines.
If you use qang in your research, please cite the paper that defines the unit:
@article{monteverde2026qang,
title = {The Qang (qg): A Unified Angular-Probability Unit and Metric for Parametric Quantum Circuit Design},
author = {Monteverde, Vicente Humberto},
year = {2026},
publisher = {Zenodo},
doi = {10.5281/zenodo.22832150}
}and, for the software itself, the repository: https://github.com/Viny2030/qang.
