197 lines
7.9 KiB
Python
197 lines
7.9 KiB
Python
"""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()
|