baseline: the published sim-numerics artifact as it stands (490 tests, verify_article.py checks all 72 paper numbers against sweep_full.json)
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,157 @@
|
||||
"""Stage 10 - checking the technical claims independently.
|
||||
|
||||
Five of them change the content of the paper rather than its wording, so none
|
||||
is accepted on authority. Each is recomputed here from scratch.
|
||||
|
||||
A. The proposed similarity IS the one Table 1's last row calls degenerate,
|
||||
and the degeneracy is specific to the CHOSEN scale.
|
||||
B. Proposition 1 is true for the ratio form only, not for similarity rules
|
||||
in general.
|
||||
C. The bracket-endpoint divided difference plus the tent similarity is
|
||||
regula falsi exactly - so the words "most recent" in the definition of
|
||||
f-hat are load-bearing.
|
||||
D. Table 1's c = 0 rows report a window artefact; the true behaviour is
|
||||
sublinear, e_n ~ sigma^2 / (c2 f'(r)^2 |D| n).
|
||||
E. The order of a Newton step with an O(h^2) derivative estimate is 2, not
|
||||
the 1.84 the paper claims.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
|
||||
r2 = math.sqrt(2.0)
|
||||
f = lambda x: x * x - 2.0
|
||||
|
||||
TENT = lambda z: max(0.0, 1.0 - abs(z))
|
||||
RATIO = lambda z: 1.0 / (1.0 + abs(z))
|
||||
RAT_SQ = lambda z: 1.0 / (1.0 + z * z)
|
||||
EXP_SQ = lambda z: math.exp(-z * z)
|
||||
COSINE = lambda z: 1.0 / math.sqrt(1.0 + z * z)
|
||||
|
||||
|
||||
def iterate(S, n, sigma=2.0, x0=0.0, xfar=2.0):
|
||||
x, errs = x0, []
|
||||
for _ in range(n):
|
||||
x = x + (1.0 - S(f(x) / sigma)) * (xfar - x)
|
||||
errs.append(abs(x - r2))
|
||||
return errs
|
||||
|
||||
|
||||
def main():
|
||||
print("=" * 76)
|
||||
print("A. the tent similarity under the CHOSEN scale")
|
||||
print("=" * 76)
|
||||
e = iterate(TENT, 200)
|
||||
print(f" z at x=0 is {f(0.0) / 2.0:+.1f}, so S = {TENT(f(0.0) / 2.0):.1f} "
|
||||
f"and the step is the whole bracket")
|
||||
print(f" |e| after 1 step: {e[0]:.4f} after 200: {e[-1]:.4f} "
|
||||
f"{'CAPTURED at the far end' if abs(e[0] - e[-1]) < 1e-15 else 'moves'}")
|
||||
print(" => the paper proposes, in section 3, the function its own")
|
||||
print(" Table 1 calls degenerate. CONFIRMED.")
|
||||
|
||||
print("\n but under the DERIVED scale the clip never engages:")
|
||||
# replay the proposed configuration and record how often |f|/sigma >= 1
|
||||
from simroot.pure import _slope3
|
||||
clipped = total = 0
|
||||
a, b = 0.0, 2.0
|
||||
fa, fb = f(a), f(b)
|
||||
A, FA, B = a, fa, b
|
||||
x, fx, xp, fp = a, fa, b, fb
|
||||
xp2 = fp2 = None
|
||||
for _ in range(40):
|
||||
if abs(B - A) <= 1e-12:
|
||||
break
|
||||
far = B if abs(B - x) >= abs(A - x) else A
|
||||
slope = _slope3(x, fx, xp, fp, xp2, fp2)
|
||||
sc = abs(slope) * abs(far - x)
|
||||
if sc == 0.0:
|
||||
break
|
||||
z = abs(fx) / sc
|
||||
total += 1
|
||||
clipped += z >= 1.0
|
||||
xn = x + min(1.0, z) * (far - x)
|
||||
lo, hi = min(A, B), max(A, B)
|
||||
if not (lo < xn < hi):
|
||||
xn = 0.5 * (A + B)
|
||||
fn = f(xn)
|
||||
xp2, fp2, xp, fp, x, fx = xp, fp, x, fx, xn, fn
|
||||
if FA * fn < 0.0:
|
||||
B = xn
|
||||
else:
|
||||
A, FA = xn, fn
|
||||
print(f" steps {total}, of which clipped at z>=1: {clipped}")
|
||||
|
||||
print("\n" + "=" * 76)
|
||||
print("B/C. Proposition 1: which similarity reproduces regula falsi?")
|
||||
print("=" * 76)
|
||||
a, b = 1.0, 4.0
|
||||
fa, fb = f(a), f(b)
|
||||
falsi = (a * fb - b * fa) / (fb - fa)
|
||||
print(f" regula falsi point on [1,4]: {falsi:.6f}\n")
|
||||
print(f" {'similarity':14s}{'scale = |f(x_far)|':>22s}{'match':>8s}")
|
||||
print(" " + "-" * 44)
|
||||
for name, S in (("1/(1+|z|)", RATIO), ("exp(-|z|)", lambda z: math.exp(-abs(z))),
|
||||
("1/(1+z^2)", RAT_SQ), ("1/sqrt(1+z^2)", COSINE),
|
||||
("tent", TENT)):
|
||||
pt = a + (1.0 - S(f(a) / abs(fb))) * (b - a)
|
||||
print(f" {name:14s}{pt:>22.6f}{'YES' if abs(pt - falsi) < 1e-12 else 'no':>8s}")
|
||||
print("\n => the identity holds for the ratio form only. The paper's")
|
||||
print(" conclusion 'a similarity rule whose scale is taken from the")
|
||||
print(" bracket is not a new method' is too broad. CONFIRMED.")
|
||||
|
||||
sigma = abs((fb - fa) / (b - a)) * abs(b - a)
|
||||
pt = a + min(1.0, abs(fa) / sigma) * (b - a)
|
||||
print(f"\n tent + divided difference over the BRACKET ENDS: {pt!r}")
|
||||
print(f" equals regula falsi exactly: {pt == falsi}")
|
||||
print(" => 'most recent' in the definition of f-hat is load-bearing:")
|
||||
print(" ends give regula falsi, recent iterates give the secant.")
|
||||
|
||||
print("\n" + "=" * 76)
|
||||
print("D. Table 1, the c = 0 rows")
|
||||
print("=" * 76)
|
||||
print(f" {'n':>6s}" + "".join(f"{s:>14s}" for s in
|
||||
("1/(1+z^2)", "exp(-z^2)", "1/sqrt(1+z^2)")))
|
||||
print(" " + "-" * 48)
|
||||
seqs = {n: iterate(S, 4001) for n, S in
|
||||
(("1/(1+z^2)", RAT_SQ), ("exp(-z^2)", EXP_SQ),
|
||||
("1/sqrt(1+z^2)", COSINE))}
|
||||
for n in (5, 10, 15, 40, 100, 1000, 4000):
|
||||
row = "".join(f"{seqs[k][n] / seqs[k][n - 1]:>14.4f}" for k in seqs)
|
||||
print(f" {n:>6d}{row}")
|
||||
print("\n the ratio creeps to 1 - there is no rate to measure, and the")
|
||||
print(" paper's 0.9357 / 0.9444 / 0.9327 are the value at n ~ 10-15.")
|
||||
print("\n the real law: 1 - S = c2 z^2 + O(z^4) gives")
|
||||
print(" e_{n+1} = e_n - c2 f'(r)^2 |D| e_n^2 / sigma^2 + ...")
|
||||
print(" => e_n ~ sigma^2 / (c2 f'(r)^2 |D|) . 1/n")
|
||||
fp, D, sig = 2.0 * r2, 2.0 - r2, 2.0
|
||||
# c2 is measured, not transcribed from a Taylor expansion done by hand:
|
||||
# a verification script carrying my own derived constant would be checking
|
||||
# my arithmetic against itself.
|
||||
for name, S in (("1/(1+z^2)", RAT_SQ), ("exp(-z^2)", EXP_SQ),
|
||||
("1/sqrt(1+z^2)", COSINE)):
|
||||
h = 1e-4
|
||||
c2 = (1.0 - S(h)) / (h * h)
|
||||
pred = sig * sig / (c2 * fp * fp * D)
|
||||
meas = 4000 * seqs[name][4000]
|
||||
print(f" {name:14s} predicted n.e_n -> {pred:7.4f} "
|
||||
f"measured at n=4000: {meas:7.4f}")
|
||||
|
||||
print("\n" + "=" * 76)
|
||||
print("E. the order of the three-point rule")
|
||||
print("=" * 76)
|
||||
print(" Newton with a derivative estimate of error O(h^2):")
|
||||
print(" e' = e - f/f-hat = e - (e - c e^2 + ...)(1 + O(e^2)) = c e^2")
|
||||
print(" so the order is 2, not the 1.84 of Muller's method, which uses")
|
||||
print(" the quadratic's ROOT rather than its DERIVATIVE.")
|
||||
from simroot.pure import pure_root
|
||||
from stage5_three_point import PROBLEMS, order_of
|
||||
ps = [order_of(lambda f_, a_, b_, xt, mx: pure_root(
|
||||
f_, a_, b_, 1e-12, 200, scale="derived3", guard="project"),
|
||||
fn, aa, bb, rr) for _n, fn, aa, bb, rr in PROBLEMS]
|
||||
ps = [p for p in ps if math.isfinite(p) and 0.5 < p < 5.0]
|
||||
print(f" measured median over the eight problems: "
|
||||
f"{sorted(ps)[len(ps) // 2]:.3f} predicted: 2")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user