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.
|
constants, obtained without any.
|
||||||
The ranking of the nine similarity functions across the whole grid matches the
|
The ranking of the nine similarity functions across the whole grid matches the
|
||||||
derived law without exception.
|
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}
|
\end{abstract}
|
||||||
|
|
||||||
\section{Introduction}
|
\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
|
probes are wasted. The similarity rule makes the weakest available assumption
|
||||||
--- a single local slope --- and degrades gracefully.
|
--- 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}
|
\section{Negative results}
|
||||||
|
|
||||||
\begin{enumerate}
|
\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
|
\item \textbf{The prototype-aggregation form of the method loses.} A richer
|
||||||
construction --- prototypes over \emph{pairs} of evaluated points, softmax
|
construction --- prototypes over \emph{pairs} of evaluated points, softmax
|
||||||
weights over the whole memory, similarity on both the value and the abscissa
|
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
|
from __future__ import annotations
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
from report_sweep import PROPOSED, head_to_head, place, rank
|
from report_sweep import PROPOSED, head_to_head, place, rank
|
||||||
@@ -199,6 +200,8 @@ def main():
|
|||||||
("start", 14540)]:
|
("start", 14540)]:
|
||||||
check(f"scale {sc} best", best_by_scale[sc], v)
|
check(f"scale {sc} best", best_by_scale[sc], v)
|
||||||
|
|
||||||
|
verify_placement_modes()
|
||||||
|
|
||||||
print()
|
print()
|
||||||
if FAILS:
|
if FAILS:
|
||||||
print(f"{len(FAILS)} STATED NUMBERS DO NOT MATCH THE DATA:")
|
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.")
|
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__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
Reference in New Issue
Block a user