Valeri's second point measured: the similarity function belongs to the PLACE it is read in, not to the method. False position's three-century stall is a similarity read at order one on an approach of order m: with sigma = |f(far)| the residual ratio is (e/E)^m, so raising it to the measured 1/m recovers the distance ratio exactly. Paired inside each cell, the correction is cheaper in 7 of 7 safeguards for S = 1/(1+z) - the one function that makes that place exact inverse interpolation - and in only 29 of 60 cells over all nine functions, i.e. a coin. It does NOT beat Chandrupatla (2884 against 2683 and 2423), it HARMS the slope reading (2806 -> 2854), and it does not cure false position: 127/154 and 10676 become 128/154 and 10043, where Illinois buys 153/154 and 7045 with one constant. Estimator bias measured and stated: a pure cube reads 2.830, not 3
Also fixes a real regression from cc2c499: the derived3_cap branch was inserted in front of the derived3_m note and swallowed its division, so derived3_m silently became derived3 (2806 against 2806) and a refutation recorded in the paper stopped being reproducible. The full pin caught it; a cheap pin now guards it too. And \label{sec:method} never existed while the table on page 7 referenced it.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+64
-7
@@ -124,6 +124,38 @@ SPACES = ("x", "log")
|
||||
POINT_RULES = ("recent", "shape")
|
||||
DIRECTIONS = ("distance", "dissimilar")
|
||||
|
||||
EXPONENTS = ("none", "order")
|
||||
|
||||
|
||||
def _read_z(resid, sc, exponent, m):
|
||||
"""The normalised residual the similarity function is applied to.
|
||||
|
||||
Valeri, 2026-09-21: "the similarity function may simply be the wrong one", and then
|
||||
"the similarity function can differ in different PLACES - not by domain, by the place
|
||||
of the parameter". This is the step-length place, and here the reading is fixed by
|
||||
what f looks like locally rather than chosen.
|
||||
|
||||
For |f| ~ K.e^m the residual ratio against the far end is dimensionless and needs no
|
||||
slope at all: z = |f(x)|/|f(far)| = (e/E)^m, so z^(1/m) = e/E recovers the DISTANCE
|
||||
ratio exactly. Under S = 1/(1+z) the step fraction is z/(1+z), which at m = 1 is
|
||||
false position (Proposition 4 in the paper: 127/154, 10560 evaluations) - and false
|
||||
position's three-century-old stall is precisely a similarity read at order 1 on an
|
||||
order-m approach. Reading it at the MEASURED order turns the same formula into
|
||||
order-m inverse interpolation, exact in one step for a pure power.
|
||||
|
||||
m comes from _local_order, i.e. from three evaluations already paid for, and is 1
|
||||
whenever the power model does not apply, so nothing here is selected.
|
||||
"""
|
||||
z = resid / sc
|
||||
if exponent == "order" and m is not None and m > 1.0 and z > 0.0:
|
||||
try:
|
||||
z = z ** (1.0 / m)
|
||||
except (OverflowError, ValueError):
|
||||
return resid / sc
|
||||
if not math.isfinite(z):
|
||||
return resid / sc
|
||||
return z
|
||||
|
||||
|
||||
def _shape_defect(x, fx, u, fu, v, fv):
|
||||
"""|phi - xi| for the triple, or None when it is degenerate.
|
||||
@@ -455,7 +487,7 @@ def _local_order(x2, f2, x1, f1, x0, f0):
|
||||
def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived",
|
||||
guard="step", stats=None, budget_factor=2.0,
|
||||
budget_extra=None, endowment=1.0, space="x", prestep="none",
|
||||
points="recent", direction="distance"):
|
||||
points="recent", direction="distance", exponent="none"):
|
||||
"""The pure similarity root finder.
|
||||
|
||||
similarity : key into PURE_SIMS
|
||||
@@ -505,8 +537,16 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived",
|
||||
if similarity not in PURE_SIMS:
|
||||
raise ValueError(f"unknown similarity {similarity!r}")
|
||||
if scale not in ("derived", "derived3", "derived_rho", "derived3_rho",
|
||||
"derived3_m", "derived3_cap", "start", "bracket"):
|
||||
"derived3_m", "derived3_cap", "start", "bracket", "far"):
|
||||
raise ValueError(f"unknown scale {scale!r}")
|
||||
if exponent not in EXPONENTS:
|
||||
raise ValueError(f"unknown exponent {exponent!r}")
|
||||
if exponent == "order" and scale not in ("derived3", "derived3_cap", "bracket", "far"):
|
||||
# the order is read from a three-point divided difference; under the two-point
|
||||
# scale there is no second difference to read it from, and computing one from
|
||||
# elsewhere would hide that (PREREG 2026-09-21, slot 1)
|
||||
raise ValueError("exponent='order' requires scale in "
|
||||
"{'derived3', 'derived3_cap', 'bracket', 'far'}")
|
||||
if space not in SPACES:
|
||||
raise ValueError(f"unknown space {space!r}")
|
||||
if prestep not in ("none", "progress", "slope"):
|
||||
@@ -604,6 +644,11 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived",
|
||||
else:
|
||||
slope = _slope3(x, fx, x_prev, f_prev, x_prev2, f_prev2)
|
||||
sc = abs(slope) * abs(far - x)
|
||||
if scale == "derived3_m":
|
||||
# REFUTED as an improvement; kept so the refutation stays
|
||||
# REPRODUCIBLE, which is the whole point of keeping it. The long
|
||||
# note is at the end of the derived3_cap branch below.
|
||||
sc /= _local_order(x, fx, x_prev, f_prev, x_prev2, f_prev2)
|
||||
elif scale == "derived3_cap":
|
||||
# Valeri, 2026-09-21: "if the similarity formed the step, the step would be
|
||||
# large far from the target and small near it". It does not, and the reason
|
||||
@@ -617,7 +662,12 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived",
|
||||
# order) returns. A min over what is in hand - no constant, no threshold.
|
||||
slope = _slope3(x, fx, x_prev, f_prev, x_prev2, f_prev2)
|
||||
sc = min(abs(slope) * abs(far - x), max(abs(FA), abs(FB)))
|
||||
if scale == "derived3_m":
|
||||
# NOTE on scale="derived3_m" (the live code is in the derived3 branch
|
||||
# above). On 2026-09-21 the derived3_cap branch was inserted directly
|
||||
# in front of this note and swallowed the division with it, so
|
||||
# derived3_m silently became derived3 - 2806 against 2806 - and the
|
||||
# refutation stopped being reproducible. test_m_loses_on_the_full
|
||||
# _benchmark caught it, which is what that pin is for.
|
||||
# REFUTED as an improvement - kept for reproducibility.
|
||||
# The DERIVATION holds: dropping the linearity
|
||||
# assumption from the contraction law does produce the
|
||||
@@ -646,10 +696,14 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived",
|
||||
# rho it is read from the CURVATURE, which stays
|
||||
# meaningful as |f| goes to zero, and it returns to 1
|
||||
# at a simple root, leaving the endgame untouched.
|
||||
sc /= _local_order(x, fx, x_prev, f_prev,
|
||||
x_prev2, f_prev2)
|
||||
elif scale == "start":
|
||||
sc = start_scale
|
||||
elif scale == "far":
|
||||
# the value at the end the step AIMS AT, already computed. With
|
||||
# S = 1/(1+z) this is false position exactly (Proposition 4), which
|
||||
# is why it is the honest control for the order exponent: the pair
|
||||
# (far, none) against (far, order) differs in one thing only.
|
||||
sc = abs(FB) if far == B else abs(FA)
|
||||
else:
|
||||
sc = max(abs(FA), abs(FB))
|
||||
if scale.endswith("_rho"):
|
||||
@@ -696,6 +750,9 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived",
|
||||
if sc == 0.0 or not math.isfinite(sc):
|
||||
x_new = 0.5 * (A + B)
|
||||
else:
|
||||
m_loc = (_local_order(x, fx, x_prev, f_prev, x_prev2, f_prev2)
|
||||
if exponent == "order" else None)
|
||||
z_now = _read_z(abs(fx), sc, exponent, m_loc)
|
||||
step = None
|
||||
if prestep == "slope":
|
||||
# PRE-STEP GATE ON SHAPE (PREREG 2026-09-21). The step trusts the
|
||||
@@ -720,7 +777,7 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived",
|
||||
# less than bisection would remove, spend the same single
|
||||
# evaluation on the midpoint instead. Two lengths already in hand
|
||||
# are compared; there is no threshold and no new constant.
|
||||
cand = (1.0 - S(abs(fx) / sc)) * (far - x)
|
||||
cand = (1.0 - S(z_now)) * (far - x)
|
||||
half = 0.5 * (A + B) - x
|
||||
if abs(cand) < abs(half):
|
||||
step = half
|
||||
@@ -734,7 +791,7 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived",
|
||||
c_near = A if abs(FA) <= abs(FB) else B
|
||||
step = _log_space_step(S, x, fx, far, slope, c_near, xtol)
|
||||
if step is None:
|
||||
step = (1.0 - S(abs(fx) / sc)) * (far - x)
|
||||
step = (1.0 - S(z_now)) * (far - x)
|
||||
if sg.reject_step(step):
|
||||
x_new = 0.5 * (A + B)
|
||||
step = x_new - x
|
||||
|
||||
Reference in New Issue
Block a user