Qiskit Aer accepts crisp numbers for noise. Real superconducting qubits drift between every IBM calibration. We close the gap with a Takagi·Sugeno·Kang fuzzy inference layer that turns calibration snapshots into an ensemble of NoiseModel instances, then aggregates simulations into interval-valued predictions that bracket real hardware across calibration cycles.
Crisp calibration-based noise models match real hardware tightly on the snapshot they were tuned on and degrade silently once that snapshot goes stale. Transferability across calibration cycles is the rope we're trying to climb past that limit · the fuzzy envelope is what gives the ensemble somewhere to go when the calibration moves.
flowchart LR
A[IBM<br/>Calibration<br/>Snapshot] --> B[Feature<br/>Extraction]
B --> C[Fuzzification<br/>+ TSK Rules]
C --> D[Defuzzification]
D --> E[Squashing]
E --> F[Channel<br/>Projection]
F --> G[Aer<br/>NoiseModel<br/>Ensemble]
G --> H((Interval<br/>Prediction))
classDef stage fill:#1e1b4b,stroke:#06b6d4,stroke-width:1px,color:#fff;
classDef io fill:#0b0d17,stroke:#7f5af0,stroke-width:1.5px,color:#fff;
class A,H io;
class B,C,D,E,F,G stage;
Six stages, one Factory · Ensemble at the seam with Aer. The no-per-shot-Python-hook constraint is respected by realising epistemic uncertainty at ensemble construction time, not at simulation time.
Architecture detail: docs/architecture.md · Decision ledger (ADRs): docs/decisions.md
A crisp T1 = 142 µs is what Aer wants. A real backend that just got recalibrated wants a range of plausible values weighted by membership. We fuzzify the snapshot through the TSK rule base, sample N concrete NoiseModel instances from the resulting envelope, run each through Aer in parallel, and report [p_lo, p_hi] instead of a single fidelity number. The win is that the real IBM datapoint lives inside the interval the next time the backend gets recalibrated, which is what crisp baselines stop doing the moment the snapshot they were tuned on goes stale.
A Type-1 TSK rule asks for the membership of a calibration value and gets back a single number: μ(T1 = 142 µs) = 0.85. The curve commits to an exact membership grade at every point, and it commits to an exact T1 where that membership peaks. We don't have that much confidence: calibration drift moves not just the parameter, but our belief about the parameter, including where the "prototypical" value sits.
Interval Type-2 (IT2) loosens both at once. Membership at each calibration value becomes an interval: μ(T1 = 142 µs) ∈ [0.55, 0.85]. The peak becomes a plateau rather than a point, because we're not sure exactly where the membership function tops out either. The band between the upper membership function (UMF) and the lower membership function (LMF) is the footprint of uncertainty · it says "the membership function lives somewhere in here, and we don't insist on which curve, or on where exactly it peaks."
The ensemble we sample from an IT2-TSK rule base is correspondingly richer than what a Type-1 base could produce. That extra richness is exactly why the interval prediction in the previous diagram brackets real hardware across cycles instead of just the snapshot it was tuned on. T1 is the noise channel; T2 is how unsure we're allowed to be about it.
Phase 0 deliverable is live.
superconducted-pollarchives IBM backend calibration snapshots, driven by a GitHub Actions workflow that fires hourly againstibm_fez. Phase 1 is dataset accumulation: targeting ~24 snapshots/day, with the ≥ 630 ANFIS-training floor projected for mid-July 2026.
The lab log. Most recent on top. Each entry links to the issue, PR, or ADR it came from.
- Phase 0 · shipped. Calibration polling pipeline went live with the
superconducted-pollconsole script. Cron-friendly, idempotent, one invocation per round. → flagship repo - ADR · Factory · Ensemble pattern adopted. Aer's no-per-shot-Python-hook constraint forced the design hand: epistemic uncertainty has to be realised at ensemble construction time, not per shot. →
docs/decisions.md - Hourly polling, in CI. The
Calibration PollingGitHub Actions workflow fires at HH:05 every hour, runssuperconducted-poll --backend ibm_fez, and verifies the poller produced files before committing. Concurrency control keeps overlapping runs from racing each other. - Git as the calibration database. Snapshots are committed to a dedicated
calibration-databranch, organised assnapshots/YYYY-MM/ibm_fez/*.json. Keepsmainclean; provenance is justgit log. Historical backfill remains capped at 30 days viaSUPERCONDUCTED_HISTORICAL_MAX_DAYS. - Audit · first ADR cycle closed. 22 ADRs reviewed, 2 patched in
place, 6 new drafts, 8 follow-up issues filed. The full synthesis
lives under
docs/state-of-the-project/. → audit report
Want to write the next entry? See the open issues on the flagship.
Quick start · clone, install, test
git clone https://github.com/SuperconducTED/superconducted-noise-engine.git
cd superconducted-noise-engine
python -m venv .venv
# Windows: .venv\Scripts\activate
# POSIX: source .venv/bin/activate
pip install -r requirements.txt -r requirements-dev.txt
pip install -e . --no-deps
pytestDrop your IBM Quantum token into .env (template at .env.example) and run superconducted-poll --backend ibm_fez.
Glossary · for non-quantum visitors
| TSK | Takagi·Sugeno·Kang fuzzy inference. Rules of the form "if x is A then y = f(x)" where f is a crisp function. Maps calibration features to noise parameters. |
| IT2 | Interval Type·2 fuzzy set. The membership grade is itself an interval, not a single number. Encodes uncertainty about where the membership function lives. |
| ANFIS | Adaptive Network-based Fuzzy Inference System. A neural-style architecture for learning TSK rule parameters from data. Needs a non-trivial dataset, hence the ≥ 630 snapshot floor. |
| T1 / T2 | Energy relaxation time and decoherence time of a qubit, in microseconds. The two dominant noise channels on superconducting hardware. |
| Aer | Qiskit's high-performance simulator. Accepts a NoiseModel, but only as crisp scalar parameters. |
| NoiseModel | Qiskit's bundle of Kraus operators and channels applied to specific gates and qubits. The thing we ensemble. |
| Calibration snapshot | A point-in-time export of IBM backend properties (T1, T2, gate errors, readout errors) from the IBM Quantum API. |
| Fidelity | A scalar in [0, 1] measuring how close a simulated output distribution is to a real one. Standard quality metric. |
| Cooper pair | The bound electron pair responsible for superconductivity in the transmon qubits IBM hardware uses. Out of scope for the code, in scope for the vibes. |
FAQ · the questions we keep getting
Why fuzzy logic, not Bayesian inference? Bayesian priors want a joint distribution over noise parameters. We don't have one. We have expert intuition about which parameter ranges stay plausible after a calibration drift, which is exactly what TSK rules express. Fuzzy is the right hammer for ordinal, linguistic, sparse-data uncertainty. A Bayesian cross-check is on the roadmap, not a replacement.
Why only IBM backends? The IBM Quantum API exposes a uniform calibration schema across all transmon backends, which makes polling and feature extraction reproducible. Other vendors (IonQ, Rigetti, Quantinuum) characterise noise differently (e.g. trapped-ion gates aren't parameterised the same way). Multi-vendor support is a Phase 4 conversation, not a Phase 1 one.
Why Aer, not pulse-level simulation? Aer is the standard. Pulse-level simulators (Qiskit Dynamics and friends) are more accurate per snapshot but slower by orders of magnitude. Our value proposition is transferability across snapshots, so we want the fast inner loop. The fuzzy envelope absorbs the per-snapshot accuracy gap.
What's the ≥ 630 number? The team's working minimum for ANFIS training · enough historical records that rule consequents can be fit without overfitting. At hourly polling against ibm_fez, with realistic GitHub Actions scheduler losses factored in, reaching the floor takes roughly two months from the start of cycle 1 polling.
Can I use this without an IBM Quantum account? For the polling stage, no. For the noise modeling stage, yes: bring your own calibration JSON in the documented schema and the engine doesn't care where it came from.
Why fuzzy on the outside of Aer instead of inside the noise channel?
Aer's simulator loop is C++. There's no Python hook per shot. The Factory · Ensemble pattern was the cleanest way to keep Aer fast and still get a fuzzy result: build many crisp NoiseModel instances up front, simulate each, aggregate at the end.
Why fuzzy, why now · the long version
Aer's noise model is a single point in parameter space. Real backends move. The literature reports excellent fidelity on the snapshot it was tuned on, then degrades silently when calibration shifts. Interval Type·2 fuzzy systems let us encode epistemic uncertainty (we don't know exactly where the backend is right now) on top of the aleatoric noise Aer already handles. Ensemble construction respects Aer's no-per-shot-Python-hook constraint. It's the kind of fit that only looks obvious once you stop trying to make a single number do two jobs.
The lab · five contributors + faculty advisor
The lab sits inside the Computer Engineering program at TED University, Ankara. Module ownership and the contributor roster live in docs/team.md.
Contributing
- Open issues live on the flagship repo.
- Run
pytestbefore pushing. CI mirrors local. - Architectural changes go through an ADR in
docs/decisions.md. - Never commit a real
IBM_QUANTUM_TOKEN..envis gitignored;.env.exampleis the template.
Made in Ankara · powered by curiosity, caffeine, and Cooper pairs.