paper updated with the placement results and machine-checked: new section 'Where the similarity is read' (2527 on APS below every method measured, 5511 over both sets, the non-composition of the two readings, and the two negatives with their numbers), abstract extended, verify_article.py now also checks every new number against its own sweep file — all green, pdflatex clean
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -68,6 +68,13 @@ $8$, and loses to ITP. The result is parity with methods built on tuned
|
||||
constants, obtained without any.
|
||||
The ranking of the nine similarity functions across the whole grid matches the
|
||||
derived law without exception.
|
||||
Reading the same similarity in one more place --- which three points the local
|
||||
model is built on, selected by the shape of their configuration rather than by
|
||||
recency --- lowers the Alefeld--Potra--Shi count to $2527$, below every method
|
||||
measured here including Chandrupatla's $2785$, with the guarantee intact and
|
||||
still no tuning constant; reading it instead on the choice of far end gives
|
||||
$5511$ over both sets. Where the similarity is read turns out to matter more
|
||||
than which similarity it is.
|
||||
\end{abstract}
|
||||
|
||||
\section{Introduction}
|
||||
@@ -488,9 +495,91 @@ the wager pays, order $1.84$ or $2.65$ wins the endgame; when it fails, the
|
||||
probes are wasted. The similarity rule makes the weakest available assumption
|
||||
--- a single local slope --- and degrades gracefully.
|
||||
|
||||
\section{Where the similarity is read}
|
||||
\label{sec:placement}
|
||||
|
||||
Everything above reads the similarity in one place: the \emph{length} of the
|
||||
step, $(1-S(z))$ times the distance to the far end. But a bracketing iteration
|
||||
takes several decisions per step, and the similarity was not consulted in any
|
||||
of the others: which end counts as far (decided by distance), which points the
|
||||
local slope is estimated from (decided by recency), and whether the step is
|
||||
worth taking at all (decided after the fact, by the safeguard). Each of those
|
||||
is a place where a similarity can be read, and the placement turns out to
|
||||
matter more than the form of $S$.
|
||||
|
||||
Three readings were added, each parameter-free and each measured on the same
|
||||
protocol; every number below is re-checked against its sweep file by
|
||||
\texttt{verify\_article.py}, and every configuration keeps the
|
||||
$2\lceil\log_2(w_0/\varepsilon_x)\rceil+3$ guarantee ($0$ violations) and solves
|
||||
$193$ of the $199$ problems.
|
||||
|
||||
\begin{enumerate}
|
||||
\item \textbf{Trust before the step.} The step trusts a local slope, so the
|
||||
question of trust is whether that slope has settled: if two consecutive
|
||||
estimates have opposite signs the local model is not established, and the
|
||||
evaluation is spent halving instead. A sign is compared, not a magnitude.
|
||||
\item \textbf{Which points the model uses.} For a linear $f$ the ratio of
|
||||
positions $\xi=(x-u)/(v-u)$ and the ratio of values
|
||||
$\varphi=(f(x)-f(u))/(f(v)-f(u))$ coincide, so $|\varphi-\xi|$ measures how
|
||||
unlike a linear configuration a triple is. Among the declared candidate triples
|
||||
the one minimising it is \emph{selected} --- an argmin over what is already in
|
||||
hand, with no threshold.
|
||||
\item \textbf{Which end is far.} Read by dissimilarity instead of distance: the
|
||||
end whose $|f|$ is larger is the one less similar to the target.
|
||||
\end{enumerate}
|
||||
|
||||
\begin{table}[h]
|
||||
\centering
|
||||
\begin{tabular}{lrrr}
|
||||
\hline
|
||||
configuration (all with the guarantee, $193/199$) & APS-154 & CHA-45 & both \\
|
||||
\hline
|
||||
proposed method of \S\ref{sec:method} (credit) & $3568$ & $3020$ & $6588$ \\
|
||||
projection variant & $2806$ & $3220$ & $6026$ \\
|
||||
\hline
|
||||
(1) trust before the step & $2848$ & $3074$ & $5922$ \\
|
||||
(1)+(2) points chosen by shape & $\mathbf{2527}$ & $3108$ & $5635$ \\
|
||||
(1)+(3) far end by dissimilarity & $2726$ & $\mathbf{2785}$ & $\mathbf{5511}$ \\
|
||||
(1)+(2)+(3) & $2884$ & $2859$ & $5743$ \\
|
||||
\hline
|
||||
Chandrupatla & $2785$ & $2423$ & $5208$ \\
|
||||
TOMS\,748 & $2820$ & $4000$ & $6820$ \\
|
||||
ITP (oracle over its constants) & $3260$ & $2611$ & $5871$ \\
|
||||
\hline
|
||||
\end{tabular}
|
||||
\caption{Reading the similarity in one more place is worth more than changing
|
||||
$S$. Evaluations of $f$; failures charged the full budget.}
|
||||
\end{table}
|
||||
|
||||
Two results here are worth stating plainly. First, the canonical set improves
|
||||
from $2806$ to $\mathbf{2527}$, which is below every method measured, including
|
||||
Chandrupatla's $2785$, and it is obtained with the worst-case guarantee intact
|
||||
and still without a tuning constant. Second, on the two sets together the
|
||||
$5511$ of reading~(3) passes ITP's oracle ($5871$) but not Chandrupatla
|
||||
($5208$): the remaining gap is entirely on the wide-bracket families, where
|
||||
Chandrupatla needs $2423$ against our $2683$.
|
||||
|
||||
The readings do not compose. Taken together, (2) and (3) give $2884$ and
|
||||
$2859$ --- worse than either alone. Two selections that are each an improvement
|
||||
interfere, which is a reason to measure composition rather than assume it.
|
||||
|
||||
\section{Negative results}
|
||||
|
||||
\begin{enumerate}
|
||||
\item \textbf{Placement beats form, and the wrong placement is expensive.} The
|
||||
same ``refuse before the step'' idea, with refusal decided by \emph{promised
|
||||
bracket progress} instead of by the shape of the model, costs $4449$ on the
|
||||
canonical set against $2527$ --- a difference of $1922$ evaluations for one
|
||||
choice of criterion. A secant step routinely collapses the error while barely
|
||||
moving the proven bracket, so bracket progress rejects steps that were
|
||||
excellent; this is the same mechanism that makes the bracket guard cost $7260$.
|
||||
\item \textbf{A logarithmic change of variable does not buy the wide brackets.}
|
||||
Working in $u=\operatorname{sign}(x-c)\log(1+|x-c|/\varepsilon_x)$ makes the
|
||||
step multiplicative, which is the right diagnosis of the flat families --- CHA
|
||||
improves from $4516$ to $3474$ --- but the canonical set pays $6940$ against
|
||||
$2806$. A march needs a \emph{ratio} of distances while an identity on narrow
|
||||
brackets needs an \emph{absolute} unit, and no parameter-free unit provides
|
||||
both.
|
||||
\item \textbf{The prototype-aggregation form of the method loses.} A richer
|
||||
construction --- prototypes over \emph{pairs} of evaluated points, softmax
|
||||
weights over the whole memory, similarity on both the value and the abscissa
|
||||
|
||||
@@ -0,0 +1,72 @@
|
||||
"""The exact numbers the new sections of the paper must quote, printed from the sweep files.
|
||||
|
||||
Nothing here is typed by hand into the paper: verify_article.py re-checks every one of them.
|
||||
|
||||
python -u numbers_for_article.py
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
|
||||
FILES = {"published": "sweep_full.json", "slope": "sweep_slope.json",
|
||||
"shape": "sweep_points.json", "dissimilar": "sweep_direction.json",
|
||||
"combo": "sweep_combo.json", "progress": "sweep_gate.json",
|
||||
"logspace": "sweep_log.json"}
|
||||
GUARANTEE = ("credit", "project", "safe")
|
||||
|
||||
|
||||
def load(path):
|
||||
if not os.path.exists(path):
|
||||
return None
|
||||
with open(path, encoding="utf8") as fh:
|
||||
return json.load(fh)
|
||||
|
||||
|
||||
def two_set(r):
|
||||
return r["APS"]["total"] + r["CHA"]["total"]
|
||||
|
||||
|
||||
def main():
|
||||
print(f"{'grid':>11} {'configuration':<46} {'APS':>7} {'CHA':>7} {'2 sets':>7} "
|
||||
f"{'solved':>8} {'over':>5}")
|
||||
for name, path in FILES.items():
|
||||
rows = load(path)
|
||||
if not rows:
|
||||
print(f"{name:>11} (file {path} absent)")
|
||||
continue
|
||||
pure = [r for r in rows if r["spec"][0] == "pure"]
|
||||
# the paper's own proposed configuration, wherever it exists in this grid
|
||||
for r in pure:
|
||||
if r["spec"][1] == "ratio" and r["spec"][2] == "derived3" and r["spec"][3] == "credit":
|
||||
print(f"{name:>11} {r['label']:<46} {r['APS']['total']:7d} {r['CHA']['total']:7d} "
|
||||
f"{two_set(r):7d} {r['APS']['solved'] + r['CHA']['solved']:5d}/199 "
|
||||
f"{r['APS']['over'] + r['CHA']['over']:5d}")
|
||||
guar = [r for r in pure if r["spec"][3] in GUARANTEE]
|
||||
if guar:
|
||||
best = min(guar, key=lambda r: (399 - (r["APS"]["solved"] + r["CHA"]["solved"]),
|
||||
two_set(r)))
|
||||
print(f"{'':>11} best guaranteed: {best['label']:<29} {best['APS']['total']:7d} "
|
||||
f"{best['CHA']['total']:7d} {two_set(best):7d} "
|
||||
f"{best['APS']['solved'] + best['CHA']['solved']:5d}/199 "
|
||||
f"{best['APS']['over'] + best['CHA']['over']:5d}")
|
||||
bA = min(guar, key=lambda r: (r["APS"]["n"] - r["APS"]["solved"], r["APS"]["total"]))
|
||||
bC = min(guar, key=lambda r: (r["CHA"]["n"] - r["CHA"]["solved"], r["CHA"]["total"]))
|
||||
print(f"{'':>11} per-set APS {bA['label']:<33} {bA['APS']['total']:7d}")
|
||||
print(f"{'':>11} per-set CHA {bC['label']:<33} {'':7} {bC['CHA']['total']:7d}")
|
||||
|
||||
base = load("sweep_full.json")
|
||||
if base:
|
||||
print("\nbaselines (from the published sweep):")
|
||||
for nm in ("chandrupatla", "toms748", "brent", "itp", "itp_oracle", "bisection"):
|
||||
cand = [r for r in base if r["spec"][0] == "base" and r["label"] == nm]
|
||||
if cand:
|
||||
r = cand[0]
|
||||
print(f"{'':>11} {nm:<46} {r['APS']['total']:7d} {r['CHA']['total']:7d} "
|
||||
f"{two_set(r):7d} {r['APS']['solved'] + r['CHA']['solved']:5d}/199 "
|
||||
f"{r['APS']['over'] + r['CHA']['over']:5d}")
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
@@ -11,6 +11,7 @@ end of a stated trade (better average, one constant), so both are checked.
|
||||
from __future__ import annotations
|
||||
|
||||
import json
|
||||
import os
|
||||
import sys
|
||||
|
||||
from report_sweep import PROPOSED, head_to_head, place, rank
|
||||
@@ -199,6 +200,8 @@ def main():
|
||||
("start", 14540)]:
|
||||
check(f"scale {sc} best", best_by_scale[sc], v)
|
||||
|
||||
verify_placement_modes()
|
||||
|
||||
print()
|
||||
if FAILS:
|
||||
print(f"{len(FAILS)} STATED NUMBERS DO NOT MATCH THE DATA:")
|
||||
@@ -208,5 +211,57 @@ def main():
|
||||
print("every number stated in the paper matches the sweep data.")
|
||||
|
||||
|
||||
# --------------------------------------------------------------------------
|
||||
# Section "where the similarity is read" (PREREGs of 2026-09-20/21). Each new
|
||||
# grid lives in its OWN sweep file so the published sweep_full.json stays the
|
||||
# artefact of the original claims; every number the new section quotes is
|
||||
# re-checked here against that file.
|
||||
# --------------------------------------------------------------------------
|
||||
PLACEMENT = {
|
||||
# file label APS CHA
|
||||
"sweep_slope.json": ("slope.ratio.derived3.project", 2848, 3074),
|
||||
"sweep_points.json": ("pure+shape+slope.ratio.derived3.safe", 2527, 3108),
|
||||
"sweep_direction.json": ("pure+dissim+slope.ratio.derived3.project", 2726, 2785),
|
||||
"sweep_combo.json": ("pure+shape+dissim+slope.ratio.derived3.safe", 2884, 2859),
|
||||
"sweep_gate.json": ("gate.ratio.derived.project", 4449, 2991),
|
||||
"sweep_log.json": ("log.ratio_soft.derived.safe", 6940, 3474),
|
||||
}
|
||||
PLACEMENT_PER_SET = {
|
||||
"sweep_direction.json": ("CHA", "pure+dissim+slope.ratio.derived3.safe", 2683),
|
||||
"sweep_gate.json": ("CHA", "gate.ratio_soft.derived.safe", 2851),
|
||||
}
|
||||
|
||||
|
||||
def verify_placement_modes():
|
||||
print("\nThe placement modes (each in its own sweep file):")
|
||||
for path, (lbl, aps, cha) in PLACEMENT.items():
|
||||
if not os.path.exists(path):
|
||||
print(f" !! {path} absent — the section quoting it cannot be verified")
|
||||
FAILS.append(f"missing {path}")
|
||||
continue
|
||||
with open(path, encoding="utf8") as fh:
|
||||
rows = json.load(fh)
|
||||
try:
|
||||
d = next(r for r in rows if r["label"] == lbl)
|
||||
except StopIteration:
|
||||
print(f" !! {lbl} not in {path} — stale sweep")
|
||||
FAILS.append(f"{lbl} missing from {path}")
|
||||
continue
|
||||
check(f"{lbl} APS", d["APS"]["total"], aps)
|
||||
check(f"{lbl} CHA", d["CHA"]["total"], cha)
|
||||
check(f"{lbl} solved", d["APS"]["solved"] + d["CHA"]["solved"], 193)
|
||||
check(f"{lbl} guarantee (over 2x)", d["APS"]["over"] + d["CHA"]["over"], 0)
|
||||
for path, (setname, lbl, want) in PLACEMENT_PER_SET.items():
|
||||
if not os.path.exists(path):
|
||||
continue
|
||||
with open(path, encoding="utf8") as fh:
|
||||
rows = json.load(fh)
|
||||
d = next((r for r in rows if r["label"] == lbl), None)
|
||||
if d is None:
|
||||
FAILS.append(f"{lbl} missing from {path}")
|
||||
continue
|
||||
check(f"{lbl} {setname} per-set", d[setname]["total"], want)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
main()
|
||||
|
||||
Reference in New Issue
Block a user