Files
sim-numerics/verify_article.py
T

339 lines
16 KiB
Python

"""Check every number the paper states against sweep_full.json.
A paper is a claim about data; transcribing its tables by hand is how a claim
stops matching its data. A failure here means the paper is wrong, not the
test.
The proposed method is now the CREDIT safeguard - the only configuration with
no free constant. The projection variant is kept in the paper as the other
end of a stated trade (better average, one constant), so both are checked.
"""
from __future__ import annotations
import json
import os
import sys
from report_sweep import PROPOSED, head_to_head, place, rank
FAILS = []
PROJ = "pure.ratio.derived3.project"
def check(label, got, want):
ok = got == want
print(f" {'OK ' if ok else 'BAD'} {label:58s} got {got!r:>16} "
f"want {want!r}")
if not ok:
FAILS.append(label)
def row(rows, setname, lbl):
return next(r for r in rows if r["label"] == lbl)[setname]
def main():
with open("sweep_full.json", encoding="utf8") as fh:
rows = json.load(fh)
# Guard against quoting places from a field that is missing a competitor.
# It has already happened once: before Chandrupatla's own method was
# added, every ranking assertion here passed only because the method that
# beats us was absent.
labels = {r["label"] for r in rows}
missing = {"chandrupatla", "dekker", PROPOSED} - labels
if missing:
print(f" !! THE SWEEP IS STALE: missing {sorted(missing)}. "
"Re-run sweep_full.py.\n")
FAILS.append("sweep is stale")
check("number of configurations", len(rows), 264)
# ---- the proposed method: credit safeguard, no free constant ----------
print("\nThe proposed method (credit safeguard):")
check("its label", PROPOSED, "pure.ratio.derived3.credit")
for setname, pl, tot, sol in (("APS", 29, 3568, 153),
("CHA", 10, 3020, 40)):
d = row(rows, setname, PROPOSED)
check(f"{setname} place", place(rows, setname, PROPOSED), pl)
check(f"{setname} total", d["total"], tot)
check(f"{setname} solved", d["solved"], sol)
check("both sets", row(rows, "APS", PROPOSED)["total"]
+ row(rows, "CHA", PROPOSED)["total"], 6588)
print("\nHead to head of the proposed method:")
for setname, opp, want in [
("APS", "chandrupatla", (79, 3, 71)),
("APS", "toms748", (77, 9, 67)),
("APS", "brent", (78, 5, 70)),
("APS", "itp", (103, 10, 40)),
("APS", "bisection", (122, 1, 30)),
("CHA", "chandrupatla", (5, 0, 35)),
("CHA", "toms748", (24, 0, 16)),
("CHA", "brent", (18, 0, 20)),
("CHA", "itp", (12, 20, 8))]:
w, t, l, _ = head_to_head(rows, PROPOSED, opp, setname)
check(f"{setname} vs {opp}", (w, t, l), want)
# ---- the trade against the projection variant -------------------------
print("\nThe stated trade: credit against the projection variant:")
check("projection APS", row(rows, "APS", PROJ)["total"], 2806)
check("projection CHA", row(rows, "CHA", PROJ)["total"], 3220)
check("projection both", row(rows, "APS", PROJ)["total"]
+ row(rows, "CHA", PROJ)["total"], 6026)
check("credit costs more in total",
(row(rows, "APS", PROPOSED)["total"]
+ row(rows, "CHA", PROPOSED)["total"])
> (row(rows, "APS", PROJ)["total"] + row(rows, "CHA", PROJ)["total"]),
True)
for setname, opp, want in [("APS", "brent", (102, 11, 40)),
("APS", "toms748", (86, 16, 51))]:
w, t, l, _ = head_to_head(rows, PROJ, opp, setname)
check(f"projection {setname} vs {opp}", (w, t, l), want)
# ---- what the earlier, order-destroying guards cost --------------------
print("\nThe guards that replace the step instead of projecting it:")
check("APS unguarded", row(rows, "APS", "pure.ratio.derived3.none")["total"],
2806)
cha_none = row(rows, "CHA", "pure.ratio.derived3.none")
check("CHA unguarded total", cha_none["total"], 4104)
check("CHA unguarded solved", cha_none["solved"], 35)
check("CHA unguarded bound violations", cha_none["over"], 10)
check("APS bracket-guard", row(rows, "APS", "pure.ratio.derived3.bracket")["total"],
7260)
check("APS both-guard", row(rows, "APS", "pure.ratio.derived3.both")["total"],
7239)
# ---- the field --------------------------------------------------------
print("\nAlefeld-Potra-Shi:")
check("APS winner", rank(rows, "APS")[0]["label"], "chandrupatla")
for lbl, pl, tot in [("chandrupatla", 1, 2785), ("toms748", 4, 2820),
("brent", 5, 2889), ("dekker", 12, 3158),
("itp_oracle", 13, 3260), ("ridders", 20, 3313),
("itp", 34, 3957), ("illinois", 73, 7045),
("bisection", 79, 7530), ("regula_falsi", 244, 10560)]:
check(f"APS {lbl} place", place(rows, "APS", lbl), pl)
check(f"APS {lbl} total", row(rows, "APS", lbl)["total"], tot)
check("APS regula falsi solved", row(rows, "APS", "regula_falsi")["solved"],
127)
print("\nChandrupatla:")
top = rank(rows, "CHA")[0]
check("CHA rank 1 label", top["label"], "pure.sqrt.bracket.project")
check("CHA rank 1 solves one more than anyone else", top["CHA"]["solved"], 41)
for lbl, pl, tot in [("chandrupatla", 2, 2423), ("itp_oracle", 3, 2611),
("itp", 6, 2857), ("bisection", 16, 3090),
("toms748", 164, 4000), ("brent", 226, 4099)]:
check(f"CHA {lbl} place", place(rows, "CHA", lbl), pl)
check(f"CHA {lbl} total", row(rows, "CHA", lbl)["total"], tot)
check("CHA brent solved", row(rows, "CHA", "brent")["solved"], 38)
ours_both = (row(rows, "APS", PROPOSED)["total"]
+ row(rows, "CHA", PROPOSED)["total"])
cha_both = (row(rows, "APS", "chandrupatla")["total"]
+ row(rows, "CHA", "chandrupatla")["total"])
check("chandrupatla, both sets", cha_both, 5208)
check("Chandrupatla beats us on both sets", cha_both < ours_both, True)
# ---- the regime findings ---------------------------------------------
print("\nNegative results, the regime claims:")
check("CHA cbrt over the whole set",
row(rows, "CHA", "pure.cbrt.derived3.project")["total"], 4099)
switched = (row(rows, "APS", PROJ)["total"]
+ row(rows, "CHA", "pure.cbrt.derived3.project")["total"])
single = row(rows, "APS", PROJ)["total"] + row(rows, "CHA", PROJ)["total"]
check("single fixed choice, both sets", single, 6026)
check("switch by benchmark set, both sets", switched, 6905)
check("switching is worse than not switching", switched > single, True)
for pid, ours_n, cb_n in (("fun4.1", 89, 32), ("fun4.2", 93, 32),
("fun4.3", 113, 40), ("fun4.4", 125, 47),
("fun4.5", 153, 59)):
o = row(rows, "CHA", PROJ)["per"][pid]
c = row(rows, "CHA", "pure.cbrt.derived3.project")["per"][pid]
check(f"{pid} projection variant", o[0], ours_n)
check(f"{pid} cbrt", c[0], cb_n)
# ---- the law across the grid ------------------------------------------
print("\nThe law across the grid:")
lin = ("ratio", "rational", "exp_abs")
quad = ("rat_sq", "exp_sq", "cosine")
want = {("derived3", "lin"): 6809, ("derived3", "quad"): 22294,
("derived", "lin"): 6906, ("derived", "quad"): 22167,
("bracket", "lin"): 10263, ("bracket", "quad"): 19137,
("start", "lin"): 16102, ("start", "quad"): 15345}
for scale in ("derived3", "derived", "bracket", "start"):
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 or gu != "step" or sim not in group:
continue
cnt += 1
tot += r["APS"]["total"] + r["CHA"]["total"]
check(f"mean total, scale={scale}, {gname}",
round(tot / cnt), want[(scale, gname)])
best_by_sim, best_by_scale = {}, {}
for r in rows:
if r["spec"][0] != "pure" or r["spec"][3] != "step":
continue
t = r["APS"]["total"] + r["CHA"]["total"]
best_by_sim[r["spec"][1]] = min(best_by_sim.get(r["spec"][1], 10 ** 9), t)
best_by_scale[r["spec"][2]] = min(best_by_scale.get(r["spec"][2], 10 ** 9), t)
check("every c=1 similarity beats every c=0 similarity",
max(best_by_sim[s] for s in lin) < min(best_by_sim[s] for s in quad),
True)
check("similarity ranking",
[s for s, _ in sorted(best_by_sim.items(), key=lambda kv: kv[1])],
["ratio", "exp_abs", "rational", "ratio_soft", "sqrt", "cbrt",
"exp_sq", "rat_sq", "cosine"])
for sim, v in [("ratio", 6496), ("exp_abs", 6822), ("rational", 7038),
("ratio_soft", 9502), ("sqrt", 10497), ("cbrt", 11941),
("exp_sq", 14314), ("rat_sq", 15102), ("cosine", 16394)]:
check(f"similarity {sim} best", best_by_sim[sim], v)
check("scale ranking",
[s for s, _ in sorted(best_by_scale.items(), key=lambda kv: kv[1])],
["derived3", "derived", "bracket", "start"])
for sc, v in [("derived3", 6496), ("derived", 6628), ("bracket", 9081),
("start", 14540)]:
check(f"scale {sc} best", best_by_scale[sc], v)
verify_placement_modes()
verify_per_place()
print()
if FAILS:
print(f"{len(FAILS)} STATED NUMBERS DO NOT MATCH THE DATA:")
for f in FAILS:
print(f" {f}")
sys.exit(1)
print("every number stated in the paper matches the sweep data.")
# --------------------------------------------------------------------------
# Section "where the similarity is read" (PREREGs of 2026-09-20/21). Each new
# grid lives in its OWN sweep file so the published sweep_full.json stays the
# artefact of the original claims; every number the new section quotes is
# re-checked here against that file.
# --------------------------------------------------------------------------
PLACEMENT = {
# file label APS CHA
"sweep_slope.json": ("slope.ratio.derived3.project", 2848, 3074),
"sweep_points.json": ("pure+shape+slope.ratio.derived3.safe", 2527, 3108),
"sweep_direction.json": ("pure+dissim+slope.ratio.derived3.project", 2726, 2785),
"sweep_combo.json": ("pure+shape+dissim+slope.ratio.derived3.safe", 2884, 2859),
"sweep_gate.json": ("gate.ratio.derived.project", 4449, 2991),
"sweep_log.json": ("log.ratio_soft.derived.safe", 6940, 3474),
}
# The per-place table of section "the similarity function belongs to the place":
# seven PAIRED comparisons in sweep_order.json. Checked as pairs, because a pair is
# what the pre-registration licensed and a single cell would prove nothing.
ORDER_PAIRS = {
# guard (APS m=1, APS measured, CHA m=1, CHA measured)
"both": (4522, 3675, 3387, 3216),
"bracket": (4606, 3542, 3571, 3303),
"credit": (5190, 4686, 3013, 2884),
"project": (6932, 6364, 4794, 4559),
"safe": (5987, 5229, 4108, 3923),
"step": (6435, 5551, 4257, 4022),
"none": (10676, 10043, 8265, 7794),
}
# the negative item: the order does not cure false position
ORDER_FALSEPOS = {("rational", "far", "none", "none"): (127, 10676),
("rational", "far", "none", "order"): (128, 10043)}
# and the harmful direction, quoted in the same subsection
ORDER_SLOPE_HARM = {("ratio", "derived3", "none", "none"): 2806,
("ratio", "derived3", "none", "order"): 2854}
def verify_per_place():
print("\nThe per-place reading (sweep_order.json):")
if not os.path.exists("sweep_order.json"):
print(" !! sweep_order.json absent — section 'belongs to the place' unverifiable")
FAILS.append("missing sweep_order.json")
return
with open("sweep_order.json", encoding="utf8") as fh:
rows = json.load(fh)
def cell(sim, sc, gu, ex):
for r in rows:
s = r["spec"]
if (s[1], s[2], s[3], s[8] if len(s) > 8 else "none") == (sim, sc, gu, ex):
return r
return None
cheaper = 0
for gu, (a1, a2, c1, c2) in ORDER_PAIRS.items():
p = cell("rational", "far", gu, "none")
q = cell("rational", "far", gu, "order")
if p is None or q is None:
FAILS.append(f"order pair {gu} missing from sweep_order.json")
print(f" !! pair {gu} missing — stale sweep")
continue
check(f"far+rational {gu} APS m=1", p["APS"]["total"], a1)
check(f"far+rational {gu} APS order", q["APS"]["total"], a2)
check(f"far+rational {gu} CHA m=1", p["CHA"]["total"], c1)
check(f"far+rational {gu} CHA order", q["CHA"]["total"], c2)
cheaper += (q["APS"]["total"] + q["CHA"]["total"]
< p["APS"]["total"] + p["CHA"]["total"])
check("cheaper in 7 of 7 safeguards", cheaper, 7)
for (sim, sc, gu, ex), (solved, total) in ORDER_FALSEPOS.items():
r = cell(sim, sc, gu, ex)
if r is None:
FAILS.append(f"false-position cell {ex} missing")
continue
check(f"false position {ex} solved", r["APS"]["solved"], solved)
check(f"false position {ex} APS", r["APS"]["total"], total)
for (sim, sc, gu, ex), want in ORDER_SLOPE_HARM.items():
r = cell(sim, sc, gu, ex)
if r is None:
FAILS.append(f"slope-harm cell {ex} missing")
continue
check(f"slope reading {ex} APS", r["APS"]["total"], want)
fam = [r for r in rows if r["spec"][3] in ("project", "safe", "credit")]
check("guarantee family violations", sum(r["APS"]["over"] + r["CHA"]["over"]
for r in fam), 0)
PLACEMENT_PER_SET = {
"sweep_direction.json": ("CHA", "pure+dissim+slope.ratio.derived3.safe", 2683),
"sweep_gate.json": ("CHA", "gate.ratio_soft.derived.safe", 2851),
}
def verify_placement_modes():
print("\nThe placement modes (each in its own sweep file):")
for path, (lbl, aps, cha) in PLACEMENT.items():
if not os.path.exists(path):
print(f" !! {path} absent — the section quoting it cannot be verified")
FAILS.append(f"missing {path}")
continue
with open(path, encoding="utf8") as fh:
rows = json.load(fh)
try:
d = next(r for r in rows if r["label"] == lbl)
except StopIteration:
print(f" !! {lbl} not in {path} — stale sweep")
FAILS.append(f"{lbl} missing from {path}")
continue
check(f"{lbl} APS", d["APS"]["total"], aps)
check(f"{lbl} CHA", d["CHA"]["total"], cha)
check(f"{lbl} solved", d["APS"]["solved"] + d["CHA"]["solved"], 193)
check(f"{lbl} guarantee (over 2x)", d["APS"]["over"] + d["CHA"]["over"], 0)
for path, (setname, lbl, want) in PLACEMENT_PER_SET.items():
if not os.path.exists(path):
continue
with open(path, encoding="utf8") as fh:
rows = json.load(fh)
d = next((r for r in rows if r["label"] == lbl), None)
if d is None:
FAILS.append(f"{lbl} missing from {path}")
continue
check(f"{lbl} {setname} per-set", d[setname]["total"], want)
if __name__ == "__main__":
main()