diff --git a/apply_article_modab.py b/apply_article_modab.py new file mode 100644 index 0000000..71a0af2 --- /dev/null +++ b/apply_article_modab.py @@ -0,0 +1,103 @@ +"""ModAB in article/sim_numerics.md (PREREG_modab outcome, sweep_modab.json): Table 8 and +Table 10 rows, the protocol note, the evidence paragraph of section 9, the precursor of the +exit judgment in 8.6, the abstract, the conclusion, future work, the introduction and +reference 20. Exact anchors, each found exactly once, or nothing is written. + + python -u apply_article_modab.py +""" +from __future__ import annotations + +PATH = "article/sim_numerics.md" + +REPL = [ + # introduction + ("an interpolate–truncate–project cycle in ITP [4].", + "an interpolate–truncate–project cycle in ITP [4], an Anderson–Björck step behind a linearity " + "check in ModAB [10, 20]."), + # Table 8 + ("| ITP, per-problem oracle | 3260 | 2647 | 5907 | A′ 126/7/20 | A′ 35/1/4 |", + "| ITP, per-problem oracle | 3260 | 2647 | 5907 | A′ 126/7/20 | A′ 35/1/4 |\n" + "| ModAB [10, 20] | 2914 | 2436 | 5350 | A′ 118/11/25 | A′ 32/9/4 |"), + # section 9: how ModAB is run + ("Where roots are not known in closed form, and for uniformity on all six corpora,", + "ModAB, the most recent bracketing method we know of, is run from its authors' package " + "(`pymodab` 1.0.9, a wrapper of their C code) with the stopping rule of every other method — a " + "bracket no wider than $\\varepsilon_x$, the relative term at machine precision, no stopping on " + "$|f|$ — and counted by the same wrapper around $f$, whose count agrees with the package's own. " + "Where roots are not known in closed form, and for uniformity on all six corpora,"), + # Table 10 + ("| corpus | A′ | Chandrupatla | Brent | TOMS 748 | A′ vs Chandrupatla |\n|---|---|---|---|---|---|", + "| corpus | A′ | Chandrupatla | ModAB | Brent | TOMS 748 | A′ vs Chandrupatla | A′ vs ModAB |\n" + "|---|---|---|---|---|---|---|---|"), + ("| APS (154) | **2259** (0) | 2595 (0) | 2707 (0) | 2636 (0) | 103/20/31, $p=3\\cdot10^{-10}$ |", + "| APS (154) | **2259** (0) | 2595 (0) | 2726 (0) | 2707 (0) | 2636 (0) | 103/20/31, $p=3\\cdot10^{-10}$ | 118/10/26 |"), + ("| Chandrupatla (45) | **1074** (0) | 1505 (0) | 3238 (18) | 3088 (15) | 31/4/10, $p=0.001$ |", + "| Chandrupatla (45) | **1074** (0) | 1505 (0) | 1681 (0) | 3238 (18) | 3088 (15) | 31/4/10, $p=0.001$ | 34/4/7 |"), + ("| new corpus 1 (206) | **3290** (0) | 3716 (0) | 6395 (38) | 5746 (22) | 108/33/65, $p=0.001$ |", + "| new corpus 1 (206) | **3290** (0) | 3716 (0) | 3809 (1) | 6395 (38) | 5746 (22) | 108/33/65, $p=0.001$ | 125/26/55 |"), + ("| Roots.jl (78) | **1371** (0) | 1566 (0) | 2455 (11) | 2339 (9) | 44/14/20, $p=0.004$ |", + "| Roots.jl (78) | **1371** (0) | 1566 (0) | 1446 (0) | 2455 (11) | 2339 (9) | 44/14/20, $p=0.004$ | 47/11/20 |"), + ("| applied + GSL (132) | 1382 (0) | 1382 (0) | 1503 (1) | 1756 (1) | 48/52/32, $p=0.09$ |", + "| applied + GSL (132) | 1382 (0) | 1382 (0) | 1460 (0) | 1503 (1) | 1756 (1) | 48/52/32, $p=0.09$ | 76/35/21 |"), + ("| **corpus 4 (240), the one test** | **3656** (0) | 5717 (0) | 8267 (50) | 8084 (37) | **177/35/28, $p=10^{-27}$** |", + "| **corpus 4 (240), the one test** | **3656** (0) | 5717 (0) | 5535 (8) | 8267 (50) | 8084 (37) | **177/35/28, $p=10^{-27}$** | **183/23/34** |"), + ("| all 855 | **13032** | 16481 | 24565 | 23649 | |", + "| all 855 | **13032** | 16481 | 16657 | 24565 | 23649 | | |"), + # the evidence paragraph + ("**What the evidence supports, and what it does not.** Against Brent and TOMS 748 A′ is ahead on " + "every corpus, by 8% to 67% in total, and it keeps its bound on all 855 problems, which Brent breaks " + "on 118 and TOMS 748 on 84.", + "**What the evidence supports, and what it does not.** Against Brent and TOMS 748 A′ is ahead on " + "every corpus, by 8% to 67% in total, and it keeps its bound on all 855 problems, which Brent breaks " + "on 118 and TOMS 748 on 84. Against ModAB it is ahead on every corpus, in total and problem by " + "problem ($p\\le0.0013$), on the one test of corpus 4 by 3656 to 5535 and 183 problems to 34 " + "($p=7\\cdot10^{-26}$), and on ModAB's own benchmark as well — all 91 problems of it, 1507 against " + "1588, 56/13/22 ($p=1.5\\cdot10^{-4}$); ModAB breaks the bound on 9 problems."), + # 8.6 table: the exit judgment's precursor + ("| the tolerance step | Dekker [9], Brent [2] — borrowed and named as such |", + "| the tolerance step | Dekker [9], Brent [2] — borrowed and named as such |\n" + "| the exit judgment of §8.2 (the value at a split against the line) | ModAB's linearity check at " + "the midpoint [10, 20], $|y_m-y_3| cost(mm[p]) for p in am) + check(f"A' vs ModAB protocol {setname}", (w, len(am) - w - l, l), want) + md = dict(mb["seen"]["modab"]) + md.update(mb["fourth"]["modab"]) + worst_p = 0.0 + for s, (tm, vm, wtl) in {"APS": (2726, 0, (118, 10, 26)), "CHA": (1681, 0, (34, 4, 7)), + "NEW": (3809, 1, (125, 26, 55)), "RJL": (1446, 0, (47, 11, 20)), + "APP": (1460, 0, (76, 35, 21)), "D": (5535, 8, (183, 23, 34))}.items(): + m = md[s] + check(f"Table 10 ModAB {s}", (sum(cost(v) for v in m.values()), + sum(v[2] for v in m.values())), (tm, vm)) + ps = list(seen["Aprime"][s]) + w = sum(cost(seen["Aprime"][s][p]) < cost(m[p]) for p in ps) + l = sum(cost(seen["Aprime"][s][p]) > cost(m[p]) for p in ps) + check(f"Table 10 A' vs ModAB {s}", (w, len(ps) - w - l, l), wtl) + worst_p = max(worst_p, sign_p(w, l)) + check("A' vs ModAB: every corpus p <= 0.0013", round(worst_p, 4) <= 0.0013, True) + check("ModAB over all 855", sum(sum(cost(v) for v in md[s].values()) for s in names), 16657) + check("ModAB violations over 855", sum(v[2] for s in names for v in md[s].values()), 9) + check("corpus 4 A' vs ModAB p (1 digit)", f"{sign_p(183, 34):.1g}", "7e-26") + rjm = mb["rjl"] + ps91 = list(rjm["Aprime"]) + w = sum(cost(rjm["Aprime"][p]) < cost(rjm["modab"][p]) for p in ps91) + l = sum(cost(rjm["Aprime"][p]) > cost(rjm["modab"][p]) for p in ps91) + check("ModAB's own benchmark, all 91", (len(ps91), sum(cost(rjm["Aprime"][p]) for p in ps91), + sum(cost(rjm["modab"][p]) for p in ps91), + (w, len(ps91) - w - l, l)), + (91, 1507, 1588, (56, 13, 22))) + check("ModAB's own benchmark p (2 digits)", f"{sign_p(w, l):.2g}", "0.00015") + print("\nTable 9a and section 7: the similarity in the step (fresh audit run):") aps_ = {r["spec"][1]: r for r in _load("sweep_aprime_s.json")} abs_ = _load("sweep_ablation_s.json")