PREREG_estimated_transform_2026-09-22 (revision 2, point 5), before code and run: Chandrupatla on sign(f)|f|^(1/m_hat) with m_hat estimated during the run - Lagouanelle (K3-L) or A's analogy order (K3-A), hysteresis on the branches m>=2, m<=2/3; decisive on corpus 4; outcome rule including withdrawal of the 6.6 claim. Also diag_revision2.py (points 3, 4: the three unchanged Table 2 rows exhaust the budget on aps.13.00 under both criteria; exact-zero stops per method in Table 11).
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,71 @@
|
|||||||
|
# PREREG — классическое преобразование с оценённой кратностью (К3)
|
||||||
|
|
||||||
|
Составлено 2026-09-22 до кода и до прогона, ветка `release`. Доработка 2, п. 5;
|
||||||
|
Валерий: «контроль п. 5 делаем». Документ коммитится до кода; внешней метки времени нет (депозит на
|
||||||
|
Zenodo не делался — это решение автора, не принятое на момент записи), так что порядок подтверждается
|
||||||
|
только git, как и у прежних документов.
|
||||||
|
|
||||||
|
## Вопрос
|
||||||
|
|
||||||
|
Табл. 11 (К1): Chandrupatla на sign(f)|f|^{1/m\*} с **истинной** кратностью в 2.4–6.8 раза дешевле A′
|
||||||
|
на кратных и дробных корнях. Между ней и A′ — самая естественная классическая альтернатива:
|
||||||
|
тот же Chandrupatla на sign(f)|f|^{1/m̂}, где m̂ **оценивается по ходу прогона**. Она отвечает, сколько
|
||||||
|
стоит оценка порядка в классической рамке, а не в рамке A′, и закрывает (или нет) утверждение §6.6 о
|
||||||
|
том, что выигрыш несёт решающий слой A′.
|
||||||
|
|
||||||
|
## Определение К3
|
||||||
|
|
||||||
|
**Решатель.** Наша реализация Chandrupatla (`simroot/baselines.py::chandrupatla`), совпадающая с
|
||||||
|
`scipy.optimize.elementwise.find_root` на всех 199 задачах (`audit_chandrupatla_library.py`). Метод
|
||||||
|
хранит **истинные** значения f в своих трёх точках. Знаки, выбор лучшей точки и остановка — по f, как
|
||||||
|
у исходного метода (g и f имеют одинаковые знаки и одинаково упорядочены по модулю). В ξ, φ полосы
|
||||||
|
приёмки и в формуле обратной квадратичной интерполяции значения f заменяются на
|
||||||
|
G(v) = sign(v)·|v|^{1/m̂}, пересчитанные из хранимых f при текущем m̂. Лишних вычислений f нет.
|
||||||
|
|
||||||
|
**Оценка m̂.** Начальное m̂ = 1 (преобразования нет). После каждого вычисления по трём последним
|
||||||
|
вычисленным точкам (в порядке вычисления) читается порядок m одним из двух оценщиков:
|
||||||
|
|
||||||
|
- **К3-Л (Лагуанель):** m_L из параболы через три точки, θ = f·f''/f'², m = 1/(1 − θ) при θ < 1,
|
||||||
|
m = ∞ при θ ≥ 1 — ровно определение К2-Л (`_lagouanelle_raw`);
|
||||||
|
- **К3-А (аналогия):** порядок аналогичной пары A′ (формула (6), предел трансляции m = ∞), по памяти
|
||||||
|
конфигураций этого прогона — ровно `_config3` / `_analogy_order` A′.
|
||||||
|
|
||||||
|
**Гистерезис** (как в К2): m̂ заменяется прочитанным m, только если m ≥ 2 или 0 < m ≤ ⅔ (ветви §6.1);
|
||||||
|
чтения из (⅔, 2) и неопределённые m̂ не меняют. Сброса нет. При m̂ = ∞ G(v) = sign(v), и полоса почти
|
||||||
|
всегда отвергает интерполяцию — метод делит пополам.
|
||||||
|
|
||||||
|
Ни одного нового числа: ½, ⅔, 2 — константы A′ и К2. Кроме оценщика, ничего не выбирается.
|
||||||
|
|
||||||
|
**Проверка реализации до прогона:** при оценщике «нет» (m̂ ≡ 1) К3 совпадает с `chandrupatla` бит в
|
||||||
|
бит (x и число вычислений) на всех 199 задачах — тест.
|
||||||
|
|
||||||
|
## Где и как считать
|
||||||
|
|
||||||
|
Шесть корпусов §7, единый критерий (смена знака f в 10⁻⁶ или f = 0), бюджет 200, провал за 200,
|
||||||
|
остановка — ширина скобки ≤ εx или точный ноль f (как у всех). Нарушения границы 2⌈log₂(w/εx)⌉ + 4 —
|
||||||
|
сообщаются (Chandrupatla её не обещает).
|
||||||
|
|
||||||
|
## Критерии и что пишется в статье
|
||||||
|
|
||||||
|
| # | сообщается / решается |
|
||||||
|
|---|---|
|
||||||
|
| **E1** | **корпус 4, решающий:** для каждого оценщика — сумма К3 против A′, по задачам w/t/l, знаковый тест |
|
||||||
|
| **E2** | шесть корпусов: суммы К3-Л, К3-А, A′, Chandrupatla на f — сообщается |
|
||||||
|
| **E3** | кратные/дробные корни (группа табл. 11, m\* ≥ 2 или ≤ ⅔): К3-Л, К3-А, A′, оракул К1 — какая доля разрыва A′ → оракул закрыта оценкой в классической рамке |
|
||||||
|
| **E4** | простые корни (остальные): не хуже ли К3 обычного Chandrupatla — цена ложных срабатываний оценщика |
|
||||||
|
|
||||||
|
**Правило вывода (при любом исходе в статью):**
|
||||||
|
|
||||||
|
- Если хотя бы один вариант К3 на корпусе 4 **не хуже A′ по сумме**, или выигрывает у A′ по задачам со
|
||||||
|
знаковым тестом p < 0.05, — утверждение §6.6 о том, что выигрыш несёт решающий слой A′, **снимается**:
|
||||||
|
пишется, что классическое преобразование с оценкой порядка по ходу прогона даёт то же (или больше), и
|
||||||
|
вклад статьи сужается до вывода и сравнения; аннотация и заключение следуют за этим.
|
||||||
|
- Если A′ дешевле обоих вариантов на корпусе 4 и выигрывает по задачам с p < 0.05, — утверждение
|
||||||
|
остаётся, с числами К3 рядом с К1 в табл. 11.
|
||||||
|
- Промежуточный исход (A′ дешевле по сумме, но по задачам незначимо) пишется как есть, без вывода в
|
||||||
|
пользу A′.
|
||||||
|
- Сравнение К3-А и К3-Л отделяет оценщик от рамки: если К3-А лучше К3-Л, оценка по аналогии лучше и в
|
||||||
|
классической рамке; если К3-А хуже A′, выигрыш A′ — в рамке (режим, выход, остальные правила).
|
||||||
|
|
||||||
|
**Стоп-правило.** Один прогон. Определения после него не меняются; поправки, если понадобятся после
|
||||||
|
смоука, записываются здесь с перечнем уже увиденного, как в `PREREG_controls_2026-09-22.md`.
|
||||||
@@ -0,0 +1,86 @@
|
|||||||
|
"""Revision 2, points 3 and 4 - facts only, no new method.
|
||||||
|
|
||||||
|
Point 3: Dekker, Illinois and false position show the same APS totals under both criteria. Which
|
||||||
|
problems do they fail, and why do they fail aps.13.00 under 'sign change or f = 0' as well?
|
||||||
|
Point 4: how do the runs on g = sign(f)|f|^(1/m*) (Table 11) end - by the bracket width, or on an
|
||||||
|
exact zero of g (which every method, A' included, accepts)? Counted per method on the
|
||||||
|
multiple/fractional problems, next to A' on the same problems.
|
||||||
|
|
||||||
|
python -u diag_revision2.py
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import json
|
||||||
|
import math
|
||||||
|
import random
|
||||||
|
|
||||||
|
import scipy.optimize._tstutils as T
|
||||||
|
|
||||||
|
from corpus_roots_jl import solved
|
||||||
|
from rescore_uniform import load_uniform
|
||||||
|
from simroot.baselines import brent_scipy, chandrupatla_lib
|
||||||
|
from simroot.pure import pure_root
|
||||||
|
from sweep_controls import k1_problems, m_star, nonsimple
|
||||||
|
from sweep_full import MAXFEV, XTOL, make_method
|
||||||
|
|
||||||
|
APRIME = ("pure", "ratio", "derived3", "project", "x", "contra+flatanalogmempt+exp+half+close+sub",
|
||||||
|
"recent", "distance", "none", "pattern")
|
||||||
|
|
||||||
|
|
||||||
|
def point3():
|
||||||
|
U = {r["label"]: r for r in load_uniform("sweep_full.json")}
|
||||||
|
O = {r["label"]: r for r in json.load(open("sweep_full.json", encoding="utf8"))}
|
||||||
|
probs = {pid: (f, a, b) for s, pid, f, a, b, _r in __import__("sweep_full").load_problems()}
|
||||||
|
for lb in ("dekker", "illinois", "regula_falsi"):
|
||||||
|
fails_u = [p for p, (n, ok) in U[lb]["APS"]["per"].items() if not ok]
|
||||||
|
fails_o = [p for p, (n, ok) in O[lb]["APS"]["per"].items() if not ok]
|
||||||
|
print(f"{lb}: APS failures uniform {len(fails_u)}, harness {len(fails_o)}, "
|
||||||
|
f"same set {sorted(fails_u) == sorted(fails_o)}; uniform total {U[lb]['APS']['total']}, "
|
||||||
|
f"harness {O[lb]['APS']['total']}")
|
||||||
|
f, a, b = probs["aps.13.00"]
|
||||||
|
x, n, conv = make_method(("base", lb))(f, a, b, XTOL, MAXFEV)
|
||||||
|
print(f" aps.13.00: returned x={float(x):.3g}, nfev={n}, converged={conv}, "
|
||||||
|
f"f(x)={f(float(x))!r}, sign-change criterion {solved(f, float(x))}")
|
||||||
|
|
||||||
|
|
||||||
|
def ends_on_zero(method, f, g, a, b):
|
||||||
|
"""(nfev, stopped on an exact zero of the function it saw, bracket-width stop)."""
|
||||||
|
seen = []
|
||||||
|
|
||||||
|
def w(x):
|
||||||
|
v = g(x)
|
||||||
|
seen.append(v)
|
||||||
|
return v
|
||||||
|
T._f6_cache.clear()
|
||||||
|
random.seed(20260921)
|
||||||
|
x, n, conv = method(w, a, b, XTOL, MAXFEV)
|
||||||
|
return int(n), bool(seen and seen[-1] == 0.0), bool(conv)
|
||||||
|
|
||||||
|
|
||||||
|
def point4():
|
||||||
|
for s in ("CHA", "NEW", "D"):
|
||||||
|
tally = {"chandrupatla_g": [0, 0, 0], "brent_g": [0, 0, 0], "Aprime": [0, 0, 0]}
|
||||||
|
for pid, f, a, b, r in k1_problems(s):
|
||||||
|
m = m_star(f, r)
|
||||||
|
if not nonsimple(m):
|
||||||
|
continue
|
||||||
|
inv = 1.0 / m
|
||||||
|
|
||||||
|
def g(x, _f=f, _i=inv):
|
||||||
|
v = _f(x)
|
||||||
|
return 0.0 if v == 0 else math.copysign(abs(v) ** _i, v)
|
||||||
|
for name, meth, fun in (("chandrupatla_g", chandrupatla_lib, g), ("brent_g", brent_scipy, g),
|
||||||
|
("Aprime", make_method(APRIME), f)):
|
||||||
|
n, zero, conv = ends_on_zero(meth, f, fun, a, b)
|
||||||
|
t = tally[name]
|
||||||
|
t[0] += 1
|
||||||
|
t[1] += zero
|
||||||
|
t[2] += n
|
||||||
|
print(f"{s}: problems {tally['Aprime'][0]}; runs ending on an exact zero / total evaluations: " +
|
||||||
|
"; ".join(f"{k} {v[1]}/{v[2]}" for k, v in tally.items()))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
point3()
|
||||||
|
point4()
|
||||||
|
print("revision2 diag done")
|
||||||
Reference in New Issue
Block a user