Parameter sweep as a first-class object
One `SweepRunner(params, kernel_template, post_process)` driver replaces the hand-rolled loops in g1.py + g3.py.
Results · real Selene shots
sweep_runner_drives_g1 · verdict_matches_reference · metrics_within_mc_errorMigrated G1 driver runs through quantum/sweep.py (SweepSpec + SweepRunner). Output matches nadarasa_g1.json: refutation verdict identical (`consistent_with_g1`), Δ worst_violating_excess = 0.021, Δ min_srp_minus_violating = 0.001 — both within Monte-Carlo error at 400 shots/slope. ~80-line slope/template/JSON boilerplate eliminated.
Why this matters
G1 and G3 share a kernel shape — coset state, per-qubit controlled phase, terminal H + measure — and differ only in the host post-processor. Today each script duplicates ~80 lines of slope-loop, template-render, JSON-write boilerplate. A SweepRunner makes adding G4 (and every future Gn) a 20-line file.
What the repo already has
quantum/sweep.py (SweepSpec + SweepRunner) plus the migrated quantum/nadarasa_g1_via_sweep.py driver that consumes it.
What's missing
Nothing required by the card. nadarasa_g1.py and nadarasa_g3.py are kept as the authoritative reference drivers; the migrated G1 (and any future Gn) goes through SweepRunner.
Smallest experiment
Build it or kill itQubits
n/a — pure refactor
Ancilla pattern
n/a
Shots
Re-run G1 through the runner; verify headline metrics match within Monte-Carlo error.
Predicted outcome
Migrated driver emits nadarasa_g1_via_sweep.json with the same refutation verdict as the reference, and the headline metrics agree within Monte-Carlo error at 400 shots/slope.
Refutation criterion
If the migrated driver's refutation verdict differs from the reference, or the headline metrics drift beyond Monte-Carlo error (~0.05), the SweepRunner changed semantics — revert.
Kernel sketch
Untested — sketch only# quantum/nadarasa_g1_via_sweep.py (verified migration)
spec = SweepSpec(
name=f"g1_N{N}_p{p}_{branch}",
params=[{"s": s, "n": n, "N": N, "p": p} for s in slopes],
template=lambda pp: render_kernel(pp["n"], pp["s"], pp["N"]),
n_qubits=lambda pp: pp["n"] + 1,
post=lambda shots, pp: {"s": pp["s"], "hist": residue_histogram(shots, pp["n"], pp["p"])},
shots=shots,
)
result = runner.run(spec)Host pipeline
Per (N, p, branch): one SweepSpec → SweepRunner.run() → per-slope rows. Aggregation is the only experiment-specific code; render/import/build/shot-loop boilerplate is gone.
Related
Files in this repo
- · quantum/sweep.py
- · quantum/nadarasa_g1_via_sweep.py
- · src/data/demos/nadarasa_g1_via_sweep.json
- · quantum/nadarasa_g1.py