The three neighbouring applications out of the published branch: the NLMS step size (anc), the ODE step controllers (odestep) and the relaxation factor (relax), with the six stage scripts that drive them and the five tests that cover them. They are not part of the root-finding paper and no document refers to them. stage18_bulletproof.py keeps claim A and loses claim B; tests/test_bulletproof.py loses the one test that reached into anc. Server: verify 548 OK / 0 BAD, tests x2 1205 passed (was 1240 with the three).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
vvs
2026-09-25 10:02:18 +01:00
co-authored by Claude Opus 5
parent 886b3f4244
commit 8ad09b47a6
22 changed files with 2 additions and 2335 deletions
-75
View File
@@ -12,15 +12,6 @@ falsi goes from 133 solved and 18799 evaluations to 193 and 8056.
TEST: the same rule, the same driver, the same everything, with the
stale-endpoint correction swapped for each classical fix in turn and for
the credit projection. Only the repair differs.
CLAIM B. In active noise control the measured step size beats Kwong-Johnston
by 7 dB.
OBJECTION: Kwong-Johnston's gains are scale-dependent, and yours are the
published defaults run on a signal they were not scaled for. Give it its
best constants and the gap will close.
TEST: an oracle over its (alpha, gamma) grid, chosen separately for every
scenario - not an achievable controller, exactly as the ITP oracle in the
root-finding work was not.
"""
from __future__ import annotations
@@ -32,8 +23,6 @@ import numpy as np
from scipy.optimize._tstutils import (_APS_TESTS_DICTS,
_CHANDRUPATLA_TESTS_DICTS)
from anc.bench import SCENARIOS, make_primary_path, make_secondary_path, run_nlms
from anc.rules import Fixed, KwongJohnston, Measured, Rule
from simroot.baselines import Counter, _Budget
from simroot.pure import _Safeguard
@@ -162,69 +151,5 @@ def claim_a():
return rows
# ==========================================================================
# CLAIM B: the measured step size against a Kwong-Johnston oracle
# ==========================================================================
class KJTuned(KwongJohnston):
def __init__(self, a, g):
self.A, self.G = a, g
self.name = f"KJ a={a:g} g={g:g}"
self.constants = 4
N, SEEDS, SNRS = 8000, 6, (30.0, 15.0)
KJ_GRID = [(a, g) for a in (0.9, 0.97, 0.99)
for g in (2e-4, 2e-3, 2e-2, 2e-1)]
def anc_score(rule, scen_gen, snr, seeds=SEEDS):
vals = []
for s in range(seeds):
rng = np.random.default_rng(1000 + s)
noise = scen_gen(N, rng)
nr = run_nlms(noise, make_primary_path(rng), make_secondary_path(rng),
rule, snr_db=snr, seed=s)
if math.isfinite(nr):
vals.append(nr)
return (sum(vals) / len(vals)) if vals else float("nan")
def claim_b():
print("\n" + "=" * 84)
print("CLAIM B - the measured step size against a Kwong-Johnston ORACLE")
print("=" * 84)
print(f"the oracle is given the best of {len(KJ_GRID)} (alpha, gamma) "
f"pairs for every scenario\nand noise level separately - not an "
f"achievable controller\n")
print(f"{'scenario':22s}{'SNR':>6s}{'KJ default':>12s}{'KJ oracle':>12s}"
f"{'measured':>11s}{'fixed 0.5':>11s}")
print("-" * 84)
tot = {"kj": 0.0, "orc": 0.0, "meas": 0.0, "fix": 0.0}
cells = 0
for sname, gen in SCENARIOS:
for snr in SNRS:
kj = anc_score(KwongJohnston(), gen, snr)
orc = max(anc_score(KJTuned(a, g), gen, snr) for a, g in KJ_GRID)
meas = anc_score(Measured(), gen, snr)
fix = anc_score(Fixed(0.5), gen, snr)
tot["kj"] += kj
tot["orc"] += orc
tot["meas"] += meas
tot["fix"] += fix
cells += 1
print(f"{sname:22s}{snr:>6.0f}{kj:>12.2f}{orc:>12.2f}"
f"{meas:>11.2f}{fix:>11.2f}", flush=True)
print("-" * 84)
print(f"{'mean':22s}{'':6s}{tot['kj'] / cells:>12.2f}"
f"{tot['orc'] / cells:>12.2f}{tot['meas'] / cells:>11.2f}"
f"{tot['fix'] / cells:>11.2f}")
survives = tot["meas"] > tot["orc"]
print(f"\n measured {tot['meas'] / cells:.2f} dB against the oracle "
f"{tot['orc'] / cells:.2f} dB => "
f"{'SURVIVES' if survives else 'FAILS'} the objection")
return survives
if __name__ == "__main__":
claim_a()
claim_b()