Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
15 commits
Select commit Hold shift + click to select a range
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Reihenfolge: §1 Working agreements > §2 Conventions > §3 Don't > §4 When stu
## Project
- **Was:** Adaptiver RG-QEC-Simulator als **Diagnostik-/Verifikations-Harness mit Konvergenz-Guards** (KEIN Frontier-Threshold-Tool). Spec/Theorie + lauffähiger Phase-1-MVP (seit PR#4).
- **Inhalt:** gehärtete Kernel-Spec v1.0 + Proof-Block v1.1 / KernelSpec v1.2 (`spec/`) + Phase-1-MVP-Code (`src/adaptiverg_qec/`, `tests/`, CI).
- **MVP-Stand:** real = A-Kernel-MCMC + Foster-Lyapunov-Drift-Guard + MCRG-Map/Jacobian + **skalarer Swendsen-MCRG-Schätzer** (sample-geschätzte R̂ `T̂=⟨S'S⟩_c/⟨S'S'⟩_c` vs `tanh(2K)` validiert; 1D-Ising-Instanz). **Phase-3a (NEU): T̂ aus dem korrelierten A-Kernel-MCMC (statt exakt-i.i.d.) mit autokorrelations-bewussten Fehlerbalken** — `autocorr.py`: FFT-ρ (Wiener-Khinchin), τ_int + Wolff-g-Windowing, Binning-Cross-Check, Block-Jackknife fürs Verhältnis; belegt N_eff<N und σ_korr>σ_iid (`results/phase3a-akernel-autocorr.json`). **Phase-3b (NEU): Multi-Operator-Swendsen-MATRIX auf 2D-Ising** — `ising2d.py` (vektorisierter Checkerboard-Metropolis + Majority-Rule-Blocking b=2) + `mcrg_matrix.py` (gerade Operatoren S₁/S₂/S₃, connected-corr-Matrizen A,B, `T=A·B⁻¹` via `np.linalg.solve`, Eigenwert-Exponenten, Block-Jackknife). y_t=0.97±0.01 vs Onsager-Orakel y_t=1 — **ehrlich GROB** (single-spin + 1 RG-Stufe → kritisches Slowing-Down; Plausibilität, KEIN Frontier-Wert), `results/phase3b-swendsen-matrix.json`. **Phase-4 (NEU): Wolff-Cluster + Multi-RG + y_h** — `wolff2d.py` (Wolff-Single-Cluster, `P_add=1−e^{−2K}`, vektorisierter BFS, rejection-free; Energie vs exakte L=4-Enum |err|<0.008; `τ_int(Wolff)≪τ_int(Metropolis)`, ×12–16 @ L=32) + `mcrg_multirg.py` (iterierte Majority-Stufen L=32→16→8→4: gerader y_t konvergiert, bester `|y_t−1|≈0.006` vs 3b 0.035; ungerade Operatoren O₁=M, O₂=3-Spin-L-Cluster → ungerade Swendsen-Matrix `T_h=A·B⁻¹` → y_h, bester Iterationswert `|y_h−15/8|≈0.002` (Minimum über Iterationen, NICHT tiefste Stufe; tiefste-Iter ≈0.003) vs Onsager y_h=15/8=1.875). Gates G24–G29, `results/phase4-wolff-multirg.json`. **Ehrlich:** Rest-finite-Size bleibt, KEINE L→∞-FSS, KEIN Frontier-Wert. **Phase-5 (NEU): CLT-Varianz σ²_g + R̂-Multichain + Run-Manifest** — `clt.py` (MCMC-CLT `σ²_g=2·τ_int·Var(g)` via Γ-Methode + UNABHÄNGIGER OBM-Schätzer Flegal-Jones; gegen geschlossene AR(1)-Form `σ²_g=σ²_ε/(1−φ)²` validiert, φ=0.8 Orakel 25.0 → Γ rel.0.010/OBM rel.0.020; Coverage beidseitig: korrekt 0.937 vs iid-falsch 0.490), `rhat.py` (rank-normalized split-R̂ + folded-R̂ + bulk/tail-ESS nach Vehtari et al. 2021 doi:10.1214/20-BA1221; A-Kernel M=4 → R̂=1.0003 converged; beidseitig: Mittel-Drift R̂=1.62 bulk / Skalen-Drift R̂=1.27 folded>bulk), `manifest.py` + CLI `phase5 --from-manifest` (Seeds/Parameter/Versionen/git-SHA/Plattform; byte-identische Reproduktion via SHA-256 result_hash; beidseitig: Round-trip==Hash, geänderter Seed→anderer Hash). Gates G33–G38, `results/phase5-clt-rhat-manifest.json`. **Phase-6 (NEU): SNIS + Surrogate-DA + Checkpoint/Restart-Lockfile — schliesst die drei dokumentierten Phase-4/5-Lücken.** `snis.py` (Self-Normalized Importance Sampling auf der offenen 1D-Ising-Kette; χ²-Divergenz GESCHLOSSEN `[cosh(2K_t−K_p)cosh(K_p)/cosh²(K_t)]^{L−1}−1` → Orakel für ESS `1/(1+χ²)`, führenden O(1/N)-Bias `(1+χ²)(tanh K_t−tanh(2K_t−K_p))/N` und MSE-Bound `4(1+χ²)/N` (Agapiou et al. 2017); ESS-Kollaps-Guard beidseitig), `surrogate.py` (Delayed-Acceptance-Metropolis nach Christen & Fox 2005, Surrogat `β̃=β(1+γ)`; γ=0 BIT-IDENTISCH zum Metropolis-A-Kernel, miskalibriertes Surrogat bleibt exakt vs Transfer-Matrix-Orakel; Surrogate-Drift-Guard feuert/hält beidseitig), `checkpoint.py` (Philox-State-Serialisierung + gemeinsamer `advance_chain`/`postprocess_multichain`-Code-Pfad → Interrupt+Resume ergibt BYTE-IDENTISCHEN `result_hash`; O_EXCL-Lockfile + SHA-256-Integritäts-Hash fail-closed). Gates G39–G45, `results/phase6-snis-surrogate-checkpoint.json`, CLI `phase6`. Zusätzlich Audit-Härtung: zell-eigene Seeds in QEC-Sweeps (vorher rangkorrelierte Zellen), Jeffreys-regularisierte `std_err` (Null-Ereignis-Zellen falsifizierbar), `n_sigma` auf SEM statt Einzel-Seed-std (√8 strenger), R̂ erkennt konstante Ketten mit verschiedenen Mitteln (vorher „converged"), Manifest-`__post_init__`-Validierung, rg_map-dtype-Fix. Selftest gesamt **45/45 [PASS]**. Keine neuen Deps. Offen (ehrlich, NICHT erledigt): Defensive Mixture, SNIS auf 2D/RBIM-Targets, DA×Diminishing-Adaptation-Kombination, MMD-Drift; bekannte dokumentierte Limitationen: Majority-Tie-Break nicht Z2-äquivariant (`ising2d.majority_block_b2`), RBIM-Scan nutzt gemeinsame Seeds über p (common random numbers), τ_int-Clamp ≥0.5 (konservativ bei Anti-Korrelation).
- **MVP-Stand:** real = A-Kernel-MCMC + Foster-Lyapunov-Drift-Guard + MCRG-Map/Jacobian + **skalarer Swendsen-MCRG-Schätzer** (sample-geschätzte R̂ `T̂=⟨S'S⟩_c/⟨S'S'⟩_c` vs `tanh(2K)` validiert; 1D-Ising-Instanz). **Phase-3a (NEU): T̂ aus dem korrelierten A-Kernel-MCMC (statt exakt-i.i.d.) mit autokorrelations-bewussten Fehlerbalken** — `autocorr.py`: FFT-ρ (Wiener-Khinchin), τ_int + Wolff-g-Windowing, Binning-Cross-Check, Block-Jackknife fürs Verhältnis; belegt N_eff<N und σ_korr>σ_iid (`results/phase3a-akernel-autocorr.json`). **Phase-3b (NEU): Multi-Operator-Swendsen-MATRIX auf 2D-Ising** — `ising2d.py` (vektorisierter Checkerboard-Metropolis + Majority-Rule-Blocking b=2) + `mcrg_matrix.py` (gerade Operatoren S₁/S₂/S₃, connected-corr-Matrizen A,B, `T=A·B⁻¹` via `np.linalg.solve`, Eigenwert-Exponenten, Block-Jackknife). y_t=0.97±0.01 vs Onsager-Orakel y_t=1 — **ehrlich GROB** (single-spin + 1 RG-Stufe → kritisches Slowing-Down; Plausibilität, KEIN Frontier-Wert), `results/phase3b-swendsen-matrix.json`. **Phase-4 (NEU): Wolff-Cluster + Multi-RG + y_h** — `wolff2d.py` (Wolff-Single-Cluster, `P_add=1−e^{−2K}`, vektorisierter BFS, rejection-free; Energie vs exakte L=4-Enum |err|<0.008; `τ_int(Wolff)≪τ_int(Metropolis)`, ×12–16 @ L=32) + `mcrg_multirg.py` (iterierte Majority-Stufen L=32→16→8→4: gerader y_t konvergiert, bester `|y_t−1|≈0.006` vs 3b 0.035; ungerade Operatoren O₁=M, O₂=3-Spin-L-Cluster → ungerade Swendsen-Matrix `T_h=A·B⁻¹` → y_h, bester Iterationswert `|y_h−15/8|≈0.002` (Minimum über Iterationen, NICHT tiefste Stufe; tiefste-Iter ≈0.003) vs Onsager y_h=15/8=1.875). Gates G24–G29, `results/phase4-wolff-multirg.json`. **Ehrlich:** Rest-finite-Size bleibt, KEINE L→∞-FSS, KEIN Frontier-Wert. **Phase-5 (NEU): CLT-Varianz σ²_g + R̂-Multichain + Run-Manifest** — `clt.py` (MCMC-CLT `σ²_g=2·τ_int·Var(g)` via Γ-Methode + UNABHÄNGIGER OBM-Schätzer Flegal-Jones; gegen geschlossene AR(1)-Form `σ²_g=σ²_ε/(1−φ)²` validiert, φ=0.8 Orakel 25.0 → Γ rel.0.010/OBM rel.0.020; Coverage beidseitig: korrekt 0.937 vs iid-falsch 0.490), `rhat.py` (rank-normalized split-R̂ + folded-R̂ + bulk/tail-ESS nach Vehtari et al. 2021 doi:10.1214/20-BA1221; A-Kernel M=4 → R̂=1.0003 converged; beidseitig: Mittel-Drift R̂=1.62 bulk / Skalen-Drift R̂=1.27 folded>bulk), `manifest.py` + CLI `phase5 --from-manifest` (Seeds/Parameter/Versionen/git-SHA/Plattform; byte-identische Reproduktion via SHA-256 result_hash; beidseitig: Round-trip==Hash, geänderter Seed→anderer Hash). Gates G33–G38, `results/phase5-clt-rhat-manifest.json`. **Phase-6 (NEU): SNIS + Surrogate-DA + Checkpoint/Restart-Lockfile — schliesst die drei dokumentierten Phase-4/5-Lücken.** `snis.py` (Self-Normalized Importance Sampling auf der offenen 1D-Ising-Kette; χ²-Divergenz GESCHLOSSEN `[cosh(2K_t−K_p)cosh(K_p)/cosh²(K_t)]^{L−1}−1` → Orakel für ESS `1/(1+χ²)`, führenden O(1/N)-Bias `(1+χ²)(tanh K_t−tanh(2K_t−K_p))/N` und MSE-Bound `4(1+χ²)/N` (Agapiou et al. 2017); ESS-Kollaps-Guard beidseitig), `surrogate.py` (Delayed-Acceptance-Metropolis nach Christen & Fox 2005, Surrogat `β̃=β(1+γ)`; γ=0 BIT-IDENTISCH zum Metropolis-A-Kernel, miskalibriertes Surrogat bleibt exakt vs Transfer-Matrix-Orakel; Surrogate-Drift-Guard feuert/hält beidseitig), `checkpoint.py` (Philox-State-Serialisierung + gemeinsamer `advance_chain`/`postprocess_multichain`-Code-Pfad → Interrupt+Resume ergibt BYTE-IDENTISCHEN `result_hash`; O_EXCL-Lockfile + SHA-256-Integritäts-Hash fail-closed). Gates G39–G45, `results/phase6-snis-surrogate-checkpoint.json`, CLI `phase6`. Zusätzlich Audit-Härtung: zell-eigene Seeds in QEC-Sweeps (vorher rangkorrelierte Zellen), Jeffreys-regularisierte `std_err` (Null-Ereignis-Zellen falsifizierbar), `n_sigma` auf SEM statt Einzel-Seed-std (√8 strenger), R̂ erkennt konstante Ketten mit verschiedenen Mitteln (vorher „converged"), Manifest-`__post_init__`-Validierung, rg_map-dtype-Fix. Selftest gesamt **45/45 [PASS]**. Keine neuen Deps. Offen (ehrlich, NICHT erledigt): Defensive Mixture, SNIS auf 2D/RBIM-Targets, DA×Diminishing-Adaptation-Kombination, MMD-Drift; bekannte dokumentierte Limitationen: τ_int-Clamp ≥0.5 (konservativ bei Anti-Korrelation). **Z2/Seed-Härtung (NEU):** `ising2d.majority_block_b2` löst 2+2-Ties jetzt durch Auswahl eines der vier Original-Spins des Blocks → `B(-s) == -B(s)` gilt konstruktiv exakt statt nur im Mittel; die dadurch verschobenen Phase-3b/4-Referenzwerte (G32, `test_fix3_central_values_unchanged`) wurden neu erhoben, die externen Onsager-Gates G22/G27/G28 blieben PASS. `rbim_scan.py` macht die Stream-Politik explizit (`SeedSequence` + `spawn(2)`, Default `independent`; CRN nur als benannte Option); die historische `rbim_nishimori`-Baseline behält bewusst ihre additiven Seeds. Offen: Regeneration der `results/`-Artefakte.

## Working agreements
1. **Kein Overclaim „implementiert".** `src/` enthält den Phase-1-MVP; README/SOURCES/Status nennen ehrlich, was MVP-real vs. gestubbt ist (stochastische R̂, SNIS, Multichain offen). Keine Komponente als „validiert" behaupten ohne lauffähigen Code + Gate-Log in `results/`.
Expand Down
29 changes: 22 additions & 7 deletions docs/ROADMAP.md
Original file line number Diff line number Diff line change
Expand Up @@ -141,13 +141,28 @@ Duplikat-p-Guard; Surface-Threshold-Fenster verbreitert (0.09–0.115, 80k Shots
`crossing_found`-Flag statt stillem NaN.

**Bekannte, BEWUSST nicht in diesem Inkrement gefixte Limitationen (dokumentiert, Follow-up):**
- `ising2d.majority_block_b2`-Tie-Break ist deterministisch, aber nicht Z2-äquivariant
(Tie-Break flippt nicht unter s→−s); in-Repo-Aufrufer übergeben `config_index`, der Effekt
ist im Rahmen der ausgewiesenen Grobheit enthalten. Ein äquivarianter Fix ändert alle
committeten Phase-3b/4-Baselines (inkl. G32-Goldwerte) und gehört in ein eigenes Inkrement.
- `rbim_nishimori`-Scan nutzt denselben `base_seed` über alle p (common random numbers über
die Kurve; Disorder-Realisierungen über p genestet) — die p*-Lokalisierung bleibt auf
Plausibilitäts-Niveau, wie ausgewiesen.
- ~~`ising2d.majority_block_b2`-Tie-Break nicht Z2-äquivariant~~ — **erledigt.** Der Tie-Break
wählt jetzt einen der vier Original-Spins des 2x2-Blocks, womit `B(-s) == -B(s)` konstruktiv
exakt gilt (vorher nur im Mittel 50/50). Wie hier vorhergesagt hat der Fix die committeten
Phase-3b/4-Referenzwerte verschoben: die G32-/`test_fix3_central_values_unchanged`-Werte
wurden unter dem äquivarianten Tie-Break neu erhoben (Herleitung im jeweiligen Docstring),
die externen Onsager-Gates G22/G27/G28 blieben unverändert PASS. **Evidenz nachgezogen:**
die drei Artefakte, die die Blocking-Regel berühren, wurden aus diesem Commit neu erzeugt —
`results/phase3b-swendsen-matrix.json` (`python -m adaptiverg_qec.mcrg_matrix`, 18 s),
`results/phase4-wolff-multirg.json` (`python -m adaptiverg_qec.mcrg_multirg`, 135 s) und der
Gate-Log `results/selftest.json`
(`python -m adaptiverg_qec.cli --selftest --json results/selftest.json`, 414 s, 45/45 PASS).
Nur diese drei sind betroffen: `majority_block_b2` wird ausschliesslich von `mcrg_matrix` und
`mcrg_multirg` aufgerufen. Ein Gate-Log, der eine Transformation beschreibt, die es in diesem
Commit nicht mehr gibt, wäre irreführend — auch wenn ihn kein Test liest.
- `rbim_nishimori`-Scan (historische Baseline, bewusst unverändert) nutzt weiterhin
arithmetische Seeds `base_seed + d` / `base_seed + 10000 + d` — also implizite common random
numbers über p. Der neue Pfad `rbim_scan.py` macht die Wahl explizit: Default
`seed_policy="independent"` mischt `p`/`L`/Replikat über `SeedSequence` und trennt Bond- und
Thermal-Strom per `spawn(2)`; CRN ist nur noch als ausdrückliche Option erreichbar.
**Offen an der Baseline:** die additive Ableitung lässt Bond- und MCMC-Seeds ab
`n_disorder >= 10001` exakt überlappen (`base_seed + 10000` tritt in beiden Familien auf);
`n_disorder` ist nur gegen `< 1` geprüft.
- `autocorr.integrated_autocorr_time` klemmt τ_int ≥ 0.5 (für anti-korrelierte Reihen bewusst
konservativ; jetzt im Code dokumentiert).
- G26 vergleicht τ_int in Update-Einheiten (1 Wolff-Cluster vs 1 Metropolis-Sweep), nicht
Expand Down
22 changes: 14 additions & 8 deletions pyproject.toml
Original file line number Diff line number Diff line change
@@ -1,21 +1,22 @@
[build-system]
requires = ["setuptools>=68"]
requires = ["setuptools>=77.0.3"]
build-backend = "setuptools.build_meta"

[project]
name = "adaptiverg-qec"
version = "0.1.0.dev0"
description = "AdaptiveRG-QEC Phase-1 MVP: Diagnostik-/Verifikations-Harness mit Konvergenz-Guards (MCMC + minimaler MCRG)."
description = "AdaptiveRG-QEC diagnostics and verification harness for MCMC, MCRG, and quantum-error-correction experiments."
readme = "README.md"
requires-python = ">=3.12"
license = { text = "Apache-2.0" }
license = "Apache-2.0"
license-files = ["LICENSE"]
authors = [{ name = "Coworker Research" }]
keywords = ["qec", "mcmc", "renormalization-group", "foster-lyapunov", "diagnostics"]
classifiers = [
"Development Status :: 3 - Alpha",
"Intended Audience :: Science/Research",
"License :: OSI Approved :: Apache Software License",
"Programming Language :: Python :: 3",
"Programming Language :: Python :: 3.12",
"Topic :: Scientific/Engineering :: Physics",
]
dependencies = [
Expand All @@ -25,14 +26,18 @@ dependencies = [

[project.optional-dependencies]
dev = ["pytest>=7.4", "ruff>=0.5"]
# Inkrement-3: ECHTES MWPM-Decoding hinter optional-dependency-Gate.
# Ohne dieses Extra importiert surface_decoder.py nicht und seine Tests SKIPPEN
# (sie failen NICHT hart). Kein Eigen-Decoder: Stim (Sampling) + PyMatching 2 (MWPM).
# Real MWPM decoding behind an optional dependency gate. Keep decoder
# dependencies out of the core install so the analytical/MCMC harness remains
# lightweight and independently testable.
surface = ["stim>=1.13", "pymatching>=2.1"]

[project.scripts]
adaptiverg-qec = "adaptiverg_qec.cli:main"

[project.urls]
Repository = "https://github.com/marcohost33-maker/qec-engine"
Issues = "https://github.com/marcohost33-maker/qec-engine/issues"

[tool.setuptools.packages.find]
where = ["src"]

Expand All @@ -48,7 +53,8 @@ src = ["src", "tests"]

[tool.ruff.lint]
select = ["E", "F", "I", "B", "UP", "SIM"]
# B008: scipy/numpy style; allow defaults. We keep strict otherwise.
# B904 is intentionally ignored for compatibility with existing exception
# chaining style. Keep this comment synchronized with the configured rule.
ignore = ["B904"]

[tool.ruff.lint.per-file-ignores]
Expand Down
70 changes: 35 additions & 35 deletions results/phase3b-swendsen-matrix.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,68 +16,68 @@
"rows": [
{
"seed": 0,
"y_t": 0.9620743073104707,
"y_t_error_jackknife": 0.01282754451200649,
"abs_error_vs_oracle": 0.03792569268952928,
"n_sigma": 2.956582427293945,
"lambda_max": 1.9481088736086845,
"cond_B": 87.26739243966706,
"tau_int_max": 4.292362206104164,
"y_t": 0.9721966879350383,
"y_t_error_jackknife": 0.013094867322879159,
"abs_error_vs_oracle": 0.02780331206496167,
"n_sigma": 2.123222128137498,
"lambda_max": 1.9618254526442591,
"cond_B": 89.95801868899628,
"tau_int_max": 4.1479082343668985,
"block_size": 9,
"n_blocks": 666,
"n_samples": 6000,
"eigenvalues_abs": [
1.9481088736086845,
0.20520006968096904
1.9618254526442591,
0.21590292842653014
],
"exponents": [
0.9620743073104707,
-2.2848968740380515
0.9721966879350383,
-2.211545283218558
]
},
{
"seed": 1,
"y_t": 0.9747667403326046,
"y_t_error_jackknife": 0.012729263847867515,
"abs_error_vs_oracle": 0.025233259667395425,
"n_sigma": 1.9823031377908515,
"lambda_max": 1.9653234114638973,
"cond_B": 88.49498716449236,
"tau_int_max": 4.754650650677398,
"y_t": 0.9609243556959352,
"y_t_error_jackknife": 0.013187918611818722,
"abs_error_vs_oracle": 0.03907564430406485,
"n_sigma": 2.962987978182252,
"lambda_max": 1.9465566825425507,
"cond_B": 88.81785823291553,
"tau_int_max": 4.691073292390602,
"block_size": 10,
"n_blocks": 600,
"n_samples": 6000,
"eigenvalues_abs": [
1.9653234114638973,
0.18004396177200732
1.9465566825425507,
0.22382184954666418
],
"exponents": [
0.9747667403326046,
-2.4735788789618196
0.9609243556959352,
-2.1595772154364883
]
},
{
"seed": 2,
"y_t": 0.9586219810979993,
"y_t_error_jackknife": 0.013977778172939664,
"abs_error_vs_oracle": 0.04137801890200066,
"n_sigma": 2.960271538870648,
"lambda_max": 1.943452680453265,
"cond_B": 89.74556191382386,
"tau_int_max": 3.5879848820483846,
"y_t": 0.9482400730709694,
"y_t_error_jackknife": 0.013477340065490635,
"abs_error_vs_oracle": 0.05175992692903064,
"n_sigma": 3.8405150183576935,
"lambda_max": 1.9295174256779086,
"cond_B": 93.55665165239814,
"tau_int_max": 3.552955853157631,
"block_size": 8,
"n_blocks": 750,
"n_samples": 6000,
"eigenvalues_abs": [
1.943452680453265,
0.24657952643829528
1.9295174256779086,
0.23995835909788088
],
"exponents": [
0.9586219810979993,
-2.0198750775154
0.9482400730709694,
-2.0591440237836443
]
}
],
"y_t_mean": 0.9651543429136916,
"y_t_multiseed_spread": 0.008501663200437526
"y_t_mean": 0.9604537055673142,
"y_t_multiseed_spread": 0.011985240197593486
}
Loading