Revision step 2 into the paper: section 9.1 (Tables 9b, 9c) as PREREG_controls prescribes. The analogy detector beats Lagouanelle-with-memory, Chandrupatla's band and no detector on corpus 4 (3656 vs 4488, 6236, 6165); with the multiplicity given, the classical transformation is 2.4-6.8x cheaper on every multiple or fractional root - stated as the price of estimating the order, in the abstract, 8.3, 8.6, the conclusion and as the first future-work question. verify_controls(): 26 checks. Server: verify 526 OK / 0 BAD, regression x2 1232 passed, PDF 30 pages, 0 errors, 0 undefined, 0 overfull.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
vvs
2026-09-22 07:53:58 +01:00
co-authored by Claude Opus 5
parent 92c07d8a40
commit fbf13cd592
8 changed files with 532 additions and 35 deletions
+97
View File
@@ -0,0 +1,97 @@
"""PREREG_controls_2026-09-22 outcome into article/sim_numerics.md, as the pre-registration
prescribes: C1 passed for every detector (the claim of 8.6 stands, with the numbers), and K1 -
with the multiplicity known the classical transformation is much cheaper - stated plainly.
New section 9.1 (Tables 9b, 9c); a sentence each in the abstract, 8.3, 8.6, the conclusion, and
the future work. Exact anchors, each found exactly once, or nothing is written.
python -u apply_article_controls.py
"""
from __future__ import annotations
PATH = "article/sim_numerics.md"
REPL = []
def R(old, new):
REPL.append((old, new))
R("and without them the lead is 2403 against 3569, on the simple-root families alone 737 against 747.",
"and without them the lead is 2403 against 3569, on the simple-root families alone 737 against 747. "
"Against simpler detectors put in the place of the analogy — Lagouanelle's multiplicity estimate "
"with the same memory, Chandrupatla's acceptance band, or none — it wins on that corpus in total "
"and problem by problem (3656 against 4488, 6236 and 6165); against the classical transformation "
"$\\operatorname{sign}(f)|f|^{1/m}$ with the multiplicity given in advance it loses every multiple or "
"fractional root, by a factor of 2.4 to 6.8 — the price of estimating the order.")
R("classical since Schröder [16] and Traub [17]; what is new here is only where $m$ comes from.",
"classical since Schröder [16] and Traub [17]; what is new here is only where $m$ comes from. With "
"the multiplicity given in advance the transformation is far cheaper still (§9.1): the contribution "
"is the estimate, and its price is measured there.")
R("Roots.jl's `Order1B` and `Order2B` [12]); Chandrupatla takes the decision to halve by an empirical acceptance band [3].",
"Roots.jl's `Order1B` and `Order2B` [12]); Chandrupatla takes the decision to halve by an empirical "
"acceptance band [3]. §9.1 puts this claim against the detectors a reader would try first, and "
"against the transformation with the multiplicity known in advance.")
SEC91 = """
### 9.1 Controls: simpler detectors, and the multiplicity known in advance
Two controls ask whether the gain of §8 comes from the recognition by analogy or only from the split (7) with any reasonable detector. Both were pre-registered, with what the paper would say under every outcome, before the run (`sweep_controls.py`).
**Other detectors in A′.** A′ is run with only its detector swapped; the memory, the split, the exit and the five readings of §8.4 are unchanged. (a) *Lagouanelle's estimate* $m_L=1/(1-\\theta)$, $\\theta=ff''/f'^2$ from the parabola through the last three points ($m_L=\\infty$ for $\\theta\\ge1$), with the same memory — once seen, held until the exit, a hysteresis — entering at $m_L\\ge2$ and at $0<m_L\\le\\tfrac23$ and splitting at $m_L$. (b) *Chandrupatla's acceptance band*, entering when the band rejects the current triple and splitting at the current $m_L$. (c) *No detector*: the regime is entered at every unkept promise.
**Table 9b.** A′ against its detector swapped: totals on the six corpora of §9 (uniform criterion), and A′'s wins/ties/losses on corpus 4. No variant breaks the bound.
| detector | APS | CHA | new-1 | Roots.jl | applied | corpus 4 | all | A′ on corpus 4 |
|---|---|---|---|---|---|---|---|---|
| **analogy (A′)** | 2259 | **1074** | **3290** | **1371** | **1382** | **3656** | **13032** | — |
| Lagouanelle, with memory | **2235** | 1437 | 4026 | 1495 | 1490 | 4488 | 15171 | 84/121/35, $p=8\\cdot10^{-6}$ |
| Chandrupatla's band | 2682 | 2526 | 5485 | 2117 | 1622 | 6236 | 20668 | 110/96/34, $p=1.5\\cdot10^{-10}$ |
| none | 2693 | 2526 | 5569 | 2126 | 1670 | 6165 | 20749 | 113/87/40, $p=3\\cdot10^{-9}$ |
On corpus 4, the one test, A′ beats all three in total and problem by problem, as the pre-registered criterion required. The competent alternative is Lagouanelle's estimate: it is slightly better on the canonical set (2235 against 2259), and on corpus 4 A′'s lead over it lies in the multiple-root and fractional-power families (1163 against 1739, 924 against 1207); it is behind on $\\log(1+q^2)$ of a cubic (503 against 477) and level on the rest. The band and the regime without a detector are worse than no regime at all. The decision layer by analogy therefore earns its place against the detectors a reader would try first.
**The multiplicity known in advance.** The second control asks how good the classical transformation is when its multiplicity is given. Library Chandrupatla and Brent are run on $g=\\operatorname{sign}(f)\\,|f|^{1/m^*}$, with $m^*$ the order read at the known root — the slope of $\\ln|f|$ against $\\ln|x-r|$ on both sides at $h=10^{-5}$, rounded to 0.01, and 1 where either side shows no zero (a jump). It is not an achievable method but an upper bound. On the multiple and fractional roots, $m^*\\ge2$ or $m^*\\le\\tfrac23$ — the branches of §8.1 where a tangent step loses to a halving:
**Table 9c.** Multiple and fractional roots with the multiplicity given: totals, failures charged. A′ wins none of the 148 problems.
| corpus | problems | A′ | Chandrupatla on $g$ | Brent on $g$ | Chandrupatla on $f$ |
|---|---|---|---|---|---|
| Chandrupatla | 20 | 654 | 96 | 66 | 1068 |
| new corpus 1 | 40 | 1229 | 358 | 337 | 1792 |
| corpus 4 | 88 | 2159 | 901 | 844 | 4151 |
With the multiplicity known the transformation is 2.4 to 6.8 times cheaper than A′. A′ is far ahead of Chandrupatla on $f$ itself, which does not know the multiplicity either. On the remaining problems the transformed and untransformed runs differ little and A′ is close to them: ahead on the canonical sets (2259 against 2640, 420 against 437 for Chandrupatla on $g$), behind on corpora 1 and 4 (2061 against 1924, 1497 against 1427). So on multiple roots the contribution of A′ is the estimate of the order without knowing it, and the gap to Table 9c is the price of that estimate — large, and the clearest direction for improving the method."""
R("and the smooth equations of the applied corpus, where the two are level.\n",
"and the smooth equations of the applied corpus, where the two are level." + SEC91 + "\n")
R("and on a corpus fixed after its code was frozen it needs 36% fewer evaluations and wins 177 problems to 28.",
"and on a corpus fixed after its code was frozen it needs 36% fewer evaluations and wins 177 problems "
"to 28. Its decision layer beats Lagouanelle's estimate, Chandrupatla's band and no detector put in "
"its place; with the multiplicity known in advance the classical transformation is 2.4 to 6.8 times "
"cheaper on multiple roots, which measures what estimating the order costs.")
R("Two questions remain, both narrower than the one this section used to pose.\n\nThe first is the steep flank.",
"Three questions remain, all narrower than the one this section used to pose.\n\nThe first is the "
"price of estimating the order. With the multiplicity given, the transformation of §8.3 is 2.4 to 6.8 "
"times cheaper than A′ on multiple and fractional roots (Table 9c): the order read from the analogous "
"pair, or its use in the split, loses most of what the transformation could deliver.\n\nThe second is "
"the steep flank.")
R("The second is the one geometric choice of §8.2,",
"The third is the one geometric choice of §8.2,")
def main():
src = open(PATH, encoding="utf8").read()
bad = [old[:90] for old, _ in REPL if src.count(old) != 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 old, new in REPL:
src = src.replace(old, new)
open(PATH, "w", encoding="utf8").write(src)
print(f"applied {len(REPL)} replacements")
if __name__ == "__main__":
main()