Point 1. The base step's order is Muller's 1.839, not 2: the derivative of the parabola through
the last three points errs by f'''/6 (x_n - x_{n-1})(x_n - x_{n-2}) = O(e_{n-1} e_{n-2}).
order_high_precision.py (3000 digits, to 1e-2900): 1.840 on cos x - x, e^x - 2, x^3 - x - 2,
sin x - 1/2; 2.000 only on x^2 - 2; two-point 1.618. The double-precision medians (2.000, 1.94)
are removed from the text.
Point 3. Every protocol number is re-scored under the criterion of section 9 - a sign change
within 1e-6 or f(x) == 0. rescore_uniform.py re-runs all 2779 distinct configurations of the 25
protocol sweeps on APS and CHA (the runs did not keep x) -> sweep_uniform.json, same row format;
it reproduces the APS/CHA lines of Table 10 exactly (built-in check). verify_article.py,
audit_similarity_places.py and the gap diagnostics read the re-scored data; the multiplier and
endowment measurements score by the same criterion. Table 7 (two criteria side by side) is gone;
7.3 now explains why the criterion is a sign change. Consequences stated in the text: the base
rule 2634 / 2357 against Chandrupatla 2595 / 1505 (1.5% behind on APS, no longer "level"); A'
2259 / 1074 (12.9% and 28.6% below Chandrupatla); the defect reading 2351 is second to the
shape reading 2337, not the record; the remembered analogy is level with no regime (2633 vs
2634) under this criterion; Table 9a's range is 19% to 425%.
Point 8. report_sweep.head_to_head counts every problem, failures charged (it counted only the
problems both methods solved, which is why Table 8 rows summed to 153 and 40). Family-level
comparisons added (A' vs Chandrupatla 8/1/6 of 15 and 7/0/2 of 9 families, not significant), and
an independence paragraph in section 9.
Point 11. sweep_itp.py: ITP (recommended constants and per-problem oracle) on all six corpora ->
Table 10; behind A' on every corpus, 0 bound violations.
Points 7, 9, 10 and the internals: the 2x bound is ours, not the rivals' promise; the law
predicts the group order only; "outside the proven bracket" explained (narrowest bracket of all
observed signs); 7.4's fun1 paragraph corrected (five costs under safe; the unguarded numbers
belong to fun1.4, fun1.5 and to fun3.1, fun5.1 separately); Table 1's last cell; the corpus-4
composition and odd multiplicities stated, also in the abstract.
build_tex.py: pdflatex output decoded with errors="replace" (a UTF-8 character cut by TeX's log
wrap crashed the build). Table 10 column widths rebalanced.
Checks: verify_article on the server 500 OK / 0 BAD (467 existing with the new values, 33 new);
regression x2 on the server 1232 passed, 0 failed; PDF 28 pages, 0 errors, 0 undefined, 0 overfull.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
73 lines
2.4 KiB
Python
73 lines
2.4 KiB
Python
"""Revision point 11 (2026-09-22): ITP in Table 10 - at the authors' recommended constants and as
|
|
the per-problem oracle of section 4 - on all six corpora, under the uniform criterion of
|
|
section 9, with the harness of sweep_fourth.py (same problems, same seeding, same charging).
|
|
|
|
python -u sweep_itp.py run -> sweep_itp.json, then the table
|
|
python -u sweep_itp.py --report
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
import json
|
|
import sys
|
|
from multiprocessing import Pool
|
|
|
|
import sweep_fourth
|
|
from sweep_oos import sign_p
|
|
|
|
sweep_fourth.CONFIGS["itp"] = ("base", "itp")
|
|
sweep_fourth.CONFIGS["itp_oracle"] = ("base", "itp_oracle")
|
|
SETS = ("APS", "CHA", "NEW", "RJL", "APP", "D")
|
|
|
|
|
|
def job(j):
|
|
name, which = j
|
|
return name, which, sweep_fourth.evaluate((name, which))[1]
|
|
|
|
|
|
def cost(v):
|
|
return v[0] if v[1] else 200
|
|
|
|
|
|
def report(R):
|
|
seen = json.load(open("sweep_fourth_seen.json", encoding="utf8"))
|
|
four = json.load(open("sweep_fourth_fourth.json", encoding="utf8"))
|
|
ap = dict(seen["Aprime"])
|
|
ap.update(four["Aprime"])
|
|
print("corpus A' ITP (viol) ITP oracle (viol) A' vs ITP A' vs oracle")
|
|
tot = {"A": 0, "itp": 0, "itp_oracle": 0}
|
|
for s in SETS:
|
|
a = ap[s]
|
|
row = [f"{s:<5} {sum(cost(v) for v in a.values()):6d}"]
|
|
tot["A"] += sum(cost(v) for v in a.values())
|
|
h = []
|
|
for k in ("itp", "itp_oracle"):
|
|
r = R[k][s]
|
|
t = sum(cost(v) for v in r.values())
|
|
tot[k] += t
|
|
row.append(f"{t:6d} ({sum(v[2] for v in r.values())})")
|
|
w = sum(cost(a[p]) < cost(r[p]) for p in a)
|
|
l = sum(cost(a[p]) > cost(r[p]) for p in a)
|
|
h.append(f"{w}/{len(a) - w - l}/{l} p={sign_p(w, l):.1g}")
|
|
print(" ".join(row) + " " + " ".join(h))
|
|
print(f"all {tot['A']:6d} {tot['itp']:6d} {tot['itp_oracle']:6d}")
|
|
|
|
|
|
def main():
|
|
if "--report" not in sys.argv:
|
|
jobs = [(n, w) for n in ("itp", "itp_oracle") for w in ("seen", "fourth")]
|
|
with Pool(len(jobs)) as pool:
|
|
out = pool.map(job, jobs)
|
|
R = {}
|
|
for name, _which, res in out:
|
|
R.setdefault(name, {}).update(res)
|
|
with open("sweep_itp.json", "w", encoding="utf8") as fh:
|
|
json.dump(R, fh)
|
|
with open("sweep_itp.json", encoding="utf8") as fh:
|
|
R = json.load(fh)
|
|
report(R)
|
|
print("itp done")
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|