Why the analogy entry is late on the flat families (diagnostics only, method unchanged). At flag moments before entry: unlike-past 118, no-memory 7, m<2 2 - the order is not the bottleneck. The period-4 cycle: the flag rises in the phases whose configuration does NOT recur (the undershoot whose relative step shrinks every cycle, and the crossing); the recurring phases have the flag down and read the true order (fun4 = 6(x-2)^5: m ~ 4.9). The entry demands both at the same state. Remembering the analogy until the next flag: flat entry state 12.9 -> 8.2; problems entered APS 3 -> 8, fun9 0 -> 1.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,99 @@
|
||||
"""Why does the analogy entry come late on the flat families? (Valeri, 2026-09-21)
|
||||
|
||||
The entry is flag AND _analogous_and_steep(cur, memory). The method calls the second
|
||||
only when the flag has risen on a model step (short-circuit `and`), so a spy on it sees
|
||||
exactly the flag moments. At each one it records how many evaluations of f were spent
|
||||
and which condition held back the entry:
|
||||
no-config the last three points give no (xi, phi)
|
||||
no-memory nothing to compare with yet
|
||||
unlike-past the configuration is nearer to the line than to any past one
|
||||
m<2 analogous, but the pair's similarity exponent is below 2 (value kept)
|
||||
ENTER
|
||||
Compared with flatstickexit, which enters at the first flag. Nothing in the method
|
||||
changes; problems are the 20 flat CHA problems (fun3-6), proposed rule (projection).
|
||||
|
||||
python -u diag_analogy_late.py
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import math
|
||||
from collections import Counter as Tally
|
||||
|
||||
import simroot.pure as P
|
||||
from sweep_full import MAXFEV, XTOL, load_problems
|
||||
|
||||
FLAT = ("fun3", "fun4", "fun5", "fun6")
|
||||
_orig = P._analogous_and_steep
|
||||
LOG = []
|
||||
CALLS = [0]
|
||||
|
||||
|
||||
def reason(cur, past):
|
||||
if cur is None:
|
||||
return "no-config", None
|
||||
if not past:
|
||||
return "no-memory", None
|
||||
xi, phi = cur[0], cur[1]
|
||||
best = min(past, key=lambda q: math.hypot(xi - q[0], phi - q[1]))
|
||||
d_past = math.hypot(xi - best[0], phi - best[1])
|
||||
d_line = abs(phi - xi) / math.sqrt(2.0)
|
||||
if not d_past < d_line:
|
||||
return "unlike-past", (d_past, d_line)
|
||||
lx, lf = cur[2] / best[2], cur[3] / best[3]
|
||||
m = math.log(lf) / math.log(lx) if lx not in (0.0, 1.0) and lf > 0.0 else math.nan
|
||||
return ("ENTER" if m >= 2.0 else "m<2"), m
|
||||
|
||||
|
||||
def spy(cur, past):
|
||||
ok = _orig(cur, past)
|
||||
why, val = reason(cur, past)
|
||||
LOG.append((CALLS[0], why, val, len(past), ok))
|
||||
return ok
|
||||
|
||||
|
||||
def counted(f):
|
||||
def g(x):
|
||||
CALLS[0] += 1
|
||||
return f(x)
|
||||
return g
|
||||
|
||||
|
||||
def run(f, a, b, gate):
|
||||
st = {}
|
||||
CALLS[0] = 0
|
||||
_x, n, _ok = P.pure_root(counted(f), a, b, XTOL, MAXFEV, similarity="ratio",
|
||||
scale="derived3", guard="project", prestep=gate, stats=st)
|
||||
return n
|
||||
|
||||
|
||||
def main():
|
||||
P._analogous_and_steep = spy
|
||||
tally = Tally()
|
||||
ms_before = []
|
||||
print(f"{'problem':<10} {'exit: n':>7} {'analog: n':>9} {'first flag @':>12} "
|
||||
f"{'entry @':>8} reasons before entry")
|
||||
for s, pid, f, a, b, _root in load_problems():
|
||||
if s != "CHA" or pid.split(".")[0] not in FLAT:
|
||||
continue
|
||||
n_exit = run(f, a, b, "flatstickexit")
|
||||
LOG.clear()
|
||||
n_an = run(f, a, b, "flatanalog")
|
||||
first = LOG[0][0] if LOG else None
|
||||
entry = next((e for e, why, *_ in LOG if why == "ENTER"), None)
|
||||
before = [(why, val) for e, why, val, _, _ in LOG if entry is None or e < entry]
|
||||
for why, val in before:
|
||||
tally[why] += 1
|
||||
if why == "m<2" and val is not None and math.isfinite(val):
|
||||
ms_before.append(val)
|
||||
print(f"{pid:<10} {n_exit:7d} {n_an:9d} {str(first):>12} {str(entry):>8} "
|
||||
+ " ".join(why for why, _ in before))
|
||||
print("\nreasons at flag moments before entry, all 20 problems:", dict(tally))
|
||||
if ms_before:
|
||||
ms = sorted(ms_before)
|
||||
print("m read at analogous-but-refused moments:",
|
||||
" ".join(f"{m:.2f}" for m in ms))
|
||||
print("diag done")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
Reference in New Issue
Block a user