"""An OUT-OF-SAMPLE corpus for PREREG_out_of_sample_2026-09-21: problems no method variant was developed on. Fixed before any method is run on it; seed and distributions below are part of the pre-registration and are never changed afterwards. Six classes. C0 is SciPy's 'original' collection (6 problems, never used here before). C1-C5 are generated, 40 problems each, from one numpy Generator(seed=20260921): C1 smooth simple root f = (x - r) * g(x), g = exp(a sin(c x)) + b x^2 > 0 C2 transcendental simple f = one of atan(k(x-r)), tanh(k(x-r)), expm1(k(x-r)), sinh(k(x-r)) C3 multiple / flat root f = sign(x-r) |x-r|^p * g(x), p ~ U(2, 20) (real, not only odd) C4 exponential flank f = exp(k x) - exp(k r) (steep one-sided growth) C5 near-cancelling terms f = exp(x) - e^r + a (1/x^2 - 1/r^2) - b (1/x^3 - 1/r^3), x > 0 (the kind of end that misled us on fun9, with random parameters) Brackets: root r ~ U(-1, 1) (C5: r ~ U(0.3, 2)); width L log-uniform on [0.1, 1000] (C4: capped so that k * right end <= 600, C5: left end >= r/1000); the root sits at a fraction u ~ U(0.02, 0.98) of the bracket. Every problem is checked for finite values of opposite sign at the ends; one that fails is redrawn (the redraw count is reported). """ from __future__ import annotations import math import numpy as np SEED = 20260921 PER_CLASS = 40 def _bracket(rng, r, lo_w=0.1, hi_w=1000.0): L = math.exp(rng.uniform(math.log(lo_w), math.log(hi_w))) u = rng.uniform(0.02, 0.98) return r - u * L, r + (1.0 - u) * L def _ok(f, a, b): try: fa, fb = f(a), f(b) except (OverflowError, ValueError, ZeroDivisionError): return False return (math.isfinite(fa) and math.isfinite(fb) and fa != 0.0 and fb != 0.0 and (fa < 0.0) != (fb < 0.0)) def _c1(rng): r = rng.uniform(-1, 1) a, b, c = rng.uniform(0, 1), rng.uniform(0, 0.5), rng.uniform(0.5, 5) f = lambda x, r=r, a=a, b=b, c=c: (x - r) * (math.exp(a * math.sin(c * x)) + b * x * x) return f, r, _bracket(rng, r) def _c2(rng): r = rng.uniform(-1, 1) k = math.exp(rng.uniform(math.log(0.2), math.log(20))) kind = int(rng.integers(4)) base = (math.atan, math.tanh, math.expm1, math.sinh)[kind] a, b = _bracket(rng, r) if kind in (2, 3): # keep exp/sinh finite on the bracket span = max(abs(a - r), abs(b - r)) if k * span > 600: k = 600 / span return (lambda x, r=r, k=k, g=base: g(k * (x - r))), r, (a, b) def _c3(rng): r = rng.uniform(-1, 1) p = rng.uniform(2, 20) a, c = rng.uniform(0, 1), rng.uniform(0.5, 5) lo, hi = _bracket(rng, r, hi_w=30.0) # |x - r|^20 stays finite f = lambda x, r=r, p=p, a=a, c=c: math.copysign(abs(x - r) ** p, x - r) * math.exp(a * math.sin(c * x)) return f, r, (lo, hi) def _c4(rng): r = rng.uniform(-1, 1) k = math.exp(rng.uniform(math.log(0.5), math.log(5))) lo, hi = _bracket(rng, r) if k * hi > 600: hi = 600 / k er = math.exp(k * r) return (lambda x, k=k, er=er: math.exp(k * x) - er), r, (lo, hi) def _c5(rng): r = rng.uniform(0.3, 2.0) a = math.exp(rng.uniform(math.log(1e-3), math.log(1e-1))) b = a * rng.uniform(0.01, 0.5) * r L = math.exp(rng.uniform(math.log(0.1), math.log(100))) u = rng.uniform(0.02, 0.98) lo, hi = max(r - u * L, r / 1000.0), r + (1.0 - u) * L hi = min(hi, 600.0) er = math.exp(r) f = lambda x, r=r, a=a, b=b, er=er: (math.exp(x) - er + a * (1 / x ** 2 - 1 / r ** 2) - b * (1 / x ** 3 - 1 / r ** 3)) return f, r, (lo, hi) def build(): """[(class, id, f, a, b, root)] and the number of redraws per class.""" from scipy.optimize._tstutils import _ORIGINAL_TESTS_DICTS out, redraws = [], {} for i, d in enumerate(_ORIGINAL_TESTS_DICTS): a, b = d["bracket"] args = d.get("args", ()) f = (lambda ff, aa: lambda x: ff(x, *aa))(d["f"], args) out.append(("C0", f"C0.{i:02d}", f, float(a), float(b), float(d["root"]))) rng = np.random.default_rng(SEED) for cls, gen in (("C1", _c1), ("C2", _c2), ("C3", _c3), ("C4", _c4), ("C5", _c5)): n = red = 0 while n < PER_CLASS: f, r, (a, b) = gen(rng) if _ok(f, a, b) and min(a, b) < r < max(a, b): out.append((cls, f"{cls}.{n:02d}", f, float(a), float(b), float(r))) n += 1 else: red += 1 redraws[cls] = red return out, redraws if __name__ == "__main__": probs, red = build() from collections import Counter print("problems per class:", dict(Counter(p[0] for p in probs)), " redraws:", red)