Flat regime: exit by midpoint similarity (flatstickexit), one judgment at entry and exit (flatjudge), entry by analogy (flatanalog).
PREREG_flat_exit: NOT accepted - APS 2806 -> 3125, CHA 3220 -> 2503 (the exit is earned: APS 6897 without it). PREREG_flat_judge: NOT accepted (smoke) - APS 3009, CHA 2486: at the model's point f is small by construction, the judgment cannot tell flat from simple there. PREREG_flat_analogy: ACCEPTED with G2. Entry = unkept promise AND the (xi, phi) configuration nearer to its own past than to the line AND the pair's similarity exponent m >= 2. Projection + G2: APS 2782 -> 2780 (below Chandrupatla 2787, per problem 95/20/38 p=8e-7), CHA 3169 -> 2625, guarantee holds. Without G2: APS 2806 -> 2807 (fails by one call), CHA 2635. Simple roots are spared exactly (cost unchanged); flat families 1823 -> 1238, entry comes late. Goal (below Chandrupatla on both) NOT met: CHA 2625 vs 2441, per problem 9/6/25. Server regression x2: 1052 passed, 1 failed = the expected paper-number check. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,34 @@
|
|||||||
|
tent, 3-point, pairs (no gate -> flat gate) APS CHA both flat fun3-6
|
||||||
|
none 2806->2807 4104->2635 6910->5442 2707->1238 solved 193 over 0
|
||||||
|
none +G2 2782->2780 3863->2625 6645->5405 2474->1234 solved 193 over 0
|
||||||
|
step 3036->3035 3524->2650 6560->5685 2111->1237 solved 193 over 0
|
||||||
|
step +G2 3089->3089 3529->2661 6618->5750 2106->1238 solved 193 over 0
|
||||||
|
bracket 7260->7260 3604->3604 10864->10864 1730->1730 solved 193 over 0
|
||||||
|
bracket +G2 6837->6837 3650->3650 10487->10487 1717->1717 solved 193 over 0
|
||||||
|
both 7239->7239 3515->3515 10754->10754 1529->1529 solved 193 over 0
|
||||||
|
both +G2 7130->7130 3463->3463 10593->10593 1504->1504 solved 193 over 0
|
||||||
|
project 2806->2807 3220->2635 6026->5442 1823->1238 solved 193 over 0
|
||||||
|
project +G2 2782->2780 3169->2625 5951->5405 1780->1234 solved 193 over 0
|
||||||
|
safe 3036->3035 3390->2650 6426->5685 1977->1237 solved 193 over 0
|
||||||
|
safe +G2 3089->3089 3392->2661 6481->5750 1969->1238 solved 193 over 0
|
||||||
|
credit 3568->3568 3020->2960 6588->6528 1044->1014 solved 193 over 0
|
||||||
|
credit +G2 3799->3799 3064->3034 6863->6833 1044->1014 solved 193 over 0
|
||||||
|
|
||||||
|
VERDICTS
|
||||||
|
proposed rule APS 2806->2807 (Z2 ✗) CHA 3220->2635 (Z1 ✓) Z3 ✓ (0 viol, 0 cells <193) Z4 ✓ both 5442 vs Chandrupatla APS 87/24/42 p=9.2e-05 not accepted
|
||||||
|
proposed rule + G2 APS 2782->2780 (Z2 ✓) CHA 3169->2625 (Z1 ✓) Z3 ✓ (0 viol, 0 cells <193) Z4 ✓ both 5405 vs Chandrupatla APS 95/20/38 p=8.2e-07 ACCEPTED
|
||||||
|
|
||||||
|
nine functions, projection, no gate -> flat gate, both sets:
|
||||||
|
cbrt 18003 -> 17853
|
||||||
|
cosine 19741 -> 18885
|
||||||
|
exp_abs 6652 -> 5969
|
||||||
|
exp_sq 19786 -> 18877
|
||||||
|
rat_sq 19793 -> 18873
|
||||||
|
ratio 6026 -> 5442
|
||||||
|
ratio_soft 9352 -> 9002
|
||||||
|
rational 6823 -> 6177
|
||||||
|
sqrt 13388 -> 13212
|
||||||
|
flatanalog.ratio.derived3.project APS vs Chandrupatla 87/24/42 p=9.2e-05
|
||||||
|
flatanalog.ratio.derived3.project CHA vs Chandrupatla 9/6/25 p=0.009
|
||||||
|
pure+extP+flatanalog.ratio.derived3.project APS vs Chandrupatla 95/20/38 p=8.2e-07
|
||||||
|
pure+extP+flatanalog.ratio.derived3.project CHA vs Chandrupatla 9/6/25 p=0.009
|
||||||
@@ -0,0 +1,62 @@
|
|||||||
|
===== flatstickexit
|
||||||
|
tent, 3-point, pairs (no gate -> flat gate) APS CHA both flat fun3-6
|
||||||
|
none 2806->3125 4104->2503 6910->5628 2707->1057 solved 193 over 0
|
||||||
|
none +G2 2782->3175 3863->2508 6645->5683 2474->1057 solved 193 over 0
|
||||||
|
step 3036->3161 3524->2492 6560->5653 2111->1057 solved 193 over 0
|
||||||
|
step +G2 3089->3193 3529->2499 6618->5692 2106->1057 solved 193 over 0
|
||||||
|
bracket 7260->7226 3604->3604 10864->10830 1730->1730 solved 193 over 0
|
||||||
|
bracket +G2 6837->6874 3650->3650 10487->10524 1717->1717 solved 193 over 0
|
||||||
|
both 7239->7179 3515->3515 10754->10694 1529->1529 solved 193 over 0
|
||||||
|
both +G2 7130->7150 3463->3463 10593->10613 1504->1504 solved 193 over 0
|
||||||
|
project 2806->3125 3220->2503 6026->5628 1823->1057 solved 193 over 0
|
||||||
|
project +G2 2782->3175 3169->2508 5951->5683 1780->1057 solved 193 over 0
|
||||||
|
safe 3036->3161 3390->2492 6426->5653 1977->1057 solved 193 over 0
|
||||||
|
safe +G2 3089->3193 3392->2499 6481->5692 1969->1057 solved 193 over 0
|
||||||
|
credit 3568->4232 3020->2810 6588->7042 1044->951 solved 193 over 0
|
||||||
|
credit +G2 3799->4575 3064->2881 6863->7456 1044->951 solved 193 over 0
|
||||||
|
|
||||||
|
VERDICTS
|
||||||
|
proposed rule APS 2806->3125 (Z2 ✗) CHA 3220->2503 (Z1 ✓) Z3 ✓ (0 viol, 0 cells <193) Z4 ✓ both 5628 vs Chandrupatla APS 19/19/115 p=6.1e-18 not accepted
|
||||||
|
proposed rule + G2 APS 2782->3175 (Z2 ✗) CHA 3169->2508 (Z1 ✓) Z3 ✓ (0 viol, 0 cells <193) Z4 ✓ both 5683 vs Chandrupatla APS 19/20/114 p=1.1e-17 not accepted
|
||||||
|
|
||||||
|
nine functions, projection, no gate -> flat gate, both sets:
|
||||||
|
cbrt 18003 -> 17989
|
||||||
|
cosine 19741 -> 15076
|
||||||
|
exp_abs 6652 -> 6349
|
||||||
|
exp_sq 19786 -> 13379
|
||||||
|
rat_sq 19793 -> 13636
|
||||||
|
ratio 6026 -> 5628
|
||||||
|
ratio_soft 9352 -> 8903
|
||||||
|
rational 6823 -> 7148
|
||||||
|
sqrt 13388 -> 13233
|
||||||
|
===== flatstickmid
|
||||||
|
tent, 3-point, pairs (no gate -> flat gate) APS CHA both flat fun3-6
|
||||||
|
none 2806->6897 4104->3019 6910->9916 2707->1057 solved 193 over 0
|
||||||
|
none +G2 2782->6918 3863->3055 6645->9973 2474->1057 solved 193 over 0
|
||||||
|
step 3036->6663 3524->3019 6560->9682 2111->1057 solved 193 over 0
|
||||||
|
step +G2 3089->6709 3529->3055 6618->9764 2106->1057 solved 193 over 0
|
||||||
|
bracket 7260->7214 3604->3604 10864->10818 1730->1730 solved 193 over 0
|
||||||
|
bracket +G2 6837->6886 3650->3650 10487->10536 1717->1717 solved 193 over 0
|
||||||
|
both 7239->7241 3515->3515 10754->10756 1529->1529 solved 193 over 0
|
||||||
|
both +G2 7130->7196 3463->3463 10593->10659 1504->1504 solved 193 over 0
|
||||||
|
project 2806->6897 3220->3019 6026->9916 1823->1057 solved 193 over 0
|
||||||
|
project +G2 2782->6918 3169->3055 5951->9973 1780->1057 solved 193 over 0
|
||||||
|
safe 3036->6663 3390->3019 6426->9682 1977->1057 solved 193 over 0
|
||||||
|
safe +G2 3089->6709 3392->3055 6481->9764 1969->1057 solved 193 over 0
|
||||||
|
credit 3568->6837 3020->3002 6588->9839 1044->951 solved 193 over 0
|
||||||
|
credit +G2 3799->6953 3064->3002 6863->9955 1044->951 solved 193 over 0
|
||||||
|
|
||||||
|
VERDICTS
|
||||||
|
proposed rule APS 2806->6897 (Z2 ✗) CHA 3220->3019 (Z1 ✓) Z3 ✓ (0 viol, 0 cells <193) Z4 ✓ both 9916 vs Chandrupatla APS 9/4/140 p=2.3e-31 not accepted
|
||||||
|
proposed rule + G2 APS 2782->6918 (Z2 ✗) CHA 3169->3055 (Z1 ✓) Z3 ✓ (0 viol, 0 cells <193) Z4 ✓ both 9973 vs Chandrupatla APS 9/4/140 p=2.3e-31 not accepted
|
||||||
|
|
||||||
|
nine functions, projection, no gate -> flat gate, both sets:
|
||||||
|
cbrt 18003 -> 12694
|
||||||
|
cosine 19741 -> 10825
|
||||||
|
exp_abs 6652 -> 10621
|
||||||
|
exp_sq 19786 -> 10810
|
||||||
|
rat_sq 19793 -> 10793
|
||||||
|
ratio 6026 -> 9916
|
||||||
|
ratio_soft 9352 -> 10447
|
||||||
|
rational 6823 -> 10634
|
||||||
|
sqrt 13388 -> 11332
|
||||||
+102
-2
@@ -593,6 +593,41 @@ def _order_split(A, FA, B, FB, m):
|
|||||||
return A + t * (B - A)
|
return A + t * (B - A)
|
||||||
|
|
||||||
|
|
||||||
|
def _config3(x, fx, xp, fp, xp2, fp2):
|
||||||
|
"""The dimensionless configuration of the last three points and its two scales
|
||||||
|
(PREREG_flat_analogy 2026-09-21): xi = where x sits between the earlier two, phi =
|
||||||
|
where f(x) sits between their values, and |x - xp|, |fx - fp|. A linear f has
|
||||||
|
phi = xi exactly; a pure power repeats (xi, phi) under zoom. None when undefined."""
|
||||||
|
if xp2 is None or xp2 == xp or fp2 == fp:
|
||||||
|
return None
|
||||||
|
xi = (x - xp) / (xp2 - xp)
|
||||||
|
phi = (fx - fp) / (fp2 - fp)
|
||||||
|
if not (math.isfinite(xi) and math.isfinite(phi)):
|
||||||
|
return None
|
||||||
|
return xi, phi, abs(x - xp), abs(fx - fp)
|
||||||
|
|
||||||
|
|
||||||
|
def _analogous_and_steep(cur, past):
|
||||||
|
"""Is the configuration nearer to its own past than to the line phi = xi, and does the
|
||||||
|
analogous pair scale like a power of order m >= 2? Two ordinal judgments and the
|
||||||
|
flag's own break-even (1/4 = (1 - 1/2)^2 <-> m = 2); no new constant.
|
||||||
|
|
||||||
|
Nearness: Euclidean in the (xi, phi) plane, the line by its perpendicular. Order: the
|
||||||
|
pair shrank x by L and f by L^m, m = ln(f ratio) / ln(x ratio)."""
|
||||||
|
if cur is None or not past:
|
||||||
|
return False
|
||||||
|
xi, phi = cur[0], cur[1]
|
||||||
|
best = min(past, key=lambda q: math.hypot(xi - q[0], phi - q[1]))
|
||||||
|
if not math.hypot(xi - best[0], phi - best[1]) < abs(phi - xi) / math.sqrt(2.0):
|
||||||
|
return False
|
||||||
|
if best[2] <= 0.0 or best[3] <= 0.0 or cur[2] <= 0.0 or cur[3] <= 0.0:
|
||||||
|
return False
|
||||||
|
lx, lf = cur[2] / best[2], cur[3] / best[3]
|
||||||
|
if not (math.isfinite(lx) and math.isfinite(lf)) or lx == 1.0 or lf <= 0.0:
|
||||||
|
return False
|
||||||
|
return math.log(lf) / math.log(lx) >= 2.0
|
||||||
|
|
||||||
|
|
||||||
def _local_order(x2, f2, x1, f1, x0, f0):
|
def _local_order(x2, f2, x1, f1, x0, f0):
|
||||||
"""The local order m of f, from three evaluations and nothing else.
|
"""The local order m of f, from three evaluations and nothing else.
|
||||||
|
|
||||||
@@ -710,7 +745,8 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived",
|
|||||||
if space not in SPACES:
|
if space not in SPACES:
|
||||||
raise ValueError(f"unknown space {space!r}")
|
raise ValueError(f"unknown space {space!r}")
|
||||||
if prestep not in ("none", "progress", "slope", "band", "defect", "simpair", "flat",
|
if prestep not in ("none", "progress", "slope", "band", "defect", "simpair", "flat",
|
||||||
"flat2", "flatcreep", "flatstick", "flatstickmid"):
|
"flat2", "flatcreep", "flatstick", "flatstickmid", "flatstickexit",
|
||||||
|
"flatjudge", "flatanalog"):
|
||||||
raise ValueError(f"unknown prestep {prestep!r}")
|
raise ValueError(f"unknown prestep {prestep!r}")
|
||||||
if prestep in ("band", "defect", "simpair") and scale not in (
|
if prestep in ("band", "defect", "simpair") and scale not in (
|
||||||
"derived3", "derived3_cap", "derived3_m", "bracket", "far"):
|
"derived3", "derived3_cap", "derived3_m", "bracket", "far"):
|
||||||
@@ -766,6 +802,8 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived",
|
|||||||
last_model = False # was the step just evaluated the model's own? (flat gate)
|
last_model = False # was the step just evaluated the model's own? (flat gate)
|
||||||
unkept_run = 0 # consecutive model steps whose promise failed (flat2)
|
unkept_run = 0 # consecutive model steps whose promise failed (flat2)
|
||||||
sticky_m = None # order read at entry to the sticky flat regime (flatstick*)
|
sticky_m = None # order read at entry to the sticky flat regime (flatstick*)
|
||||||
|
judged = 0 # flatjudge: +1 the last point looked flat, -1 linear, 0 tie
|
||||||
|
configs = [] # flatanalog: the run's memory of (xi, phi, |dx|, |df|)
|
||||||
if stats is not None:
|
if stats is not None:
|
||||||
stats['forced'] = 0
|
stats['forced'] = 0
|
||||||
stats['pre_refused'] = 0
|
stats['pre_refused'] = 0
|
||||||
@@ -959,22 +997,58 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived",
|
|||||||
# late, before the crossing (flat2's failure).
|
# late, before the crossing (flat2's failure).
|
||||||
step = 0.5 * (A + B) - x
|
step = 0.5 * (A + B) - x
|
||||||
pre_refused += 1
|
pre_refused += 1
|
||||||
if step is None and prestep in ("flatstick", "flatstickmid"):
|
if step is None and prestep in ("flatstick", "flatstickmid",
|
||||||
|
"flatstickexit"):
|
||||||
# PREREG_flat_stick 2026-09-21. The same entry as "flat", but the
|
# PREREG_flat_stick 2026-09-21. The same entry as "flat", but the
|
||||||
# regime is a property of the root, not of one step: once the
|
# regime is a property of the root, not of one step: once the
|
||||||
# promise has failed, every later step splits the bracket. The
|
# promise has failed, every later step splits the bracket. The
|
||||||
# single flag replaced one step and the model undershot again.
|
# single flag replaced one step and the model undershot again.
|
||||||
# flatstick splits where |f| ~ |x-r|^m puts the root, m read from
|
# flatstick splits where |f| ~ |x-r|^m puts the root, m read from
|
||||||
# the failed promise itself; flatstickmid halves (the ablation).
|
# the failed promise itself; flatstickmid halves (the ablation).
|
||||||
|
# flatstickexit halves too, and may LEAVE the regime - see the
|
||||||
|
# similarity judgment at the midpoint after the evaluation.
|
||||||
if (sticky_m is None and last_model and f_prev != 0.0
|
if (sticky_m is None and last_model and f_prev != 0.0
|
||||||
and fx / f_prev >= 0.25):
|
and fx / f_prev >= 0.25):
|
||||||
sticky_m = _order_from_promise(fx / f_prev)
|
sticky_m = _order_from_promise(fx / f_prev)
|
||||||
|
if stats is not None:
|
||||||
|
stats['stick_entries'] = stats.get('stick_entries', 0) + 1
|
||||||
if sticky_m is not None:
|
if sticky_m is not None:
|
||||||
if prestep == "flatstick":
|
if prestep == "flatstick":
|
||||||
step = _order_split(A, FA, B, FB, sticky_m) - x
|
step = _order_split(A, FA, B, FB, sticky_m) - x
|
||||||
else:
|
else:
|
||||||
step = 0.5 * (A + B) - x
|
step = 0.5 * (A + B) - x
|
||||||
pre_refused += 1
|
pre_refused += 1
|
||||||
|
if step is None and prestep == "flatanalog":
|
||||||
|
# PREREG_flat_analogy 2026-09-21. A pure power is similar to itself
|
||||||
|
# under zoom: its configuration RECURS, while a simple root's tends
|
||||||
|
# to the line. Enter on the unkept promise only when the current
|
||||||
|
# configuration is nearer to its own past than to the line AND the
|
||||||
|
# analogous pair scales as a power of order >= 2. Every state the
|
||||||
|
# gate sees joins the memory after it has been judged.
|
||||||
|
cur = _config3(x, fx, x_prev, f_prev, x_prev2, f_prev2)
|
||||||
|
if (sticky_m is None and last_model and f_prev != 0.0
|
||||||
|
and fx / f_prev >= 0.25 and _analogous_and_steep(cur, configs)):
|
||||||
|
sticky_m = math.inf
|
||||||
|
if stats is not None:
|
||||||
|
stats['stick_entries'] = stats.get('stick_entries', 0) + 1
|
||||||
|
if cur is not None:
|
||||||
|
configs.append(cur)
|
||||||
|
if sticky_m is not None:
|
||||||
|
step = 0.5 * (A + B) - x
|
||||||
|
pre_refused += 1
|
||||||
|
if step is None and prestep == "flatjudge":
|
||||||
|
# PREREG_flat_judge 2026-09-21. Enter only when the unkept promise
|
||||||
|
# AND the point itself looks flat (judged at its evaluation, below);
|
||||||
|
# a simple root that trips the flag is usually judged linear there
|
||||||
|
# and never pays for a midpoint. In the regime every step halves.
|
||||||
|
if (sticky_m is None and last_model and f_prev != 0.0
|
||||||
|
and fx / f_prev >= 0.25 and judged > 0):
|
||||||
|
sticky_m = math.inf
|
||||||
|
if stats is not None:
|
||||||
|
stats['stick_entries'] = stats.get('stick_entries', 0) + 1
|
||||||
|
if sticky_m is not None:
|
||||||
|
step = 0.5 * (A + B) - x
|
||||||
|
pre_refused += 1
|
||||||
if step is None and prestep == "flat2" and unkept_run >= 2:
|
if step is None and prestep == "flat2" and unkept_run >= 2:
|
||||||
# PREREG_flat_twice 2026-09-21. The same unkept promise as
|
# PREREG_flat_twice 2026-09-21. The same unkept promise as
|
||||||
# "flat" (model step, no crossing, r >= 1/4), but only after it has
|
# "flat" (model step, no crossing, r >= 1/4), but only after it has
|
||||||
@@ -1080,7 +1154,33 @@ def pure_root(f, a, b, xtol, maxfev, similarity="ratio", scale="derived",
|
|||||||
# step moved by the safeguard says nothing about the model
|
# step moved by the safeguard says nothing about the model
|
||||||
last_model = model_target is not None and x_new == model_target
|
last_model = model_target is not None and x_new == model_target
|
||||||
w_before = abs(B - A)
|
w_before = abs(B - A)
|
||||||
|
mid_now, lin_mid = 0.5 * (A + B), 0.5 * (FA + FB) # before the bracket moves
|
||||||
fnew = g(x_new)
|
fnew = g(x_new)
|
||||||
|
if (prestep in ("flatstickexit", "flatanalog") and sticky_m is not None
|
||||||
|
and x_new == mid_now
|
||||||
|
and abs(fnew - lin_mid) < abs(fnew)):
|
||||||
|
# PREREG_flat_exit 2026-09-21. A midpoint evaluated in the regime is judged
|
||||||
|
# against the two predictions: a simple root (f nearly linear on the
|
||||||
|
# bracket) puts f(M) at (FA+FB)/2, a flat approach puts it at ~0. More
|
||||||
|
# like the linear one - the regime is left and the model steps again.
|
||||||
|
# Ordinal: two distances compared, no threshold; a tie stays.
|
||||||
|
sticky_m = None
|
||||||
|
if stats is not None:
|
||||||
|
stats['stick_exits'] = stats.get('stick_exits', 0) + 1
|
||||||
|
if prestep == "flatjudge":
|
||||||
|
# PREREG_flat_judge 2026-09-21. One similarity judgment, made at every new
|
||||||
|
# point before the bracket moves: is f(x) more like the line through the
|
||||||
|
# bracket ends (a simple root) or like 0 (a flat approach)? Weighted as
|
||||||
|
# FA(1-t) + FB t, t in (0,1), so it cannot overflow. At a midpoint it is
|
||||||
|
# exactly the exit judgment of flatstickexit. Ordinal, no threshold.
|
||||||
|
t_at = (x_new - A) / (B - A)
|
||||||
|
lin_at = FA * (1.0 - t_at) + FB * t_at
|
||||||
|
d_lin, d_flat = abs(fnew - lin_at), abs(fnew)
|
||||||
|
judged = 1 if d_flat < d_lin else (-1 if d_lin < d_flat else 0)
|
||||||
|
if sticky_m is not None and x_new == mid_now and judged < 0:
|
||||||
|
sticky_m = None
|
||||||
|
if stats is not None:
|
||||||
|
stats['stick_exits'] = stats.get('stick_exits', 0) + 1
|
||||||
# the run of unkept promises (flat2): x, fx are still the point the step left
|
# the run of unkept promises (flat2): x, fx are still the point the step left
|
||||||
if last_model and fx != 0.0 and fnew / fx >= 0.25:
|
if last_model and fx != 0.0 and fnew / fx >= 0.25:
|
||||||
unkept_run += 1
|
unkept_run += 1
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
+12
-3
@@ -419,10 +419,16 @@ def main():
|
|||||||
flat2mode = "--flat2" in sys.argv # the flat gate, promise failed twice
|
flat2mode = "--flat2" in sys.argv # the flat gate, promise failed twice
|
||||||
creepmode = "--flatcreep" in sys.argv # the flat gate AND a creep
|
creepmode = "--flatcreep" in sys.argv # the flat gate AND a creep
|
||||||
stickmode = "--flatstick" in sys.argv # the sticky flat regime + its midpoint ablation
|
stickmode = "--flatstick" in sys.argv # the sticky flat regime + its midpoint ablation
|
||||||
|
exitmode = "--flatexit" in sys.argv # the sticky regime with an exit by similarity
|
||||||
|
judgemode = "--flatjudge" in sys.argv # one similarity judgment at entry and exit
|
||||||
|
analogmode = "--flatanalog" in sys.argv # entry by analogy with the run's own past
|
||||||
combomode = "--combo" in sys.argv # modes A and B together
|
combomode = "--combo" in sys.argv # modes A and B together
|
||||||
pointsmode = "--points" in sys.argv # mode A: triple by shape
|
pointsmode = "--points" in sys.argv # mode A: triple by shape
|
||||||
dirmode = "--direction" in sys.argv # mode B: far end by dissimilarity
|
dirmode = "--direction" in sys.argv # mode B: far end by dissimilarity
|
||||||
specs = (build_grid_flat(smoke, ("flatstick", "flatstickmid")) if stickmode else
|
specs = (build_grid_flat(smoke, ("flatanalog", "flatstickexit")) if analogmode else
|
||||||
|
build_grid_flat(smoke, ("flatjudge", "flatstickexit")) if judgemode else
|
||||||
|
build_grid_flat(smoke, ("flatstickexit", "flatstickmid")) if exitmode else
|
||||||
|
build_grid_flat(smoke, ("flatstick", "flatstickmid")) if stickmode else
|
||||||
build_grid_flat(smoke, "flatcreep") if creepmode else
|
build_grid_flat(smoke, "flatcreep") if creepmode else
|
||||||
build_grid_flat(smoke, "flat2") if flat2mode else
|
build_grid_flat(smoke, "flat2") if flat2mode else
|
||||||
build_grid_flat(smoke) if flatmode else
|
build_grid_flat(smoke) if flatmode else
|
||||||
@@ -452,8 +458,11 @@ def main():
|
|||||||
|
|
||||||
# the published sweep_full.json is what verify_article.py checks the paper
|
# the published sweep_full.json is what verify_article.py checks the paper
|
||||||
# against, so the log grid never writes into it
|
# against, so the log grid never writes into it
|
||||||
if stickmode or creepmode or flat2mode or flatmode or ext2mode or extmode or decmode or ordermode or capmode or combomode or pointsmode or dirmode:
|
if analogmode or judgemode or exitmode or stickmode or creepmode or flat2mode or flatmode or ext2mode or extmode or decmode or ordermode or capmode or combomode or pointsmode or dirmode:
|
||||||
base = ("sweep_flatstick" if stickmode else
|
base = ("sweep_flatanalog" if analogmode else
|
||||||
|
"sweep_flatjudge" if judgemode else
|
||||||
|
"sweep_flatexit" if exitmode else
|
||||||
|
"sweep_flatstick" if stickmode else
|
||||||
"sweep_flatcreep" if creepmode else
|
"sweep_flatcreep" if creepmode else
|
||||||
"sweep_flat2" if flat2mode else
|
"sweep_flat2" if flat2mode else
|
||||||
"sweep_flat" if flatmode else
|
"sweep_flat" if flatmode else
|
||||||
|
|||||||
@@ -158,3 +158,112 @@ def test_an_infinite_end_gives_the_midpoint_not_nan():
|
|||||||
safeguard before the loop checked finiteness."""
|
safeguard before the loop checked finiteness."""
|
||||||
assert _order_split(0.0, -math.inf, 2.0, 1.0, 3.0) == 1.0
|
assert _order_split(0.0, -math.inf, 2.0, 1.0, 3.0) == 1.0
|
||||||
assert _order_split(0.0, -math.inf, 2.0, math.inf, 3.0) == 1.0
|
assert _order_split(0.0, -math.inf, 2.0, math.inf, 3.0) == 1.0
|
||||||
|
|
||||||
|
|
||||||
|
# ---- PREREG_flat_exit_2026-09-21: leaving the sticky regime by similarity at the midpoint ----
|
||||||
|
@pytest.mark.parametrize("f,a,b", PROBS)
|
||||||
|
@pytest.mark.parametrize("guard", ("project", "credit"))
|
||||||
|
@pytest.mark.parametrize("ext", ("none", "pattern"))
|
||||||
|
def test_the_guarantee_holds_with_the_exit(f, a, b, guard, ext):
|
||||||
|
x, n, ok = pure_root(f, a, b, XTOL, MAXFEV, similarity="ratio", scale="derived3",
|
||||||
|
guard=guard, prestep="flatstickexit", extrapolate=ext)
|
||||||
|
assert ok and min(a, b) <= x <= max(a, b)
|
||||||
|
half = math.ceil(math.log2(abs(b - a) / XTOL))
|
||||||
|
assert n <= (2 * half + 3 if guard == "project" else half + 4), n
|
||||||
|
|
||||||
|
|
||||||
|
def _exit_stats(f, a, b):
|
||||||
|
st = {}
|
||||||
|
pure_root(f, a, b, XTOL, MAXFEV, similarity="ratio", scale="derived3", guard="project",
|
||||||
|
prestep="flatstickexit", stats=st)
|
||||||
|
return st.get("stick_entries", 0), st.get("stick_exits", 0)
|
||||||
|
|
||||||
|
|
||||||
|
def test_the_exit_leaves_a_false_entry_and_keeps_a_true_one():
|
||||||
|
"""Measured before pinning: a simple root that trips the flag (the cubic, exp) leaves
|
||||||
|
the regime at a midpoint; pure powers, scale-invariant, never do."""
|
||||||
|
assert _exit_stats(lambda t: 3.0 * t - 1.0, -2.0, 5.0) == (0, 0)
|
||||||
|
assert _exit_stats(lambda t: t ** 3 - 2.0 * t - 5.0, 1.0, 4.0) == (1, 1)
|
||||||
|
assert _exit_stats(lambda t: math.exp(t) - 2.0, 0.0, 3.0) == (1, 1)
|
||||||
|
for f, a, b in ((lambda t: t ** 9, -1.0, 2.0), (lambda t: t ** 19, -10.0, 100.0),
|
||||||
|
(lambda t: 6.0 * (t - 2.0) ** 5, 0.0, 10.0)):
|
||||||
|
ent, ex = _exit_stats(f, a, b)
|
||||||
|
assert ent >= 1 and ex == 0, (ent, ex)
|
||||||
|
|
||||||
|
|
||||||
|
def test_the_exit_does_not_touch_the_other_sticky_modes():
|
||||||
|
for gate in ("flatstick", "flatstickmid"):
|
||||||
|
st = {}
|
||||||
|
pure_root(lambda t: math.exp(t) - 2.0, 0.0, 3.0, XTOL, MAXFEV, similarity="ratio",
|
||||||
|
scale="derived3", guard="project", prestep=gate, stats=st)
|
||||||
|
assert st.get("stick_exits", 0) == 0
|
||||||
|
|
||||||
|
|
||||||
|
# ---- PREREG_flat_judge_2026-09-21: one similarity judgment at entry and exit ----
|
||||||
|
@pytest.mark.parametrize("f,a,b", PROBS)
|
||||||
|
@pytest.mark.parametrize("guard", ("project", "credit"))
|
||||||
|
@pytest.mark.parametrize("ext", ("none", "pattern"))
|
||||||
|
def test_the_guarantee_holds_with_the_judge(f, a, b, guard, ext):
|
||||||
|
x, n, ok = pure_root(f, a, b, XTOL, MAXFEV, similarity="ratio", scale="derived3",
|
||||||
|
guard=guard, prestep="flatjudge", extrapolate=ext)
|
||||||
|
assert ok and min(a, b) <= x <= max(a, b)
|
||||||
|
half = math.ceil(math.log2(abs(b - a) / XTOL))
|
||||||
|
assert n <= (2 * half + 3 if guard == "project" else half + 4), n
|
||||||
|
|
||||||
|
|
||||||
|
def test_the_judge_is_silent_on_a_line_and_holds_a_pure_power():
|
||||||
|
st = {}
|
||||||
|
pure_root(lambda t: 3.0 * t - 1.0, -2.0, 5.0, XTOL, MAXFEV, similarity="ratio",
|
||||||
|
scale="derived3", guard="project", prestep="flatjudge", stats=st)
|
||||||
|
assert st.get("stick_entries", 0) == 0 and st["pre_refused"] == 0
|
||||||
|
st = {}
|
||||||
|
pure_root(lambda t: t ** 19, -10.0, 100.0, XTOL, MAXFEV, similarity="ratio",
|
||||||
|
scale="derived3", guard="project", prestep="flatjudge", stats=st)
|
||||||
|
assert st.get("stick_entries", 0) >= 1 and st.get("stick_exits", 0) == 0, st
|
||||||
|
|
||||||
|
|
||||||
|
# ---- PREREG_flat_analogy_2026-09-21: entry by analogy with the run's own past ----
|
||||||
|
from simroot.pure import _analogous_and_steep, _config3 # noqa: E402
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize("f,a,b", PROBS)
|
||||||
|
@pytest.mark.parametrize("guard", ("project", "credit"))
|
||||||
|
@pytest.mark.parametrize("ext", ("none", "pattern"))
|
||||||
|
def test_the_guarantee_holds_with_the_analogy_entry(f, a, b, guard, ext):
|
||||||
|
x, n, ok = pure_root(f, a, b, XTOL, MAXFEV, similarity="ratio", scale="derived3",
|
||||||
|
guard=guard, prestep="flatanalog", extrapolate=ext)
|
||||||
|
assert ok and min(a, b) <= x <= max(a, b)
|
||||||
|
half = math.ceil(math.log2(abs(b - a) / XTOL))
|
||||||
|
assert n <= (2 * half + 3 if guard == "project" else half + 4), n
|
||||||
|
|
||||||
|
|
||||||
|
def test_the_analogy_entry_spares_simple_roots_and_catches_powers():
|
||||||
|
"""Measured before pinning: the cubic and exp, which trip the single flag, never
|
||||||
|
enter, and cost exactly what the rule costs without the regime."""
|
||||||
|
for f, a, b in ((lambda t: 3.0 * t - 1.0, -2.0, 5.0),
|
||||||
|
(lambda t: t ** 3 - 2.0 * t - 5.0, 1.0, 4.0),
|
||||||
|
(lambda t: math.exp(t) - 2.0, 0.0, 3.0)):
|
||||||
|
st = {}
|
||||||
|
_x, n1, _ = pure_root(f, a, b, XTOL, MAXFEV, similarity="ratio", scale="derived3",
|
||||||
|
guard="project", prestep="flatanalog", stats=st)
|
||||||
|
_x, n0, _ = pure_root(f, a, b, XTOL, MAXFEV, similarity="ratio", scale="derived3",
|
||||||
|
guard="project")
|
||||||
|
assert st.get("stick_entries", 0) == 0 and n1 == n0
|
||||||
|
for f, a, b in ((lambda t: t ** 9, -1.0, 2.0), (lambda t: t ** 19, -10.0, 100.0),
|
||||||
|
(lambda t: 6.0 * (t - 2.0) ** 5, 0.0, 10.0)):
|
||||||
|
st = {}
|
||||||
|
pure_root(f, a, b, XTOL, MAXFEV, similarity="ratio", scale="derived3",
|
||||||
|
guard="project", prestep="flatanalog", stats=st)
|
||||||
|
assert st.get("stick_entries", 0) >= 1
|
||||||
|
|
||||||
|
|
||||||
|
def test_a_line_is_never_analogous_and_an_exact_power_repeats_with_its_order():
|
||||||
|
line = [_config3(x, 3 * x, xp, 3 * xp, xp2, 3 * xp2)
|
||||||
|
for x, xp, xp2 in ((0.1, 0.5, 1.0), (0.05, 0.1, 0.5))]
|
||||||
|
assert line[0][0] == pytest.approx(line[0][1]) # phi = xi on a line
|
||||||
|
assert not _analogous_and_steep(line[1], [line[0]])
|
||||||
|
p = lambda t: t ** 5 # noqa: E731
|
||||||
|
old = _config3(0.4, p(0.4), 0.8, p(0.8), 1.6, p(1.6))
|
||||||
|
new = _config3(0.1, p(0.1), 0.2, p(0.2), 0.4, p(0.4)) # the same shape, zoomed by 4
|
||||||
|
assert new[0] == pytest.approx(old[0]) and new[1] == pytest.approx(old[1])
|
||||||
|
assert _analogous_and_steep(new, [old])
|
||||||
|
|||||||
Reference in New Issue
Block a user