"""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()