"""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)