"""Revision 2: points 2-7 into article/sim_numerics.md. 2 'pre-registered' -> 'recorded in advance'; Appendix D says the order is attested only by the author's git history 3 why Dekker, Illinois and false position show the same totals under both criteria 4 exact-zero stops in Table 11, per method 5 control K3 (PREREG_estimated_transform): Table 12 and its paragraph; 6.6, conclusion, future work 6 Algorithms 1-2: lo/hi, the return on a stall, L_x and L_f, an empty memory, the step pattern as a formula, the O(n^2) search 7 Table 3's two missing bracket-scaled rows; dashes in Table 5; the abstract's last sentence Exact anchors, each found exactly once, or nothing is written. python -u apply_article_revision2.py """ from __future__ import annotations PATH = "article/sim_numerics.md" R = [] def E(old, new): R.append((old, new)) # ---- point 2 E("The code, the corpora and the pre-registrations are released", "The code, the corpora and the documents that recorded each test before its run are released") E("Every rule below was pre-registered with a stop rule (Appendix D);", "Every rule below was recorded, with its criteria and stop rule, before its code and run (Appendix D);") E("because the pre-registered rule removes only a component", "because the rule recorded in advance removes only a component") E("Pre-registration protects each decision but not the chain:", "Recording each decision in advance protects the decision but not the chain:") E("by every pre-registered criterion (per problem", "by every criterion recorded in advance (per problem") E("Both were pre-registered, with what the paper would say under every outcome, before the run", "Both were recorded, with what the paper would say under every outcome, before the run") E("as the pre-registered criterion required.", "as the criterion recorded in advance required.") E("the pre-registrations with the commits of Appendix D;", "the advance records with the commits of Appendix D;") E("and it passed every pre-registered criterion there.", "and it passed every criterion recorded for it there.") E("was rejected by its own pre-registration,", "was rejected by its own advance record,") E("## Appendix D. Pre-registrations and the frozen code", "## Appendix D. Advance records and the frozen code") E("The code of A′ was committed (`8027d7f`)", "We call these documents advance records, not pre-registrations: they live in the author's repository, and their order relative to the runs is attested only by the author's git history, whose timestamps the author sets; no external registry was used. A deposit with an external timestamp (Zenodo, OSF) before a run would remove that limitation for future tests. The code of A′ was committed (`8027d7f`)") E("**Table D1.** Pre-registrations, in the order they were written.", "**Table D1.** Advance records, in the order they were written.") E("| pre-registration | commit | results file | commit | order |", "| advance record | commit | results file | commit | order |") # ---- point 3 E("and 79/5/70 against Brent.", "and 79/5/70 against Brent. Dekker, Illinois and false position fail `aps.13.00` under either criterion and so keep their totals: they spend the whole budget without converging, Dekker and Illinois stalled on one side of the zero where $|f|<10^{-62}$ but $f$ does not change sign within $10^{-6}$.") # ---- point 4 E("With the multiplicity known the transformation is 2.4 to 6.8 times cheaper than A′.", "With the multiplicity known the transformation is 2.4 to 6.8 times cheaper than A′. Every method, A′ included, stops on an exact zero of the function it evaluates, and on the pure powers of the Chandrupatla set $g$ is exactly linear, so the secant lands on the root: 15 of Brent's 20 runs and 4 of Chandrupatla's end that way there (A′: 2). On new corpus 1 no transformed run ends on a zero, and the transformation is still 3.4 times cheaper.") # ---- point 5: K3 K3 = """ **The multiplicity estimated during the run.** Between A′ and the oracle lies the natural classical method: Chandrupatla's interpolation on $g=\\operatorname{sign}(f)|f|^{1/\\hat m}$ with $\\hat m$ estimated during the run. Our implementation of Chandrupatla's method (identical to the library on all 199 problems, and to itself when $\\hat m\\equiv1$) keeps the true $f$ at its three points and reads $G(v)=\\operatorname{sign}(v)|v|^{1/\\hat m}$ only in the acceptance band and the interpolation; $\\hat m$ starts at 1 and takes an order read from the last three evaluations whenever that order lies on a branch of §6.1 ($m\\ge2$ or $0 1/2, # and step and x - xp point the same way if the pattern repeats:""", """ # step pattern: q_j <- |d_j|/|d_(j-1)| over successive nonzero # moves d (k of them); rho(u,v) <- min(u,v)/max(u,v); repeats iff # max over p = 2..floor(k/2) of mean_j rho(q_j, q_(j-p)) > 1/2 if repeats and step, x - xp point the same way:""") E(" xn <- clamp(xn, hi - allow, lo + allow) # projection (3)", " lo, hi <- min(A,B), max(A,B)\n xn <- clamp(xn, hi - allow, lo + allow) # projection (3)") E(" xn <- mid; if mid in {x, xp}: stop", " xn <- mid; if mid in {x, xp}: return mid") E("implement exactly this and agree bit for bit.", "implement exactly this and agree bit for bit. The nearest-configuration search runs over the run's memory: $O(n)$ per step, $O(n^2)$ per run of $n$ evaluations ($n\\le200$ here), arithmetic that matters only when $f$ is cheap (Appendix B).") # ---- point 7 E("| 3 | similarity, $e^{-\\lvert z\\rvert}$, bracket scale, both guards | no | 45/45 | 1778 | 0 |", "| 3 | similarity, $e^{-\\lvert z\\rvert}$, bracket scale, both guards | no | 45/45 | 1778 | 0 |\n| 4 | similarity, $e^{-\\lvert z\\rvert}$, bracket scale, bracket guard | no | 45/45 | 1848 | 0 |") E("| 5 | ITP, recommended constants | yes | 45/45 | 1946 | 0 |", "| 5 | ITP, recommended constants | yes | 45/45 | 1946 | 0 |\n| 6 | similarity, $e^{-\\lvert z\\rvert}$, bracket scale, earned projection | no | 45/45 | 1952 | 0 |") E("| A′, earned budget (no free constant) | 3417 | 1852 | 5269 | | |", "| A′, earned budget (no free constant) | 3417 | 1852 | 5269 | — | — |") E("| base rule (§3) | 2634 | 2357 | 4991 | | |", "| base rule (§3) | 2634 | 2357 | 4991 | — | — |") E("We replace bisection's midpoint rule by a similarity rule — the step grows with how dissimilar $f(x)$ is to the target 0, under a similarity $S$ with $S(0)=1$ — and derive", "We replace bisection's midpoint rule by a similarity rule — the step grows with the dissimilarity of $f(x)$ to 0 under a similarity $S$ — and derive") E("With the multiplicity known, the classical transformation $\\operatorname{sign}(f)|f|^{1/m}$ is 2.4 to 6.8 times cheaper on multiple roots.", "With the multiplicity known, the classical transformation $\\operatorname{sign}(f)|f|^{1/m}$ is 2.4 to 6.8 times cheaper on multiple roots; what A′ adds is an estimate of the order made without knowing it, within a guarantee of twice bisection.") def main(): src = open(PATH, encoding="utf8").read() bad = [o[:80] for o, _ in R if src.count(o) != 1] if bad: for b in bad: print("ANCHOR NOT FOUND EXACTLY ONCE:", repr(b)) raise SystemExit(f"{len(bad)} anchors failed; nothing written") for o, n in R: src = src.replace(o, n) open(PATH, "w", encoding="utf8").write(src) ab = src.split("## Abstract\n\n")[1].split("\n\n---\n")[0] code = src.split("**Algorithm 2 (A′).**")[1].split("```")[1] print(f"applied {len(R)}; abstract {len(ab.split())} words; longest Algorithm 2 line " f"{max(len(l) for l in code.split(chr(10)))}; 'pre-regist' left: {src.lower().count('pre-regist')}") if __name__ == "__main__": main()