Flat regime (PREREG_flat_regime): the unkept-promise flag - after a model step that did not cross the root, r = f_new/f_old >= 1/4, the tangent-versus-halving break-even at m = 2 - RECOGNISES the regime (stage 1: 53.6% of model steps flagged on the flat families against 21.6% on APS and 17.0% on fun1; recall ten times the m>=2 estimator's 5.8%) and cuts the wide-bracket set by 350-490 wherever the budget does not already bind: safe 3390 -> 3037, step 3524 -> 3037, unguarded 4104 -> 3198.
NOT accepted into the proposed rule by the stop rule: under the projection the flat families are already budget-bound (CHA 3220 -> 3198 only) while the false flags on APS cost 2806 -> 3029 (Z2 fails); with G2 both sets fail. The per-problem edge over Chandrupatla on APS turns into 26/72/55. Guarantee intact in every cell. Next candidate, not pre-registered: require the promise to fail twice in a row. Regression on the branch: 918 pass (twice); the one red test is the paper-number check awaiting the paper update. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
+19
-1
@@ -665,7 +665,7 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived",
|
||||
"{'derived3', 'derived3_cap', 'bracket', 'far'}")
|
||||
if space not in SPACES:
|
||||
raise ValueError(f"unknown space {space!r}")
|
||||
if prestep not in ("none", "progress", "slope", "band", "defect", "simpair"):
|
||||
if prestep not in ("none", "progress", "slope", "band", "defect", "simpair", "flat"):
|
||||
raise ValueError(f"unknown prestep {prestep!r}")
|
||||
if prestep in ("band", "defect", "simpair") and scale not in (
|
||||
"derived3", "derived3_cap", "derived3_m", "bracket", "far"):
|
||||
@@ -718,6 +718,7 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived",
|
||||
dir_changed = 0
|
||||
slope = 0.0
|
||||
slope_prev = None
|
||||
last_model = False # was the step just evaluated the model's own? (flat gate)
|
||||
if stats is not None:
|
||||
stats['forced'] = 0
|
||||
stats['pre_refused'] = 0
|
||||
@@ -725,6 +726,7 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived",
|
||||
stats['dir_changed'] = 0
|
||||
|
||||
while abs(B - A) > xtol:
|
||||
model_target = None
|
||||
if sg.bisect_before_step(abs(B - A)):
|
||||
x_new = 0.5 * (A + B)
|
||||
forced += 1
|
||||
@@ -886,6 +888,18 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived",
|
||||
x_prev2, f_prev2):
|
||||
step = 0.5 * (A + B) - x
|
||||
pre_refused += 1
|
||||
if (step is None and prestep == "flat" and last_model
|
||||
and f_prev != 0.0 and fx / f_prev >= 0.25):
|
||||
# PREREG_flat_regime 2026-09-21. The last step was the model's
|
||||
# own, it did not cross the root (r > 0), and it left r = f/f_prev
|
||||
# >= 1/4 of |f|. Under a tangent step on an order-m approach
|
||||
# r = (1 - 1/m)^m, and the step loses to a halving from m = 2 on,
|
||||
# where r = (1 - 1/2)^2 = 1/4: bisection's 1/2, carried through
|
||||
# the same formula, not a chosen number. So the model is losing
|
||||
# here, and this evaluation is spent halving; the next step is
|
||||
# the model's again and is judged by its own result.
|
||||
step = 0.5 * (A + B) - x
|
||||
pre_refused += 1
|
||||
if step is None and prestep == "slope":
|
||||
# PRE-STEP GATE ON SHAPE (PREREG 2026-09-21). The step trusts the
|
||||
# local slope, so the question of trust is whether that slope has
|
||||
@@ -941,6 +955,7 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived",
|
||||
reach = abs(far - x)
|
||||
step = (longer if abs(longer) <= reach
|
||||
else math.copysign(reach, step))
|
||||
model_target = x + step # the model's own proposal
|
||||
if stats is not None and "trace" in stats:
|
||||
# DIAGNOSTIC HOOK, behaviour-neutral: records the state each
|
||||
# step was taken from, so another model can be evaluated on the
|
||||
@@ -978,6 +993,9 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived",
|
||||
stats['forced'] = forced; stats['pre_refused'] = pre_refused; stats['triple_changed'] = triple_changed; stats['dir_changed'] = dir_changed
|
||||
return x_new, g.n, abs(B - A) <= xtol
|
||||
|
||||
# the flat gate judges only the model's own steps: a midpoint from a gate or a
|
||||
# step moved by the safeguard says nothing about the model
|
||||
last_model = model_target is not None and x_new == model_target
|
||||
w_before = abs(B - A)
|
||||
fnew = g(x_new)
|
||||
sg.j += 1 # one step of the bisection budget is spent
|
||||
|
||||
Reference in New Issue
Block a user