Files
sim-numerics/sweep_applied.py

97 lines
3.7 KiB
Python

"""PREREG_applied_2026-09-21: variants A, B, the plain rule and the three library rivals on
the GSL test suite and the applied equations (corpus_applied.py).
python -u sweep_applied.py run -> sweep_applied.json, then the verdicts
python -u sweep_applied.py --report verdicts only
"""
from __future__ import annotations
import json
import math
import sys
from multiprocessing import Pool
from corpus_applied import build
from corpus_roots_jl import solved
from sweep_full import MAXFEV, XTOL, make_method
from sweep_oos import CONFIGS as OOS_CONFIGS
from sweep_oos import sign_p
NAMES = ("base", "A", "B", "chandrupatla", "brent", "toms748")
def evaluate(name):
method = make_method(OOS_CONFIGS[name])
probs, _ = build()
res = {}
for pid, f, a, b in probs:
try:
x, n, conv = method(f, a, b, XTOL, MAXFEV)
x = float(x)
except Exception:
x, n, conv = float("nan"), MAXFEV, False
ok = bool(conv and solved(f, x))
over = ok and int(n) > 2 * math.ceil(math.log2(abs(b - a) / XTOL)) + 4
res[pid] = [int(n), ok, bool(over)]
return name, res
def cost(v):
return v[0] if v[1] else MAXFEV
def group(pid):
return "GSL" if pid.startswith("G.") else pid.split(".")[1]
def report(R):
ch = R["chandrupatla"]
pids = list(R["A"])
print("== ALL 132")
for k in NAMES:
r = R[k]
print(f" {k:<14} total {sum(cost(v) for v in r.values()):6d} solved "
f"{sum(v[1] for v in r.values()):3d}/{len(r)} violations {sum(v[2] for v in r.values())}")
for v_name in ("A", "B"):
r = R[v_name]
tot, tot_ch = sum(cost(r[p]) for p in pids), sum(cost(ch[p]) for p in pids)
w = sum(cost(r[p]) < cost(ch[p]) for p in pids)
l = sum(cost(r[p]) > cost(ch[p]) for p in pids)
viol = sum(r[p][2] for p in pids)
sv, sc = sum(r[p][1] for p in pids), sum(ch[p][1] for p in pids)
t1, t2, t3 = tot < tot_ch, w > l and sign_p(w, l) < 0.05, viol == 0 and sv >= sc
print(f" {v_name}: T1 {'✓' if t1 else '✗'} ({tot} vs {tot_ch}, {100 * (tot - tot_ch) / tot_ch:+.1f}%)"
f" T2 {'✓' if t2 else '✗'} ({w}/{len(pids) - w - l}/{l} p={sign_p(w, l):.2g})"
f" T3 {'✓' if t3 else '✗'} (viol {viol}, solved {sv} vs {sc}) -> "
+ ("TRANSFERS" if t1 and t2 and t3 else "does NOT transfer"))
for rn in ("brent", "toms748"):
o = R[rn]
w2 = sum(cost(r[p]) < cost(o[p]) for p in pids)
l2 = sum(cost(r[p]) > cost(o[p]) for p in pids)
print(f" vs {rn:<8} total {tot} vs {sum(cost(o[p]) for p in pids)} "
f"per problem {w2}/{len(pids) - w2 - l2}/{l2} p={sign_p(w2, l2):.2g}")
print("\n== PER GROUP: A / B / Chandrupatla / Brent / TOMS748 totals; A vs Chandrupatla w/t/l")
for g in sorted({group(p) for p in pids}):
sel = [p for p in pids if group(p) == g]
tots = [sum(cost(R[k][p]) for p in sel) for k in ("A", "B", "chandrupatla", "brent", "toms748")]
w = sum(cost(R["A"][p]) < cost(ch[p]) for p in sel)
l = sum(cost(R["A"][p]) > cost(ch[p]) for p in sel)
print(f" {g:<10} n={len(sel):3d} " + " / ".join(f"{t:5d}" for t in tots)
+ f" {w}/{len(sel) - w - l}/{l}")
def main():
if "--report" not in sys.argv:
with Pool(len(NAMES)) as pool:
R = dict(pool.map(evaluate, NAMES))
with open("sweep_applied.json", "w", encoding="utf8") as fh:
json.dump(R, fh)
with open("sweep_applied.json", encoding="utf8") as fh:
R = json.load(fh)
report(R)
print("applied done")
if __name__ == "__main__":
main()