Metadata-Version: 2.4
Name: qang
Version: 0.6.5
Summary: The Qang (qg): a unified angular-probability unit and metric for parametric quantum circuit design.
Author-email: Vicente Humberto Monteverde <viny01958@gmail.com>
License-Expression: MIT
Project-URL: Homepage, https://github.com/Viny2030/qang
Project-URL: Repository, https://github.com/Viny2030/qang.git
Project-URL: Bug Tracker, https://github.com/Viny2030/qang/issues
Project-URL: Paper, https://doi.org/10.5281/zenodo.22832150
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
Classifier: Topic :: Scientific/Engineering :: Physics
Classifier: Intended Audience :: Science/Research
Requires-Python: >=3.9
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.24
Provides-Extra: qiskit
Requires-Dist: qiskit>=1.0; extra == "qiskit"
Requires-Dist: qiskit-aer; extra == "qiskit"
Provides-Extra: cirq
Requires-Dist: cirq>=1.0; extra == "cirq"
Provides-Extra: pennylane
Requires-Dist: pennylane>=0.42; python_version >= "3.10" and extra == "pennylane"
Provides-Extra: hardware
Requires-Dist: qiskit>=1.0; extra == "hardware"
Requires-Dist: qiskit-aer; extra == "hardware"
Requires-Dist: qiskit-ibm-runtime>=0.40; extra == "hardware"
Provides-Extra: knitting
Requires-Dist: qiskit>=1.0; extra == "knitting"
Requires-Dist: qiskit-aer; extra == "knitting"
Requires-Dist: qiskit-addon-cutting>=0.9; extra == "knitting"
Provides-Extra: ionq
Requires-Dist: qiskit>=1.0; extra == "ionq"
Requires-Dist: qiskit-aer; extra == "ionq"
Requires-Dist: qiskit-ionq>=1.0; python_version >= "3.10" and extra == "ionq"
Requires-Dist: requests; extra == "ionq"
Provides-Extra: qec
Requires-Dist: pymatching>=2.0; extra == "qec"
Provides-Extra: chemistry
Requires-Dist: pyscf>=2.3; sys_platform != "win32" and extra == "chemistry"
Requires-Dist: openfermion>=1.6; extra == "chemistry"
Requires-Dist: openfermionpyscf>=0.5; sys_platform != "win32" and extra == "chemistry"
Provides-Extra: examples
Requires-Dist: scipy>=1.10; extra == "examples"
Requires-Dist: matplotlib>=3.7; extra == "examples"
Requires-Dist: scikit-learn>=1.2; extra == "examples"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: matplotlib>=3.7; extra == "dev"
Requires-Dist: scipy>=1.10; extra == "dev"
Provides-Extra: all
Requires-Dist: qiskit>=1.0; extra == "all"
Requires-Dist: qiskit-aer; extra == "all"
Requires-Dist: qiskit-ibm-runtime>=0.40; extra == "all"
Requires-Dist: qiskit-addon-cutting>=0.9; extra == "all"
Requires-Dist: qiskit-ionq>=1.0; python_version >= "3.10" and extra == "all"
Requires-Dist: requests; extra == "all"
Requires-Dist: pymatching>=2.0; extra == "all"
Requires-Dist: cirq>=1.0; extra == "all"
Requires-Dist: pennylane>=0.42; python_version >= "3.10" and extra == "all"
Requires-Dist: scipy>=1.10; extra == "all"
Requires-Dist: pytest>=7.0; extra == "all"
Requires-Dist: matplotlib>=3.7; extra == "all"
Requires-Dist: scikit-learn>=1.2; extra == "all"
Dynamic: license-file

