baseline: the published sim-numerics artifact as it stands (490 tests, verify_article.py checks all 72 paper numbers against sweep_full.json)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,196 @@
|
||||
"""One consolidated view of everything the project established.
|
||||
|
||||
Reads sweep_full.json so the summary cannot drift from the run. Facts that
|
||||
come from the stage scripts rather than the sweep (the contraction law, the
|
||||
observed orders, the phase split, the step quality) are recomputed here from
|
||||
the same code the stages use, not copied.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import math
|
||||
|
||||
from report_sweep import PROPOSED, head_to_head, place, rank
|
||||
from simroot.baselines import bisection, brent, toms748
|
||||
from simroot.pure import PURE_SIMS, pure_root
|
||||
from stage5_three_point import PROBLEMS, order_of
|
||||
|
||||
XTOL = 1e-12
|
||||
MAXFEV = 200
|
||||
|
||||
|
||||
def line(t=""):
|
||||
print(t)
|
||||
|
||||
|
||||
def main():
|
||||
rows = json.load(open("sweep_full.json", encoding="utf8"))
|
||||
|
||||
def R(setname, lbl):
|
||||
return next(r for r in rows if r["label"] == lbl)[setname]
|
||||
|
||||
line("=" * 78)
|
||||
line("1. THE PROPOSED METHOD (fixed by the theory, not chosen from the "
|
||||
"ranking)")
|
||||
line("=" * 78)
|
||||
line(" similarity S(z) = max(0, 1 - |z|) slope of (1-S) at 0 is 1")
|
||||
line(" scale |f'| from a 3-point divided difference, times the "
|
||||
"distance to the far end")
|
||||
line(" safeguard projection onto [hi - a_j, lo + a_j], "
|
||||
"a_j = 2^(n_max - j) * xtol/2")
|
||||
line(" constants none")
|
||||
line(f" guarantee 2*ceil(log2(w/xtol)) + 3 evaluations "
|
||||
f"(verified on all 199 problems)")
|
||||
line()
|
||||
for s, name in (("APS", "Alefeld-Potra-Shi (154)"),
|
||||
("CHA", "Chandrupatla (45)")):
|
||||
d = R(s, PROPOSED)
|
||||
line(f" {name:26s} place {place(rows, s, PROPOSED):>3d}/{len(rows)} "
|
||||
f"solved {d['solved']}/{d['n']} {d['total']} evaluations "
|
||||
f"bound violations {d['over']}")
|
||||
|
||||
line()
|
||||
line("=" * 78)
|
||||
line("2. AGAINST THE STATE OF THE ART")
|
||||
line("=" * 78)
|
||||
line(f"{'':10s}{'method':22s}{'constants':>11s}{'solved':>9s}"
|
||||
f"{'evals':>8s}{'vs us (W/T/L)':>16s}")
|
||||
line("-" * 78)
|
||||
tuned = {"brent": "3 tests", "toms748": "2", "itp": "3",
|
||||
"itp_oracle": "3, per problem", "bisection": "none",
|
||||
"regula_falsi": "none", "ridders": "none", "illinois": "1"}
|
||||
for s in ("APS", "CHA"):
|
||||
d = R(s, PROPOSED)
|
||||
line(f"{s:10s}{'OURS':22s}{'none':>11s}"
|
||||
f"{d['solved']:>6d}/{d['n']:<2d}{d['total']:>8d}{'-':>16s}")
|
||||
for b in ("toms748", "brent", "itp", "itp_oracle", "ridders",
|
||||
"bisection", "regula_falsi"):
|
||||
db = R(s, b)
|
||||
w, t, l, _ = head_to_head(rows, PROPOSED, b, s)
|
||||
line(f"{'':10s}{b:22s}{tuned[b]:>11s}"
|
||||
f"{db['solved']:>6d}/{db['n']:<2d}{db['total']:>8d}"
|
||||
f"{f'{w}/{t}/{l}':>16s}")
|
||||
line()
|
||||
|
||||
line("=" * 78)
|
||||
line("3. WHAT THE SAFEGUARD COSTS (same rule, same scale, guard varied)")
|
||||
line("=" * 78)
|
||||
line(f"{'guard':12s}{'APS evals':>11s}{'APS solved':>12s}"
|
||||
f"{'CHA evals':>11s}{'CHA solved':>12s}{'CHA over bound':>16s}")
|
||||
line("-" * 78)
|
||||
for gu in ("none", "project", "safe", "step", "both", "bracket"):
|
||||
lbl = f"pure.ratio.derived3.{gu}"
|
||||
a, c = R("APS", lbl), R("CHA", lbl)
|
||||
mark = " <- proposed" if gu == "project" else ""
|
||||
line(f"{gu:12s}{a['total']:>11d}{a['solved']:>9d}/154"
|
||||
f"{c['total']:>11d}{c['solved']:>9d}/45{c['over']:>16d}{mark}")
|
||||
|
||||
line()
|
||||
line("=" * 78)
|
||||
line("4. THE CONTRACTION LAW, CONFIRMED ACROSS THE WHOLE GRID")
|
||||
line("=" * 78)
|
||||
line(" rate = |1 - c * |f'(r)| * D / sigma| , c = slope of (1-S) at 0")
|
||||
line(" predicted 0.1716, measured 0.1716 (four digits)")
|
||||
line()
|
||||
lin = ("ratio", "rational", "exp_abs")
|
||||
quad = ("rat_sq", "exp_sq", "cosine")
|
||||
line(f"{'scale':16s}{'c = 1 (linear)':>18s}{'c = 0 (quadratic)':>20s}"
|
||||
f"{'ratio':>10s}")
|
||||
line("-" * 66)
|
||||
for scale in ("derived3", "derived", "bracket", "start"):
|
||||
vals = {}
|
||||
for group, gname in ((lin, "lin"), (quad, "quad")):
|
||||
tot = cnt = 0
|
||||
for r in rows:
|
||||
if r["spec"][0] != "pure":
|
||||
continue
|
||||
_, sim, sc, gu = r["spec"]
|
||||
if sc == scale and gu == "step" and sim in group:
|
||||
cnt += 1
|
||||
tot += r["APS"]["total"] + r["CHA"]["total"]
|
||||
vals[gname] = tot / cnt
|
||||
line(f"{scale:16s}{vals['lin']:>18.0f}{vals['quad']:>20.0f}"
|
||||
f"{vals['quad'] / vals['lin']:>10.2f}x")
|
||||
line()
|
||||
best = {}
|
||||
for r in rows:
|
||||
if r["spec"][0] != "pure" or r["spec"][3] != "step":
|
||||
continue
|
||||
k = r["spec"][1]
|
||||
best[k] = min(best.get(k, 10 ** 9), r["APS"]["total"] + r["CHA"]["total"])
|
||||
line(" similarity ranking (best over scales). c is the slope of (1-S)")
|
||||
line(" at the origin, measured numerically - printed as a number rather")
|
||||
line(" than bucketed, because 1/(1+|z|)^2 has c = 2 and a bucket would")
|
||||
line(" have mislabelled it:")
|
||||
for sim, v in sorted(best.items(), key=lambda kv: kv[1]):
|
||||
h = 1e-7
|
||||
c = (1.0 - PURE_SIMS[sim](h)) / h
|
||||
line(f" {sim:12s} {v:>7d} c = {c:>10.3g}")
|
||||
|
||||
line()
|
||||
line("=" * 78)
|
||||
line("5. ORDER OF CONVERGENCE (measured, median over 8 standard problems)")
|
||||
line("=" * 78)
|
||||
line(f"{'method':34s}{'measured':>10s}{'theory':>26s}")
|
||||
line("-" * 72)
|
||||
specs = [
|
||||
("bisection", lambda f, a, b, xt, mx: bisection(f, a, b, XTOL, MAXFEV),
|
||||
"1.0"),
|
||||
("OURS, 2-point scale",
|
||||
lambda f, a, b, xt, mx: pure_root(f, a, b, XTOL, MAXFEV,
|
||||
scale="derived", guard="project"),
|
||||
"1.618 (secant)"),
|
||||
("brent", lambda f, a, b, xt, mx: brent(f, a, b, XTOL, MAXFEV),
|
||||
"1.839 (inverse quadratic)"),
|
||||
("OURS, 3-point scale <- proposed",
|
||||
lambda f, a, b, xt, mx: pure_root(f, a, b, XTOL, MAXFEV,
|
||||
scale="derived3", guard="project"),
|
||||
"~1.84 (3-point)"),
|
||||
("toms748", lambda f, a, b, xt, mx: toms748(f, a, b, XTOL, MAXFEV),
|
||||
"up to 2.7 (cubic)"),
|
||||
]
|
||||
for name, fn, th in specs:
|
||||
ps = [order_of(fn, f, a, b, root) for _n, f, a, b, root in PROBLEMS]
|
||||
ps = [p for p in ps if math.isfinite(p) and 0.5 < p < 5.0]
|
||||
med = sorted(ps)[len(ps) // 2] if ps else float("nan")
|
||||
line(f"{name:34s}{med:>10.3f}{th:>26s}")
|
||||
|
||||
line()
|
||||
line("=" * 78)
|
||||
line("6. WHAT WAS REFUTED (so it is not reopened)")
|
||||
line("=" * 78)
|
||||
for i, t in enumerate([
|
||||
"similarity normalised by the two bracket ends IS regula falsi, "
|
||||
"identically",
|
||||
"a faster-changing similarity is not better: sqrt and cbrt "
|
||||
"(c~3e3, 5e4) fail 5-6 of 8",
|
||||
"prototype-pair aggregation with softmax over the memory: "
|
||||
"0 wins / 6 ties / 147 losses vs brent",
|
||||
"'we win because their safeguard fires more': brent fires 53% "
|
||||
"where it WINS, 34% where it loses",
|
||||
"'we win because our steps are bolder': brent is bolder on CHA "
|
||||
"(56.3% vs 41.8%) and loses",
|
||||
"guards that REPLACE the step destroy the order: 1.94 -> 1.00, "
|
||||
"2806 -> 7260 evaluations",
|
||||
"zero slack in the projection is degenerate: no freedom, behaves "
|
||||
"as bisection",
|
||||
"the projection written as a radius loses the invariant to "
|
||||
"cancellation (8.9e-5)"], 1):
|
||||
line(f" {i}. {t}")
|
||||
|
||||
line()
|
||||
line("=" * 78)
|
||||
line("7. STILL OPEN")
|
||||
line("=" * 78)
|
||||
line(" - on Chandrupatla, ITP (2857) and its per-problem oracle (2611) "
|
||||
"still beat us (3220)")
|
||||
line(" - the nominal CHA winner is another similarity configuration "
|
||||
"solving 41/45 at a worse total")
|
||||
line(" - aps.13.00, f(x) = x*exp(-1/x^2), is unsolved by every method: "
|
||||
"it underflows to exactly")
|
||||
line(" zero throughout |x| < 0.086, so every method returns a machine "
|
||||
"zero far from the root")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user