README rewritten for a public mirror: what the method is, the licence and the archive DOI, how to use the compiled library, what it costs on the corpus fixed before the code was frozen, how to reproduce, the layout, and what was refuted. The old text still stated 72 checks, 490 tests and an order of 1.944, none of which has been true for some time.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -1,82 +1,71 @@
|
|||||||
# sim-numerics — similarity as a step rule for root finding
|
# sim-numerics — similarity and analogy as step rules for root finding
|
||||||
|
|
||||||
Artifact for the paper `article/sim_numerics.tex`. Every claim in the paper is
|
A bracketing root finder derived from a similarity function, with a decision layer that recognises
|
||||||
produced by one of the scripts below; nothing in the text is transcribed by
|
multiple and fractional roots by analogy, and a worst case of twice bisection plus three evaluations
|
||||||
hand, and `verify_article.py` checks all 72 stated numbers against the run
|
that holds whatever proposes the step.
|
||||||
data as part of the test suite.
|
|
||||||
|
Everything here is released under the Apache License 2.0; copyright Valeri Sitnikov (`NOTICE`).
|
||||||
|
Archive of record, with the paper, the data and the full history:
|
||||||
|
[10.5281/zenodo.22894336](https://doi.org/10.5281/zenodo.22894336) (version 1.0.0:
|
||||||
|
[10.5281/zenodo.22894337](https://doi.org/10.5281/zenodo.22894337)).
|
||||||
|
|
||||||
|
## Using the method
|
||||||
|
|
||||||
|
`lib/` builds `simbracket`, the method as a compiled library (Cython, Python 3.10 or later, wheels for
|
||||||
|
Linux and Windows in the archive). It agrees with the reference implementation bit for bit, point and
|
||||||
|
evaluation count, on all 868 problems of the six corpora.
|
||||||
|
|
||||||
|
```python
|
||||||
|
from simbracket import find_root, evaluation_bound
|
||||||
|
|
||||||
|
x, nfev, converged = find_root(f, a, b, xtol=1e-12, maxfev=200)
|
||||||
|
# f(a) and f(b) of opposite signs; stops when the bracket is no wider than xtol or f(x) == 0;
|
||||||
|
# never more than evaluation_bound(a, b, xtol) = 2*ceil(log2(|b-a|/xtol)) + 3 evaluations
|
||||||
|
```
|
||||||
|
|
||||||
|
From source instead: `simroot.pure.pure_root` with the configuration named `APRIME` in
|
||||||
|
`sweep_full.py`.
|
||||||
|
|
||||||
|
## What it costs
|
||||||
|
|
||||||
|
On the 240 problems of corpus 4, fixed before the method's code was frozen, the method needs 3656
|
||||||
|
evaluations. Chandrupatla's method needs 5717 there, ModAB 5535, Brent 8267 and TOMS 748 8084. It is
|
||||||
|
the cheapest of those methods on 77% of the problems, and on 88% of the multiple and fractional
|
||||||
|
roots.
|
||||||
|
|
||||||
## Reproducing
|
## Reproducing
|
||||||
|
|
||||||
|
Use one platform for all numbers. The test functions call `libm`, whose last digit differs between
|
||||||
|
platforms, and the same SciPy version scores 2635 for TOMS 748 on Windows against 2636 on Linux for
|
||||||
|
the same set. The published numbers are from Linux (Ubuntu 24.04, Python 3.12.3).
|
||||||
|
|
||||||
```
|
```
|
||||||
python -m pytest tests/ -q # 490 tests
|
python -m pytest tests -q # 1240 tests
|
||||||
python sweep_full.py # the full grid, writes sweep_full.json
|
python -u verify_article.py # 548 numbers of the paper against the run data
|
||||||
python verify_article.py # every paper number vs the data
|
|
||||||
```
|
```
|
||||||
|
|
||||||
Heavy runs go to a Linux machine (Python 3.12, run detached with a log,
|
Any table of the paper can be recomputed from scratch with its sweep script; each script's docstring
|
||||||
`setsid nohup ... > sweep.log 2>&1`). **Use one platform for all numbers**: the
|
names the table it produces. Heavy runs belong on a Linux machine, detached, with a log.
|
||||||
test functions call `libm`, whose last digit differs between Windows and Linux,
|
|
||||||
and the same SciPy version scores 2819 for TOMS 748 on Windows against 2820 on
|
|
||||||
Linux for the same set. The paper's numbers are the Linux ones.
|
|
||||||
|
|
||||||
## Where each claim comes from
|
|
||||||
|
|
||||||
| Paper | Claim | Script |
|
|
||||||
|---|---|---|
|
|
||||||
| Prop. 1 | the two-point similarity step **is** regula falsi | `tests/test_simroot.py::test_the_pure_two_point_similarity_step_is_regula_falsi_exactly` |
|
|
||||||
| Prop. 2, Table 1 | contraction law, predicted 0.1716 vs measured 0.1716 | `stage0c_why_pure_fails.py` |
|
|
||||||
| Cor. 1 | a chosen similarity fails on 5–8 of 8 problems | `stage0b_pure_similarity.py` |
|
|
||||||
| Cor. 2 | faster similarity is not better (`sqrt`, `cbrt`) | `stage0d_derived_similarity.py` |
|
|
||||||
| Cor. 3 | derived scale ⇒ the step is \|f\|/\|f'\| ⇒ superlinear | `stage0d_derived_similarity.py`, `stage0e_guard_cost.py` |
|
|
||||||
| §3 safeguards | bracket vs step vs both, and what each costs | `stage2_guard_modes.py`, `stage3_bound_check.py` |
|
|
||||||
| §3 order | 1.584 (2-point) vs 1.944 (3-point) | `stage5_three_point.py` |
|
|
||||||
| §3.1 | project vs replace; the guarantee costs nothing | `stage6_projection.py` |
|
|
||||||
| §3.1 | the projection invariant, instrumented per step | `stage6b_invariant.py` |
|
|
||||||
| §4 fairness | ITP is not handicapped; κ₁ and n₀ sweeps | `stage2b_itp_fairness.py` |
|
|
||||||
| Tables 2, 3 | the 154-configuration ranking on both sets | `sweep_full.py` → `report_sweep.py` |
|
|
||||||
| Table 4 | the law across the whole grid | `sweep_full.py` → `report_sweep.py` |
|
|
||||||
| §6 | approach vs endgame, order, boldness, step quality | `stage4_why.py` |
|
|
||||||
| §7.1 | the prototype-aggregation form loses 0/6/147 | `bench_full.py` (`SIM.pair2d.*`) |
|
|
||||||
| §7.2 | the 2× bound and high order are incompatible | `stage5_three_point.py`, `tests/test_three_point.py` |
|
|
||||||
| §7.4 | the symmetric ratio similarity degenerates | `simroot/pure.py` (`PURE_SIMS["ratio"]` docstring), `stage0d` |
|
|
||||||
|
|
||||||
## Layout
|
## Layout
|
||||||
|
|
||||||
```
|
```
|
||||||
simroot/pure.py the method: one similarity, one step rule, three guards
|
simroot/pure.py the method: the similarity step, the decision layer, the projection
|
||||||
simroot/baselines.py bisection, 4 false-position variants, Ridders, Brent,
|
simroot/baselines.py bisection, the false-position family, Ridders, Brent, TOMS 748, ITP
|
||||||
TOMS 748 (SciPy), ITP (own, validated against its theorem)
|
lib/ the source of the compiled library simbracket
|
||||||
simroot/sim.py the prototype-aggregation form — a NEGATIVE result, kept
|
corpus_*.py the problem corpora, as code
|
||||||
because the paper reports it
|
sweep_*.py the runs; each writes its results file
|
||||||
stage0*..stage5* the derivation, in the order it was actually established
|
verify_article.py every number stated in the paper, against the data
|
||||||
bench_full.py 17 methods on both sets
|
article/ the paper
|
||||||
sweep_full.py 9 similarities x 4 scales x 4 guards + 10 baselines
|
PREREG_*.md POSTHOC_*.md what was recorded before each run, and what after
|
||||||
report_sweep.py reads sweep_full.json, produces the paper's tables
|
FINDINGS_*.md what the diagnoses found
|
||||||
verify_article.py asserts the paper against the data (72 checks)
|
tests/ 1240 tests; every bug found in an audit is pinned here
|
||||||
tests/ 490 tests; every bug found in audit is pinned here
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Negative results, so they are not reopened
|
## What was refuted
|
||||||
|
|
||||||
1. Similarity normalised by the two bracket ends **is** regula falsi, identically.
|
The archive keeps eleven negative results in the form in which they were written, among them: a
|
||||||
2. A faster-changing similarity is not better; what matters is the slope of
|
similarity normalised by the two bracket ends is regula falsi identically; a faster-changing
|
||||||
`1 - S` at zero matching the problem, and only the data supplies it.
|
similarity is not better; every safeguard that *replaces* the computed step with a midpoint destroys
|
||||||
3. Prototype-pair aggregation with softmax over the whole memory loses to the
|
the order, which is why the step is projected instead; and the phase detector whose derivation is
|
||||||
simplest form: 0 wins / 6 ties / 147 losses against Brent on APS.
|
sound and whose estimator is not. They are kept so that they are not reopened.
|
||||||
4. "Our safeguard fires less often" — refuted: Brent discards 53% of its
|
|
||||||
interpolations on the set it wins, 34% on the set it loses.
|
|
||||||
5. "Our steps are bolder" — refuted: on Chandrupatla Brent is bolder (56.3%
|
|
||||||
against 41.8%) and still loses. The mechanism is step *quality*: median
|
|
||||||
bracket removed 0.275 against 0.058.
|
|
||||||
6. Every safeguard that REPLACES the computed step with a midpoint destroys the
|
|
||||||
order: with the three-point scale, order falls from 1.94 to 1.00 and the APS
|
|
||||||
total from 2806 to 7260. **Resolved** by projecting the step onto the
|
|
||||||
admissible interval instead (`guard="project"`), which costs nothing on APS
|
|
||||||
(2806 either way) and gains on Chandrupatla (40/45 at 3220 against 35/45 at
|
|
||||||
4104 unguarded).
|
|
||||||
7. Zero slack in the projection is degenerate: a worst case of exactly bisection
|
|
||||||
demands a halving at every step, leaving the projection no freedom.
|
|
||||||
8. Writing the projection as a radius around the midpoint instead of a clamp
|
|
||||||
loses the invariant to cancellation — a relative 8.9e-5 overshoot on eleven
|
|
||||||
Chandrupatla problems.
|
|
||||||
```
|
|
||||||
|
|||||||
Reference in New Issue
Block a user