Tables 2-3 regenerated from sweep_full.json by tables_for_md.py with the verifier's own ranking: Chandrupatla's method, missing from both, is FIRST on the canonical set (2785) and second on the wide-bracket set (2423); the proposed rule is 29th (3568) and 10th (3020); Brent 2889/4099 (was 2890/4101). The abstract, §5 text, §5.1, §5.2 (timed configuration named), §7 (records 2527/2523 are under the scheduled projection: 2523 flat for every multiplier 1.25-4, 2527 becomes 2541 at 1.25; under credit the readings give far less, best constant-free total 6494 by 'defect'), §8.4, §8.11 and the conclusion now say so: parity with the tuned methods at the price of one constant, or a constant-free rule with a tighter guarantee that trails on the canonical set. verify_article.py: 279 checks, measured tables recomputed from fresh runs; 762 tests pass twice. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
61 lines
2.6 KiB
Python
61 lines
2.6 KiB
Python
"""Part 3 of stage12_validation.py alone: is the projection's doubling load-bearing?
|
|
|
|
The canonical text (§3.1 of article/sim_numerics.md) says "the doubling is not a tuning
|
|
constant". simroot/pure.py (project_credit) says the opposite: the argument is circular
|
|
and 1.25 is cheaper. stage12 measured it but its output was never kept, so this reruns
|
|
exactly that part - the same `ours`, the same problems, the same charging - and returns
|
|
the numbers for verify_article.py. The credit safeguard, which needs no multiplier, is
|
|
put beside it from the same run.
|
|
|
|
python -u measure_budget_factor.py
|
|
"""
|
|
from __future__ import annotations
|
|
|
|
from simroot.pure import pure_root
|
|
from stage12_validation import XTOL, load, ours, per_problem, totals
|
|
|
|
FACTORS = (1.0, 1.25, 1.5, 2.0, 3.0, 4.0)
|
|
|
|
|
|
def credit(f, a, b, xtol, maxfev):
|
|
return pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived3",
|
|
guard="credit")
|
|
|
|
|
|
def main():
|
|
probs = load()
|
|
out = {}
|
|
print(f"{'factor':>8} {'APS':>6} {'solved':>7} {'CHA':>6} {'solved':>7} {'both':>6}")
|
|
for fac in FACTORS:
|
|
p = per_problem(lambda f, a, b, xt, mx, _f=fac: ours(f, a, b, xt, mx, _f),
|
|
probs, 200)
|
|
t, ok = totals(p, probs)
|
|
out[fac] = (t["APS"], ok["APS"], t["CHA"], ok["CHA"])
|
|
mark = " <- the text's choice" if fac == 2.0 else ""
|
|
print(f"{fac:8.2f} {t['APS']:6d} {ok['APS']:4d}/154 {t['CHA']:6d} {ok['CHA']:4d}/45 "
|
|
f"{t['APS'] + t['CHA']:6d}{mark}")
|
|
p = per_problem(credit, probs, 200)
|
|
t, ok = totals(p, probs)
|
|
out["credit"] = (t["APS"], ok["APS"], t["CHA"], ok["CHA"])
|
|
print(f"{'credit':>8} {t['APS']:6d} {ok['APS']:4d}/154 {t['CHA']:6d} {ok['CHA']:4d}/45 "
|
|
f"{t['APS'] + t['CHA']:6d} <- no multiplier, bound = bisection + 1 step")
|
|
# The credit rule's own number, the endowment C0, promises bisection + ceil(C0)
|
|
# steps. Every C0 in (0,1] promises the same single step; the claim in the code is
|
|
# that 1, the most permissive of them, is also the cheapest - measured here.
|
|
print(f"\n{'C0':>8} {'APS':>6} {'CHA':>6} {'both':>6} promise")
|
|
out["endowment"] = {}
|
|
for c0 in (0.1, 0.5, 1.0, 2.0, 5.0):
|
|
p = per_problem(lambda f, a, b, xt, mx, _c=c0: pure_root(
|
|
f, a, b, xt, mx, similarity="ratio", scale="derived3", guard="credit",
|
|
endowment=_c), probs, 200)
|
|
t, ok = totals(p, probs)
|
|
out["endowment"][c0] = (t["APS"], t["CHA"])
|
|
steps = -(-c0 // 1)
|
|
print(f"{c0:8.2f} {t['APS']:6d} {t['CHA']:6d} {t['APS'] + t['CHA']:6d} "
|
|
f"bisection + {int(steps)} step(s)")
|
|
return out
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|