Files
sim-numerics/measure_inertness.py
T

55 lines
2.1 KiB
Python

"""A2/B2: is the new reading INERT? (PREREG_points_and_direction_2026-09-21 §4)
A mode that changes nothing is not evidence either way, so the share of steps on which the
new rule actually changed the decision is measured over the whole benchmark, per set.
python -u measure_inertness.py
"""
from __future__ import annotations
from simroot.pure import pure_root
from sweep_full import MAXFEV, XTOL, load_problems
def run(mode):
kw = {"points": "shape"} if mode == "shape" else {"direction": "dissimilar"}
key = "triple_changed" if mode == "shape" else "dir_changed"
out = {}
for setname in ("APS", "CHA"):
steps = changed = solved = n = 0
for s, _pid, f, a, b, root in load_problems():
if s != setname:
continue
n += 1
st = {}
try:
x, nfev, ok = pure_root(f, a, b, XTOL, MAXFEV, similarity="ratio",
scale="derived3", guard="safe", prestep="slope",
stats=st, **kw)
except Exception:
continue
steps += max(nfev - 2, 0)
changed += st.get(key, 0)
solved += int(bool(ok) and abs(x - root) <= 1e-6)
out[setname] = (changed, steps, 100.0 * changed / steps if steps else float("nan"),
solved, n)
return out
def main():
for mode in ("shape", "dissimilar"):
res = run(mode)
print(f"\nmode {mode!r}:")
for setname, (ch, st, pct, solved, n) in res.items():
print(f" {setname}: changed {ch} of {st} steps = {pct:.1f}% "
f"(solved {solved}/{n})")
pct_all = 100.0 * sum(r[0] for r in res.values()) / max(sum(r[1] for r in res.values()), 1)
verdict = "NOT inert" if pct_all >= 5.0 else ("INERT — the measurement is void"
if pct_all < 1.0 else "borderline")
print(f" overall {pct_all:.1f}% -> {verdict} (prereg: >=5% not inert, <1% void)")
if __name__ == "__main__":
main()