Metadata-Version: 2.4
Name: gravopt-qv
Version: 1.0.0
Summary: Hardware-informed quantum variational optimizer — W(t) physical telemetry gating for VQE/QAOA
Author-email: Dimitar Kretski <kretski1@gmail.com>
License: Apache-2.0
Project-URL: Homepage, https://github.com/Kretski/ORAC-QNode
Project-URL: Repository, https://github.com/Kretski/ORAC-QNode
Project-URL: Bug Tracker, https://github.com/Kretski/ORAC-QNode/issues
Project-URL: Documentation, https://github.com/Kretski/ORAC-QNode#readme
Keywords: quantum computing,variational quantum eigensolver,VQE,QAOA,shot reduction,quantum optimization,hardware protection,pennylane
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: Apache Software License
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Physics
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Requires-Python: >=3.9
Description-Content-Type: text/markdown
Requires-Dist: numpy>=1.22
Provides-Extra: pennylane
Requires-Dist: pennylane>=0.36; extra == "pennylane"
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov; extra == "dev"

# gravopt-qv

**Hardware-informed quantum variational optimizer**

> *"`qml.ShotAdaptiveOptimizer` solves the algorithmic side. `gravopt-qv` adds the signal PennyLane doesn't have — the hardware itself."*

`gravopt-qv` is a variational parameter optimizer for VQE, QAOA, and VQLS circuits that ingests **real-time physical telemetry** from control hardware and uses it to gate quantum evaluations. When your hardware is under thermal stress, component wear, or experiencing an SEU event — the optimizer pauses, preserves θ, and resumes when the system recovers.