# qang — The Qang (qg) Python Framework

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Viny2030/qang/blob/main/notebooks/qang_full_reference.ipynb)
[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.22832150.svg)](https://doi.org/10.5281/zenodo.22832150)
[![PyPI](https://img.shields.io/pypi/v/qang.svg)](https://pypi.org/project/qang/)
[![Python 3.9+](https://img.shields.io/badge/python-3.9+-blue.svg)](https://www.python.org/downloads/)
[![Tests](https://github.com/Viny2030/qang/actions/workflows/tests.yml/badge.svg)](https://github.com/Viny2030/qang/actions/workflows/tests.yml)

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](https://orcid.org/0000-0001-8884-4811) · DOI: [10.5281/zenodo.22832150](https://doi.org/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.

### What is in the library

| 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 |
| `qang.statistics` | qg_Z intervals from shot counts (Bayesian, Wilson, delta method); unbiased qg² and r² |
| `qang.qml` | weight-conserving QNN classifiers 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.qiskit_gate`, `qang.cirq_gate`, `qang.pennylane_gate` | native gates for the three SDKs (optional) |

---

## Installation

Install the minimal core library (NumPy only):
```bash
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 clone
```

```bash
pip 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 ".[qec]"      # Surface-code decoding examples (pymatching)
pip install ".[chemistry]" # PySCF/OpenFermion molecules (Linux/macOS or WSL)
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 itself
```

## Quickstart

### 1. Basic Unit Conversions & Inversion
```python
from 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-qg
```

### 2. Qiskit Native Gate Integration
```python
from 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)
```

### 3. Cirq Native Gate Integration
```python
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")
)
```

### 3b. PennyLane: optimize directly in qg_Z
```python
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 exactly
```

### 4. Error Propagation & Shot Budgeting
```python
from 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")
```

## Start here: gates and algorithms in qg

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Viny2030/qang/blob/main/notebooks/qang_start_here.ipynb) English &nbsp;·&nbsp;
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Viny2030/qang/blob/main/notebooks/qang_inicio_formulacion.ipynb) Español

`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 = <P> for every Pauli string) and a gate acts as qg'_P = qg_{U^dag P U}.
Article: `manuscript/qang_formulation.pdf` (Spanish draft: `manuscript/qang_teoria_es.pdf`).

```python
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). `F.algorithm_radii()` gives the radius of the readout qubits of the 14 algorithms.

## Quantum neural networks with and without qang

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Viny2030/qang/blob/main/notebooks/qang_qml.ipynb) English &nbsp;·&nbsp;
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Viny2030/qang/blob/main/notebooks/qang_qml_es.ipynb) Español

`qang.qml` (qang >= 0.6.4) 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
(70 so far in this line, §75–§98: 53 passed, 17 failed, all reported). Note: `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) | without qang the model catches up; with a rich readout and the pair-product encoding it is 1.2 points better (decayed shots carry information) |
| 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 |
| not corrected exactly | dephasing; unequal T1 (the filter still has the lower error, but is biased) |

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).

```python
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 T1
```

## Polarized light and geometric phase in qg units

[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Viny2030/qang/blob/main/notebooks/qang_optics.ipynb) English &nbsp;·&nbsp;
[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Viny2030/qang/blob/main/notebooks/qang_optics_es.ipynb) Español

`qang.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`).

## Full Reference Notebook

`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.
  [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Viny2030/qang/blob/main/notebooks/qang_avances_colab.ipynb)
* `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 PDF `manuscript/qang_criptografia.pdf`.
  [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/Viny2030/qang/blob/main/notebooks/qang_criptografia_colab.ipynb)

## Testing
The package includes an extensive test suite (1237 tests, run in CI on Python 3.9–3.12) verifying analytical anchors, numerical stability, gradient regularizations, backend fidelity, and every numerical finding quoted in `RESEARCH_NOTES.md`:

```bash
pytest -v
```

## Contributing & Community
We welcome contributions, bug reports, and suggestions!

Issues: Please use the [GitHub Issue Tracker](https://github.com/Viny2030/qang/issues) to report bugs or request features.

Contributions: See [CONTRIBUTING.md](CONTRIBUTING.md) for local development and pull request guidelines.

## Citation
If you use qang in your research, please cite the paper that defines the unit:

```bibtex
@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>.
