Files
sim-numerics/analyze_defcontra.py
T

65 lines
2.7 KiB
Python

"""Verdicts of PREREG_defect_contra_flat_2026-09-21 (C1-C4, the goal) from a results file.
python -u analyze_defcontra.py [sweep_defcontra_smoke.json]
"""
from __future__ import annotations
import json
import sys
from analyze_extrap import h2h, sign_p
from where_we_lose import per_family
CH_APS, CH_CHA = 2787, 2441
def main(path="sweep_defcontra_smoke.json"):
rows = json.load(open(path, encoding="utf8"))
cha = {r["label"]: r for r in json.load(open("sweep_full.json", encoding="utf8"))}["chandrupatla"]
cell = {(r["spec"][9], r["spec"][5]): r for r in rows if r["spec"][3] == "project"}
for ext, name in (("none", "proposed rule"), ("pattern", "proposed rule + G2")):
base = cell[(ext, "none")]
b_aps, b_cha = base["APS"]["total"], base["CHA"]["total"]
print(f"\n== {name}: baseline APS {b_aps} CHA {b_cha}")
print(f" {'prestep':<30} {'APS':>5} {'CHA':>5} {'both':>5} C1 C2 C3 goal "
f"vs Chandrupatla APS / CHA (w/t/l)")
best = None
for (e, pre), r in cell.items():
if e != ext:
continue
aps, chv = r["APS"]["total"], r["CHA"]["total"]
c1, c2 = chv < b_cha, aps <= b_aps
c3 = r["APS"]["over"] + r["CHA"]["over"] == 0 and \
r["APS"]["solved"] + r["CHA"]["solved"] >= 193
goal = aps < CH_APS and chv < CH_CHA
wa, ta, la = h2h(r, cha, "APS")
wc, tc, lc = h2h(r, cha, "CHA")
print(f" {pre:<30} {aps:5d} {chv:5d} {aps + chv:5d} "
f"{'✓' if c1 else '✗'} {'✓' if c2 else '✗'} {'✓' if c3 else '✗'} "
f"{'YES' if goal else ' no'} {wa}/{ta}/{la} p={sign_p(wa, la):.2g} | "
f"{wc}/{tc}/{lc}")
if c1 and c2 and c3 and (best is None or aps + chv < best[1]):
best = (pre, aps + chv)
if best is None:
print(" no cell passes C1-C3")
continue
pre = best[0]
print(f" best accepted cell: {pre} (both {best[1]})")
parts = pre.split("+")
r = cell[(ext, pre)]
for p in parts:
rest = "+".join(q for q in parts if q != p) or "none"
if (ext, rest) not in cell:
continue
o = cell[(ext, rest)]
print(f" C4 ablation - remove {p:<14}: APS {o['APS']['total'] - r['APS']['total']:+d}"
f" CHA {o['CHA']['total'] - r['CHA']['total']:+d} (positive = the component earns it)")
a = per_family(r, "CHA")
c = per_family(cha, "CHA")
print(" CHA per family (ours/Chandrupatla): "
+ " ".join(f"{k} {a[k]}/{c[k]}" for k in sorted(c)))
if __name__ == "__main__":
main(*sys.argv[1:2])