PREREG before any run: third corpus - the GSL root-finding test suite (10, published) and 122 physics/engineering equations on grids fixed beforehand (Kepler incl. e up to 0.999, Colebrook-White, Lambert W, Planck/Wien, van der Waals CO2 incl. near-critical, IRR, finite square well). T1-T3 as before; GSL part reported separately; per equation breakdown.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,37 @@
|
|||||||
|
# PREREG — третий независимый корпус: набор GSL и прикладные уравнения
|
||||||
|
|
||||||
|
Составлено до прогона, ветка `signfix-and-gates`. Валерий: «давай ещё найдём корпус для теста, для
|
||||||
|
статьи это будет только плюс».
|
||||||
|
|
||||||
|
## Корпус (`corpus_applied.py`, закоммичен до прогона)
|
||||||
|
|
||||||
|
- **G** — тестовый набор модуля поиска корней GNU Scientific Library (`roots/test.c`,
|
||||||
|
`test_funcs.c`, зеркало github.com/ampl/gsl): все 10 задач со скобкой, как в оригинале.
|
||||||
|
- **P** — 122 уравнения из физики и инженерии на стандартных сетках параметров, заданных до прогона:
|
||||||
|
уравнение Кеплера (35: e ∈ {0.1, 0.5, 0.9, 0.99, 0.999} × 7 значений M), Колбрука–Уайта (36: Re ×
|
||||||
|
шероховатость), W-функция Ламберта (7), закон смещения Вина/Планка (7), Ван-дер-Ваальс для CO₂
|
||||||
|
(20: T × P, включая околокритическую T = 304 K), внутренняя норма доходности (12), конечная
|
||||||
|
квантовая яма (5). Все 132 имеют разные знаки на концах.
|
||||||
|
- Успех — смена знака в пределах 10⁻⁶ от ответа (как в PREREG_roots_jl). XTOL 10⁻¹², MAXFEV 200,
|
||||||
|
неудача = 200; гарантия ≤ 2⌈log₂(w/xtol)⌉ + 4.
|
||||||
|
|
||||||
|
Сетки выбраны мной — корпус не так независим, как опубликованный, поэтому **часть G (опубликованная)
|
||||||
|
сообщается отдельно**, а по части P — разбивка по уравнениям.
|
||||||
|
|
||||||
|
## Варианты и критерии — те же
|
||||||
|
|
||||||
|
**A** = Г2 + `contra+flatanalogmempt+exp+half`; **B** = `defect+flatanalogmempt+exp`; справочно — предложенный
|
||||||
|
метод без добавок; соперники — библиотечные Чандрупатла, Брент, TOMS748.
|
||||||
|
|
||||||
|
| # | ПРОЙДЕНО, если (все 132) |
|
||||||
|
|---|---|
|
||||||
|
| **T1** | сумма вызовов V меньше, чем у Чандрупатлы |
|
||||||
|
| **T2** | по задачам против Чандрупатлы побед больше, чем поражений, знаковый тест p < 0.05 |
|
||||||
|
| **T3** | гарантия: 0 нарушений; решено не меньше, чем у Чандрупатлы |
|
||||||
|
|
||||||
|
«Переносится» — T1, T2, T3 одновременно; сообщается также, выполнен ли T1 отдельно (выигрыш по сумме).
|
||||||
|
Метод, корпус и критерии не меняются.
|
||||||
|
|
||||||
|
**Ожидание, записано заранее:** почти-кратные случаи — Кеплер с e → 1 при малом M (около нуля
|
||||||
|
E − e sin E ≈ (1 − e)E + E³/6) и околокритический Ван-дер-Ваальс; остальное — гладкие простые корни,
|
||||||
|
где по двум прошлым корпусам ожидается паритет.
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
"""A third OUT-OF-SAMPLE corpus for PREREG_applied_2026-09-21, fixed before any method runs on it.
|
||||||
|
|
||||||
|
Part G - the GNU Scientific Library root-finding test suite (roots/test.c, test_funcs.c,
|
||||||
|
mirror github.com/ampl/gsl): the 10 bracketed problems, verbatim.
|
||||||
|
Part P - equations from physics and engineering on standard parameter grids, chosen before
|
||||||
|
any run (the grids are the pre-registration; nothing is tuned afterwards):
|
||||||
|
kepler E - e sin E - M = 0, E in [0, pi]; e x M grid (e up to 0.999: near-cubic)
|
||||||
|
colebrook 1/sqrt(f) + 2 log10(eps/3.7 + 2.51/(Re sqrt(f))) = 0, f in [1e-3, 0.2]
|
||||||
|
lambert x e^x - y = 0, x in [0, max(1, ln y + 1)]
|
||||||
|
planck x - n (1 - e^-x) = 0, x in [0.5, 2n] (n = 3: frequency peak, 5: wavelength)
|
||||||
|
vdw (P + a/V^2)(V - b) - R T = 0 for CO2, V in [1.001 b, 2RT/P + b] (T near 304 K is
|
||||||
|
near-critical: a flat, nearly triple root)
|
||||||
|
irr -100 + sum_{t=1..n} c (1+r)^-t = 0, r in [-0.5, 10]
|
||||||
|
well z sin z - sqrt(z0^2 - z^2) cos z = 0 (finite square well, ground state),
|
||||||
|
z in [0, min(pi/2, z0)]
|
||||||
|
Roots are not all known in closed form; success is a sign change within 1e-6 of the answer,
|
||||||
|
the criterion of PREREG_roots_jl (corpus_roots_jl.solved).
|
||||||
|
"""
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import math
|
||||||
|
|
||||||
|
pi = math.pi
|
||||||
|
|
||||||
|
|
||||||
|
def _sgn(x):
|
||||||
|
return 0.0 if x == 0 else math.copysign(1.0, x)
|
||||||
|
|
||||||
|
|
||||||
|
GSL = [
|
||||||
|
("G.sin[3,4]", math.sin, 3.0, 4.0),
|
||||||
|
("G.sin[-4,-3]", math.sin, -4.0, -3.0),
|
||||||
|
("G.sin[-1/3,1]", math.sin, -1.0 / 3.0, 1.0),
|
||||||
|
("G.cos[0,3]", math.cos, 0.0, 3.0),
|
||||||
|
("G.cos[-3,0]", math.cos, -3.0, 0.0),
|
||||||
|
("G.x^20-1", lambda x: x ** 20.0 - 1, 0.1, 2.0),
|
||||||
|
("G.sqrt|x|sgn", lambda x: math.sqrt(abs(x)) * _sgn(x), -1.0 / 3.0, 1.0),
|
||||||
|
("G.x^2-1e-8", lambda x: x ** 2.0 - 1e-8, 0.0, 1.0),
|
||||||
|
("G.x*exp(-x)", lambda x: x * math.exp(-x), -1.0 / 3.0, 2.0),
|
||||||
|
("G.(x-1)^7", lambda x: (x - 1) ** 7.0, 0.9995, 1.0002),
|
||||||
|
]
|
||||||
|
|
||||||
|
|
||||||
|
def _applied():
|
||||||
|
out = []
|
||||||
|
for e in (0.1, 0.5, 0.9, 0.99, 0.999):
|
||||||
|
for M in (0.001, 0.01, 0.1, 0.5, 1.0, 2.0, 3.0):
|
||||||
|
out.append((f"P.kepler.e{e}.M{M}",
|
||||||
|
(lambda E, e=e, M=M: E - e * math.sin(E) - M), 0.0, pi))
|
||||||
|
for Re in (4e3, 1e4, 1e5, 1e6, 1e7, 1e8):
|
||||||
|
for rel in (0.0, 1e-6, 1e-4, 1e-3, 1e-2, 5e-2):
|
||||||
|
out.append((f"P.colebrook.Re{Re:.0e}.e{rel}",
|
||||||
|
(lambda f, Re=Re, rel=rel: 1 / math.sqrt(f)
|
||||||
|
+ 2 * math.log10(rel / 3.7 + 2.51 / (Re * math.sqrt(f)))), 1e-3, 0.2))
|
||||||
|
for y in (1e-6, 1e-3, 0.1, 1.0, 10.0, 1e3, 1e6):
|
||||||
|
out.append((f"P.lambert.y{y}", (lambda x, y=y: x * math.exp(x) - y),
|
||||||
|
0.0, max(1.0, math.log(y) + 1.0)))
|
||||||
|
for n in (2, 3, 4, 5, 6, 8, 10):
|
||||||
|
out.append((f"P.planck.n{n}", (lambda x, n=n: x - n * (1 - math.exp(-x))), 0.5, 2.0 * n))
|
||||||
|
a, b, R = 3.64, 0.04267, 0.08314
|
||||||
|
for T in (280.0, 304.0, 350.0, 500.0):
|
||||||
|
for P in (1.0, 10.0, 40.0, 73.0, 100.0):
|
||||||
|
out.append((f"P.vdw.T{T:.0f}.P{P:.0f}",
|
||||||
|
(lambda V, T=T, P=P: (P + a / V ** 2) * (V - b) - R * T),
|
||||||
|
1.001 * b, 2 * R * T / P + b))
|
||||||
|
for c in (5.0, 10.0, 20.0, 50.0):
|
||||||
|
for n in (5, 10, 30):
|
||||||
|
out.append((f"P.irr.c{c:.0f}.n{n}",
|
||||||
|
(lambda r, c=c, n=n: -100.0 + sum(c * (1 + r) ** -t for t in range(1, n + 1))),
|
||||||
|
-0.5, 10.0))
|
||||||
|
for z0 in (1.0, 3.0, 5.0, 10.0, 20.0):
|
||||||
|
out.append((f"P.well.z0{z0:.0f}",
|
||||||
|
(lambda z, z0=z0: z * math.sin(z) - math.sqrt(max(z0 * z0 - z * z, 0.0)) * math.cos(z)),
|
||||||
|
0.0, min(pi / 2, z0)))
|
||||||
|
return out
|
||||||
|
|
||||||
|
|
||||||
|
def build():
|
||||||
|
"""[(id, f, a, b)] with values of opposite sign at the ends, and the ids dropped."""
|
||||||
|
out, dropped = [], []
|
||||||
|
for pid, f, a, b in GSL + _applied():
|
||||||
|
try:
|
||||||
|
fa, fb = f(a), f(b)
|
||||||
|
good = (math.isfinite(fa) and math.isfinite(fb) and fa != 0 and fb != 0
|
||||||
|
and (fa < 0) != (fb < 0))
|
||||||
|
except (OverflowError, ValueError, ZeroDivisionError):
|
||||||
|
good = False
|
||||||
|
(out if good else dropped).append((pid, f, float(a), float(b)) if good else pid)
|
||||||
|
return out, dropped
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
from collections import Counter
|
||||||
|
probs, dropped = build()
|
||||||
|
print(len(probs), "problems;", dict(Counter(p[0].split(".")[0] + "." + p[0].split(".")[1]
|
||||||
|
if p[0].startswith("P.") else "GSL" for p in probs)))
|
||||||
|
print("dropped (no sign change at the ends):", dropped)
|
||||||
Reference in New Issue
Block a user