[![PyPI version](https://img.shields.io/pypi/v/gravopt-qv.svg)](https://pypi.org/project/gravopt-qv/)
[![Python](https://img.shields.io/pypi/pyversions/gravopt-qv.svg)](https://pypi.org/project/gravopt-qv/)
[![License: Apache 2.0](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](https://opensource.org/licenses/Apache-2.0)
[![DOI](https://zenodo.org/badge/DOI/10.5281/zenodo.19019599.svg)](https://doi.org/10.5281/zenodo.19019599)

---

## Installation

```bash
pip install gravopt-qv
```

With PennyLane integration:

```bash
pip install "gravopt-qv[pennylane]"
```

---

## The problem it solves

Shot-adaptive optimizers like `qml.ShotAdaptiveOptimizer` (iCANS/Rosalin) reduce measurement overhead by reading **algorithmic signals** — gradient moments, operator sampling. They are excellent and free (Apache 2.0).

They do not observe the **physical state of the hardware executing the circuit.**

When a cryostat experiences thermal drift, when control electronics accumulate wear, or when an SEU occurs — the optimizer keeps issuing shots as if nothing happened. At 50 qubits this is rare. At 500+ qubits it becomes a persistent source of wasted evaluations and degraded gradient estimates.

`gravopt-qv` adds the missing signal: **W(t)**, a vitality score from the physical layer.

---

## Quick start

```python
from gravopt_qv import GravOptAdaptiveE_QV, ORACTelemetry

# 1. Your variational cost function
def my_vqe_cost(theta, shots):
    # Replace with your PennyLane QNode or Qiskit Estimator
    import numpy as np
    noise = np.random.normal(0, 0.3 / max(shots**0.5, 1))
    return float(np.sum(np.cos(theta))) + noise

# 2. Telemetry source (mock for testing — replace with real L1 reader)
telemetry_fn = lambda: ORACTelemetry.mock(W=0.72, E_norm=0.18)

# 3. Initialize
opt = GravOptAdaptiveE_QV(
    cost_fn=my_vqe_cost,
    n_params=6,
    telemetry_fn=telemetry_fn,
    lr=0.05,
    base_shots=1024,
    gradient_method="parameter_shift",
)

# 4. Run
report = opt.optimize(n_steps=100)
print(f"Shot savings:  {report['saving_pct']:.1f}%")
print(f"Final loss:    {report['final_loss']:.5f}")
print(f"Steps skipped: {report['skipped_steps']}")
```

---

## How it works

### W(t) — the physical vitality score

```
W(t) = Q·D − χ(wear)·T_norm − E_norm·0.22 + phase·0.098 − κ·U(t)
```

Produced by the ORAC-NT bare-metal hardware shield (L1, running on STM32F4). In `gravopt-qv`, it arrives via `ORACTelemetry` — either from real hardware (serial/SPI) or mocked for simulation.

### Three gating mechanisms

**1. W-Gate (full pause)**
`W < −0.12` → zero shots, θ preserved. Protects against noisy gradient estimates during hardware faults.

**2. Shot budget scaling**

| Status | W Range | Shot budget |
|:---|:---|:---|
| RESONANT | ≥ 0.45 | 100% |
| HEALTHY | 0.30 – 0.44 | 70% |
| WARM | 0.00 – 0.29 | 40% |
| Sub-zero | < 0.00 | 10% |
| CRITICAL / EMERGENCY | — | 0% |

**3. Hardware-informed gradient freeze**
Freeze percentile is driven by `E_norm` (thermal load), not gradient statistics:

| E_norm | Params frozen |
|:---|:---|
| < 0.20 | 10% |
| 0.20 – 0.49 | 25% |
| 0.50 – 0.79 | 45% |
| ≥ 0.80 | 65% |

---

## Scaling benchmark

Value increases with QPU size — because hardware stress frequency increases with system complexity:

| QPU Scale | Hardware stress | Shots saved | Steps skipped |
|:---|:---|:---|:---|
| ~50 qubits (6 params) | 15% of steps | **9%** | 0% |
| ~500 qubits (20 params) | 28% of steps | **20%** | 8% |
| ~5k+ qubits (50 params) | 48% of steps | **36%** | 18% |

All scenarios converged to global minimum despite gating.
*Simulation: 100 steps · parameter-shift gradient · base_shots=512 · physically motivated stress profiles.*

---

## Real hardware integration

`gravopt-qv` (L2, this package) is designed to pair with **ORAC-NT** (L1, bare-metal C shield):

```python
# Replace mock with real STM32F4 serial reader
import serial

def real_telemetry_fn():
    # Read W and E_norm from ORAC-NT over serial
    line = ser.readline().decode().strip()
    W, E_norm, status = parse_orac_output(line)
    return ORACTelemetry(W=W, E_norm=E_norm, T_norm=0.0, phase=1.0, status=status)

opt = GravOptAdaptiveE_QV(
    cost_fn=my_qnode,
    n_params=12,
    telemetry_fn=real_telemetry_fn,
    ...
)
```

ORAC-NT repository (L1, proprietary): [github.com/Kretski/ORAC-QNode](https://github.com/Kretski/ORAC-QNode)
For hardware licensing: kretski1@gmail.com

---

## Gradient methods

| Method | Shots/step | Accuracy | Recommended for |
|:---|:---|:---|:---|
| `parameter_shift` | 2 per param | Exact | Real QPU |
| `finite_diff` | 1 per param + 1 | Approximate | Simulators |

---

## Honest limitations

- Benchmark on synthetic cost function (not molecular Hamiltonian)
- No head-to-head comparison with `qml.ShotAdaptiveOptimizer` at equal total shot budget yet
- Real hardware pilot (CHA-BAS pump systems, STM32F4) in preparation

---

## Citation

```bibtex
@software{kretski_gravopt_qv_2026,
  author  = {Kretski, Dimitar},
  title   = {gravopt-qv: Hardware-informed quantum variational optimizer},
  year    = {2026},
  url     = {https://github.com/Kretski/ORAC-QNode},
  doi     = {10.5281/zenodo.19019599},
  version = {1.0.0}
}
```

---

## License

Apache License 2.0 — free for academic and commercial use.

The underlying ORAC-NT hardware shield (L1) is proprietary.
For hardware integration licensing: **kretski1@gmail.com**

---

*Dimitar Kretski — Independent Researcher*
*Center for Hydro- and Aerodynamics, Bulgarian Academy of Sciences, Varna, Bulgaria*
*ORCID: [0000-0001-5108-2243](https://orcid.org/0000-0001-5108-2243)*
