III-39 · Reproducibility and Numerical Reliability

Reproduce the procedure, then question its arithmetic

Replay exact group assignments and inspect two numerical counterexamples that a random seed cannot fix.

Chapters in Part VIII
  1. III-35 · Cross-Validation and Hyperparameter Tuning
  2. III-36 · Learning Curves and Model Selection
  3. III-37 · Class Imbalance, Calibration and Metric Choice
  4. III-38 · Preprocessing, Feature Engineering and Pipelines
  5. III-39 · Reproducibility and Numerical Reliability

Part VIII · experimental workflow sheet

Replay the experiment; inspect arithmetic limits

Hand-authored synthetic rows; seed controls group assignment only, never data generation. Data version p08-hand-v1. Edits are recorded in the displayed state. Probability rows are a separate hand-authored forecast example.

Split and workflow
Regression row editor
Binary64 counterexamples

Workflow phase 1 / 5. Replay preserves immutable states; edits fork the displayed frame. Revealing the test is the final step: do not tune after seeing it.

Raw X / engineered X / yObservations are mathematical columns; batch stores their transpose in rows. Missing raw values use null.
12 × 1 / n × 1 / n × 1
ParametersSelected on equal-weight CV MSE; intercept unpenalized; exact ties use first grid candidate.
power=2, λ=0
Test groupGroup allocation uses only IDs/groups and seed. Test values never fit preprocessing, select a model or enter a curve.
f
Data and RNGHand-authored rows. Seed controls only group shuffle. Full displayed JSON records edited values.
p08-hand-v1
LCG draws (u32)1664525·state + 1013904223 mod 2³²; Fisher–Yates draws descending.
1025555898, 3923423697, 2630631676, 3981355051, 211918734
Numerical limitsOverflow and underflow to zero reject the edit. Constant transformed features use scale 1 and zero slope when λ=0.
binary64; finite arithmetic required
Experimental workflow, active phase 1 of five12345
1 Split → 2 Fold fits → 3 Select → 4 Development refit → 5 Final test. Active phase 1; replay exposes each step.
Locked group split; no stratification is claimed
RoleIDs
Developmenta1, a2, b1, b2, c1, c2, d1, d2, e1, e2
Untouched testf1, f2
Fold 1Train: b1, b2, c1, c2, d1, d2
Validation: a1, a2, e1, e2
Fold 2Train: a1, a2, c1, c2, e1, e2
Validation: b1, b2, d1, d2
Fold 3Train: a1, a2, b1, b2, d1, d2, e1, e2
Validation: c1, c2
J(w,b)=1n∑i(b+wϕi−yi)2+λw2,CV=1K∑kMSEkJ(w,b)=\frac1n\sum_i(b+w\phi_i-y_i)^2+\lambda w^2,\quad \mathrm{CV}=\frac1K\sum_k\mathrm{MSE}_k
Actual fitted candidates; exact ties retain first row; chosen p=2, λ=0
Power / λTraining MSE / objective per foldValidation MSE per foldCV mean
1 / 01.014912 / 1.014912; 7.194625 / 7.194625; 4.668608 / 4.66860822.674681; 5.666231; 12.98572813.775547
1 / 11.212573 / 1.410234; 7.26576 / 7.336896; 4.945792 / 5.22297620.408144; 6.092143; 11.98497312.82842
1 / 41.520924 / 1.647427; 7.376731 / 7.422258; 5.378199 / 5.55559720.313584; 6.369024; 11.40897112.697193
2 / 01.457512 / 1.457512; 1.85763 / 1.85763; 1.162242 / 1.1622423.363659; 2.193051; 0.4401481.998953
2 / 11.539146 / 1.626071; 4.218731 / 5.500845; 3.103842 / 4.1556828.981694; 3.784647; 5.701456.15593
2 / 41.674595 / 1.732384; 6.215624 / 6.807238; 4.742027 / 5.22685415.244768; 5.467973; 9.0289079.913883

Selected candidate · fold 1

Transform fit IDs
b1, b2, c1, c2, d1, d2
Impute / center / scale
−0.4 / −0.4 / 0.974679
Model fit IDs
b1, b2, c1, c2, d1, d2
Intercept / slope
1.094953 / 0.571713
Training MSE / objectiveObjective adds λw²; validation uses MSE alone.
1.457512 / 1.457512
Validation rows transformed with the inspected training fit
IDFilled / z / φTarget / predictionSquared error
a1−3 / −2.667544 / 7.1157898 / 5.1631468.04774
a2−2.5 / −2.154555 / 4.6421056 / 3.7489075.067418
e12 / 2.462348 / 6.0631584 / 4.5613420.315105
e22.5 / 2.975337 / 8.8526326 / 6.1561220.024374
t2+1−t=1t2+1+t\sqrt{t^2+1}-t=\frac1{\sqrt{t^2+1}+t}
(10¹⁶−10¹⁶)+1
1
10¹⁶+(−10¹⁶+1)
0
Fragile root subtraction
0
Stable rationalized expression
5.000000e-9
Represented (1+δ)−1
1.000000e-8
1 / represented difference
1.000000e+8
1 / nominal δ
1.000000e+8
Subtraction condition estimate
2.000000e+8

Stable rearrangement fixes cancellation in the first problem. It cannot remove sensitivity of 1/(a−b) when a and b nearly agree: relative input errors can be amplified by (|a|+|b|)/|a−b|. Nominal δ and represented spacing differ. A seed does not fix arithmetic order or missing environment provenance.

Complete experiment provenance and parameters
{
  "state": {
    "rows": [
      {
        "id": "a1",
        "group": "a",
        "x": [
          -3
        ],
        "y": 8
      },
      {
        "id": "a2",
        "group": "a",
        "x": [
          -2.5
        ],
        "y": 6
      },
      {
        "id": "b1",
        "group": "b",
        "x": [
          -2
        ],
        "y": 4
      },
      {
        "id": "b2",
        "group": "b",
        "x": [
          null
        ],
        "y": 3
      },
      {
        "id": "c1",
        "group": "c",
        "x": [
          -1
        ],
        "y": 1
      },
      {
        "id": "c2",
        "group": "c",
        "x": [
          -0.5
        ],
        "y": 0.5
      },
      {
        "id": "d1",
        "group": "d",
        "x": [
          0.5
        ],
        "y": 0.5
      },
      {
        "id": "d2",
        "group": "d",
        "x": [
          1
        ],
        "y": 1
      },
      {
        "id": "e1",
        "group": "e",
        "x": [
          2
        ],
        "y": 4
      },
      {
        "id": "e2",
        "group": "e",
        "x": [
          2.5
        ],
        "y": 6
      },
      {
        "id": "f1",
        "group": "f",
        "x": [
          3
        ],
        "y": 8
      },
      {
        "id": "f2",
        "group": "f",
        "x": [
          4
        ],
        "y": 15
      }
    ],
    "probabilities": [
      {
        "id": "m1",
        "y": 0,
        "p": 0.1
      },
      {
        "id": "m2",
        "y": 0,
        "p": 0.2
      },
      {
        "id": "m3",
        "y": 0,
        "p": 0.3
      },
      {
        "id": "m4",
        "y": 0,
        "p": 0.4
      },
      {
        "id": "m5",
        "y": 0,
        "p": 0.6
      },
      {
        "id": "m6",
        "y": 0,
        "p": 0.8
      },
      {
        "id": "m7",
        "y": 1,
        "p": 0.5
      },
      {
        "id": "m8",
        "y": 1,
        "p": 0.9
      }
    ],
    "seed": 7,
    "threshold": 0.5,
    "folds": 3,
    "phase": 0,
    "t": 100000000,
    "delta": 1e-8
  },
  "provenance": {
    "dataVersion": "p08-hand-v1",
    "data": "Hand-authored synthetic rows; seed controls group assignment only, never data generation.",
    "seed": 7,
    "folds": 3,
    "threshold": 0.5,
    "model": "scalar engineered-feature ridge with intercept",
    "grid": [
      [
        1,
        0
      ],
      [
        1,
        1
      ],
      [
        1,
        4
      ],
      [
        2,
        0
      ],
      [
        2,
        1
      ],
      [
        2,
        4
      ]
    ],
    "split": "UTF-16 sorted groups; Fisher–Yates descending; u32 LCG; first group test; remaining round-robin CV",
    "selection": "equal-weight mean fold MSE; first grid candidate on exact ties",
    "arithmetic": "constant-preserving binary64 sequential mean of divided terms"
  },
  "board": {
    "groups": [
      "f",
      "a",
      "d",
      "c",
      "e",
      "b"
    ],
    "draws": [
      1025555898,
      3923423697,
      2630631676,
      3981355051,
      211918734
    ],
    "development": [
      "a1",
      "a2",
      "b1",
      "b2",
      "c1",
      "c2",
      "d1",
      "d2",
      "e1",
      "e2"
    ],
    "test": [
      "f1",
      "f2"
    ],
    "folds": [
      {
        "train": [
          "b1",
          "b2",
          "c1",
          "c2",
          "d1",
          "d2"
        ],
        "validation": [
          "a1",
          "a2",
          "e1",
          "e2"
        ]
      },
      {
        "train": [
          "a1",
          "a2",
          "c1",
          "c2",
          "e1",
          "e2"
        ],
        "validation": [
          "b1",
          "b2",
          "d1",
          "d2"
        ]
      },
      {
        "train": [
          "a1",
          "a2",
          "b1",
          "b2",
          "d1",
          "d2",
          "e1",
          "e2"
        ],
        "validation": [
          "c1",
          "c2"
        ]
      }
    ]
  },
  "selected": {
    "power": 2,
    "penalty": 0
  },
  "developmentFit": {
    "trainIds": [
      "a1",
      "a2",
      "b1",
      "b2",
      "c1",
      "c2",
      "d1",
      "d2",
      "e1",
      "e2"
    ],
    "preprocessing": {
      "fitIds": [
        "a1",
        "a2",
        "b1",
        "b2",
        "c1",
        "c2",
        "d1",
        "d2",
        "e1",
        "e2"
      ],
      "impute": -0.33333333333333326,
      "center": -0.33333333333333326,
      "scale": 1.760681686165901,
      "constant": false
    },
    "power": 2,
    "penalty": 0,
    "featureMean": 1,
    "targetMean": 3.3999999999999995,
    "slope": 2.3884696016771483,
    "intercept": 1.0115303983228512,
    "convention": "unpenalized intercept; mean squared error + lambda*slope^2; zero slope if unidentifiable",
    "trainingMse": 1.5133272093355263,
    "objective": 1.5133272093355263
  }
}

Replay preserves detached immutable experimental states. The provenance record describes data, parameters, transform order, model convention, split draws and arithmetic.

Repeat an experiment, not just a seed

Change the split seed, note the group order and u32 draws, then enter the same seed again. With identical rows and configuration, the same group allocation, selected parameters and numerical fits return. The observations were hand-authored; the seed controls group assignment only. Changing an observation while keeping the seed defines a different experiment.

Open Complete experiment provenance and parameters. It includes the entire displayed input state, data version, grid, selection rule, split convention and development model with transform membership. Replay selects immutable historical states; it does not perform inverse updates. Edit a target at a replay frame to fork that displayed experiment, then reset to recover the canonical rows and seed 7. All operations are synchronous and local.

The exact random mechanism

The shared generator stores an unsigned 32-bit state s. Every draw performs

sj+1=(1664525sj+1013904223) mod 232,uj=sj+1/232.s_{j+1}=(1664525s_j+1013904223)\bmod2^{32},\qquad u_j=s_{j+1}/2^{32}.

Group IDs are sorted before shuffling. Descending Fisher–Yates swaps position i with j=⌊u(i+1)⌋ for i=g−1,…,1. The first shuffled group is locked test. Remaining groups go round-robin into validation folds. Row order in membership tables follows input row order. Exact grid ties retain the first candidate, ordered by power then penalty. These details belong with the seed; choosing another PRNG or consuming an extra draw changes the experiment.

A small hand-check starts at seed 0: the first unsigned update is 1013904223. With two groups [a,b], i=1 and j=⌊2·1013904223/4294967296⌋=0, so the order becomes [b,a]. The same arithmetic must be reproduced with integer semantics in Python; arbitrary floating multiplication of large RNG states is not the contract. This tiny shuffle example explains the mechanism; the board requires enough groups for training, validation and test.

What an experiment record must carry

Record source/data versions and exact values, missing-value conventions, membership and group assumptions, the model family, feature order, objective normalization, parameter grid, selection metric, tie-breaking, chosen parameters and final fitted state. Record the evaluation threshold and probability-bin convention separately. A deployment record also needs actual runtime/library versions, hardware, thread/reduction settings and environment details. This board documents its binary64 algorithm but does not pretend a browser can capture every machine’s environment or promise cross-platform bitwise identity.

A standard library pipeline can be compared to this lab by matching mean imputation, population scaling, scalar feature power, unpenalized intercept and ridge normalization. Libraries may define ridge as SSE+αw² rather than MSE+λw², in which case α=nλ for a given fit. Matching names without matching conventions is not a valid numerical comparison. The owner-authored oracle instead uses an augmented least-squares system and exact rational calculations; the canonical code remains visible.

Binary64 addition is not associative

In exact arithmetic both parenthesizations below equal 1:

(1016+(−1016))+1,1016+((−1016)+1).(10^{16}+(-10^{16}))+1,\qquad 10^{16}+((-10^{16})+1).

In binary64, spacing near 10¹⁶ is 2. The inner −10¹⁶+1 rounds to −10¹⁶ under ties-to-even, so the right expression becomes 0. The left cancels exactly first and then adds 1. The board computes both expressions; it does not display a pre-drawn claim about them.

Parallel reductions can change addition order. A seed fixes pseudorandom draws, not the schedule of a reduction. Deterministic algorithms need a declared arithmetic order as well. Our mean sums terms divided by n sequentially; this avoids some sum overflow but cannot remove all representation error. A reproducibility tolerance must be justified by the quantity’s conditioning, not widened until unrelated answers pass.

Stable algebra addresses cancellation

The positive expression √(t²+1)−t suffers subtraction of nearly equal large numbers. Rationalization gives

t2+1−t=1t2+1+t.\sqrt{t^2+1}-t=\frac{1}{\sqrt{t^2+1}+t}.

At t=10⁸, t²+1 rounds to t². The fragile calculation yields 0. The stable expression yields approximately 5×10⁻⁹, retaining the small result without subtracting two nearly equal roots. The identity follows by multiplying numerator and denominator by √(t²+1)+t, because the numerator becomes (t²+1)−t²=1 in exact algebra.

Move t toward 1 and inspect both computed values, then restore 10⁸. The stable rearrangement addresses the algorithm’s cancellation; its root and input representation still use binary64. The lab bounds t at 10¹² so this particular demonstration cannot overflow t². It rejects overflow or underflow to zero in model arithmetic instead of producing fabricated finite scores.

Conditioning is a property of the question

Now consider 1/(a−b), a=1+δ and b=1. If a and b nearly agree, tiny relative input errors can produce a large relative change in the difference. A subtraction condition estimate is

κ=∣a∣+∣b∣∣a−b∣.\kappa=\frac{|a|+|b|}{|a-b|}.

For δ near 10⁻⁸, κ is about 2×10⁸. The stored binary64 value 1+δ is already rounded; (1+δ)−1 is not necessarily the nominal δ. The board compares reciprocal represented spacing with 1/δ. A stable algorithm cannot infer the intended exact inputs from rounded values. Measuring a and b more precisely, rescaling a model, or reformulating the scientific question may matter more than another solver.

This lab keeps δ between 10⁻¹² and .1 so its represented difference is nonzero. It reports the sensitivity honestly rather than claiming its rearranged expression makes every nearby problem reliable.

Canonical execution and numerical contracts

X and y use n×1 batches; one mathematical weight is 1×1 and the intercept is scalar. Canonical Python validates real values before NumPy conversion, rejecting Booleans, nonfinite numbers, malformed shapes and duplicate IDs. TypeScript additionally rejects sparse array holes. Intermediate arithmetic must remain representable; undefined metric denominators carry reasons. Inputs are not silently clipped and seeds must be integral u32 values.

code/python/p08/evaluation.py
"""Canonical bounded evaluation lab. X: n×1 rows; y: n×1; one slope + intercept.

Hand data, LCG-seeded group allocation. No claim of stratification. Owner runs tests.
"""
import json
import math
import numbers
import sys
from pathlib import Path
import numpy as np

ROOT = Path(__file__).resolve().parents[3]
DATA = json.loads((ROOT / "data/p08/experiments.json").read_text())
DEFAULT = dict(rows=DATA["rows"], probabilities=DATA["probabilities"], seed=7,
               threshold=.5, folds=3, phase=0, t=1e8, delta=1e-8)
GRID = [(power, penalty) for power in (1, 2) for penalty in (0, 1, 4)]


def number(v, name="number"):
    if isinstance(v, (bool, np.bool_)) or not isinstance(v, numbers.Real):
        raise ValueError(name + " must be a real number, not Boolean")
    try:
        v = float(v)
    except (OverflowError, ValueError):
        raise ValueError(name + " is not binary64 representable") from None
    if not math.isfinite(v):
        raise ValueError(name + " must be finite")
    return v


def finite(v):
    if not math.isfinite(v):
        raise ValueError("Numerical result unavailable: binary64 overflow")
    return v


def mul(a, b):
    v = finite(a * b)
    if a != 0 and b != 0 and v == 0:
        raise ValueError("Numerical result unavailable: product underflow")
    return v


def div(a, b):
    if b == 0:
        raise ValueError("Numerical result unavailable: zero divisor")
    v = finite(a / b)
    if a != 0 and v == 0:
        raise ValueError("Numerical result unavailable: quotient underflow")
    return v


def mean(values):
    if not values:
        raise ValueError("Mean needs observations")
    if all(v == values[0] for v in values):
        return values[0]
    total = 0.
    for v in values:
        total = finite(total + div(v, len(values)))
    return total


def integer(v, low, high, name):
    v = number(v, name)
    if not v.is_integer() or not low <= v <= high:
        raise ValueError(name + " must be an integer in bounds")
    return int(v)


def identifiers(rows):
    ids = set()
    for r in rows:
        if not isinstance(r, dict) or not isinstance(r.get("id"), str) or not r["id"] or r["id"] in ids:
            raise ValueError("Unique nonempty row IDs required")
        ids.add(r["id"])


def validate(s):
    if not isinstance(s, dict):
        raise ValueError("Experiment must be an object")
    rows, probs = s.get("rows"), s.get("probabilities")
    if not isinstance(rows, list) or not 8 <= len(rows) <= 64:
        raise ValueError("8–64 dense regression rows required")
    if not isinstance(probs, list) or not 1 <= len(probs) <= 64:
        raise ValueError("1–64 dense probability rows required")
    identifiers(rows)
    identifiers(probs)
    for r in rows:
        if not isinstance(r.get("group"), str) or not r["group"]:
            raise ValueError("Nonempty group required")
        if not isinstance(r.get("x"), list) or len(r["x"]) != 1:
            raise ValueError("X must contain dense one-feature rows")
        if r["x"][0] is not None:
            number(r["x"][0], "feature")
        number(r.get("y"), "target")
    for r in probs:
        if number(r.get("y"), "binary label") not in (0, 1) or not 0 <= number(r.get("p"), "probability") <= 1:
            raise ValueError("Binary label and probability in [0,1] required")
    integer(s.get("seed"), 0, 2**32-1, "seed")
    integer(s.get("folds"), 2, 4, "folds")
    integer(s.get("phase"), 0, 4, "phase")
    if not 0 <= number(s.get("threshold"), "threshold") <= 1:
        raise ValueError("Threshold in [0,1] required")
    if not 1 <= number(s.get("t"), "t") <= 1e12 or not 1e-12 <= number(s.get("delta"), "delta") <= .1:
        raise ValueError("Numerical counterexample parameters out of bounds")


def split(rows, seed, folds):
    if not isinstance(rows, list) or not rows:
        raise ValueError("Dense regression rows required")
    identifiers(rows)
    seed = integer(seed, 0, 2**32-1, "seed")
    folds = integer(folds, 2, 4, "folds")
    for r in rows:
        if not isinstance(r.get("group"), str) or not r["group"]:
            raise ValueError("Nonempty group required")
    groups = sorted(set(r["group"] for r in rows), key=lambda g: g.encode("utf-16-be", "surrogatepass"))
    if len(groups) < folds + 2:
        raise ValueError("Need at least folds+2 groups")
    state = int(seed)
    draws = []
    for i in range(len(groups)-1, 0, -1):
        state = (1664525 * state + 1013904223) % 2**32
        draws.append(state)
        j = state * (i+1) // 2**32
        groups[i], groups[j] = groups[j], groups[i]
    test_group, dev_groups = groups[0], groups[1:]
    test = [r["id"] for r in rows if r["group"] == test_group]
    dev = [r["id"] for r in rows if r["group"] != test_group]
    boards = []
    for k in range(folds):
        held = dev_groups[k::folds]
        boards.append(dict(train=[r["id"] for r in rows if r["group"] in dev_groups and r["group"] not in held],
                           validation=[r["id"] for r in rows if r["group"] in held]))
    return dict(groups=groups, draws=draws, development=dev, test=test, folds=boards)


def take(rows, ids):
    if not isinstance(rows, list) or not 1 <= len(rows) <= 64 or not isinstance(ids, list):
        raise ValueError("Dense rows and membership arrays required")
    identifiers(rows)
    lookup = {r["id"]: r for r in rows}
    if not ids or len(set(ids)) != len(ids) or any(i not in lookup for i in ids):
        raise ValueError("Membership requires unique known IDs")
    return [lookup[i] for i in ids]


def transform_fit(rows, ids):
    selected = take(rows, ids)
    for r in selected:
        if not isinstance(r.get("x"), list) or len(r["x"]) != 1:
            raise ValueError("Dense one-feature row required")
    observed = [number(r["x"][0]) for r in selected if r["x"][0] is not None]
    impute = mean(observed)
    filled = [impute if r["x"][0] is None else number(r["x"][0]) for r in selected]
    center = mean(filled)
    variance = mean([mul(finite(v-center), finite(v-center)) for v in filled])
    scale = math.sqrt(variance) if variance > 0 else 1.
    return dict(fitIds=list(ids), impute=impute, center=center, scale=scale, constant=variance == 0)


def transform(row, state, power):
    if not isinstance(row, dict) or not isinstance(row.get("x"), list) or len(row["x"]) != 1:
        raise ValueError("Dense one-feature row required")
    integer(power, 1, 2, "power")
    number(state["impute"]); number(state["center"])
    if number(state["scale"]) <= 0:
        raise ValueError("Positive fitted scale required")
    filled = state["impute"] if row["x"][0] is None else number(row["x"][0])
    z = div(finite(filled-state["center"]), state["scale"])
    feature = z if power == 1 else mul(z, z)
    return dict(id=row["id"], filled=filled, z=z, feature=feature)


def fit(rows, train_ids, power, penalty, fit_ids=None):
    power = integer(power, 1, 2, "power")
    penalty = number(penalty, "penalty")
    if penalty < 0:
        raise ValueError("Nonnegative ridge penalty required")
    pre = transform_fit(rows, train_ids if fit_ids is None else fit_ids)
    selected = take(rows, train_ids)
    features = [transform(r, pre, power)["feature"] for r in selected]
    targets = [number(r["y"]) for r in selected]
    # NumPy holds the declared row batches; arithmetic order matches the browser contract.
    X, y = np.asarray(features, dtype=np.float64).reshape(-1, 1), np.asarray(targets, dtype=np.float64).reshape(-1, 1)
    fm, ym = mean(X[:, 0].tolist()), mean(y[:, 0].tolist())
    dx, dy = [finite(v-fm) for v in features], [finite(v-ym) for v in targets]
    variance = mean([mul(v, v) for v in dx])
    covariance = mean([mul(a, b) for a, b in zip(dx, dy)])
    denominator = finite(variance + penalty)
    slope = div(covariance, denominator) if denominator else 0.
    intercept = finite(ym - mul(slope, fm))
    model = dict(trainIds=list(train_ids), preprocessing=pre, power=power, penalty=penalty,
                 featureMean=fm, targetMean=ym, slope=slope, intercept=intercept,
                 convention="unpenalized intercept; mean squared error + lambda*slope^2; zero slope if unidentifiable")
    training = evaluate(rows, train_ids, model)
    model.update(trainingMse=training["mse"], objective=finite(training["mse"] + mul(penalty, mul(slope, slope))))
    return model


def evaluate(rows, ids, model):
    evaluated = []
    for r in take(rows, ids):
        transformed = transform(r, model["preprocessing"], model["power"])
        prediction = finite(model["intercept"] + mul(model["slope"], transformed["feature"]))
        residual = finite(prediction-number(r["y"]))
        evaluated.append(dict(transformed, target=number(r["y"]), prediction=prediction,
                              residual=residual, squaredError=mul(residual, residual)))
    return dict(ids=list(ids), rows=evaluated, mse=mean([r["squaredError"] for r in evaluated]))


def metrics(rows, threshold):
    if not isinstance(rows, list) or not 1 <= len(rows) <= 64:
        raise ValueError("1–64 dense probability rows required")
    identifiers(rows)
    threshold = number(threshold)
    if not rows or not 0 <= threshold <= 1:
        raise ValueError("Nonempty probability rows and threshold in [0,1] required")
    tp = fp = tn = fn = 0
    errors, logs = [], []
    decisions = []
    bins = [dict(low=i/5, high=(i+1)/5, ids=[], count=0, meanProbability=None, frequency=None) for i in range(5)]
    for r in rows:
        y, p = number(r.get("y")), number(r.get("p"))
        if y not in (0, 1) or not 0 <= p <= 1:
            raise ValueError("Binary label and probability required")
        positive = p >= threshold
        tp += int(positive and y == 1); fp += int(positive and y == 0)
        tn += int(not positive and y == 0); fn += int(not positive and y == 1)
        errors.append(mul(p-y, p-y))
        decisions.append(dict(id=r["id"], y=y, p=p, positive=positive, squaredError=errors[-1]))
        q = p if y else 1-p
        if q == 0:
            logs.append(None)
        else:
            logs.append(finite(-math.log(q)))
        b = next(b for b in bins if p >= b["low"] and (p < b["high"] or b["high"] == 1))
        b["ids"].append(r["id"])
    for b in bins:
        selected = [r for r in rows if r["id"] in b["ids"]]
        b["count"] = len(selected)
        if selected:
            b["meanProbability"] = mean([number(r["p"]) for r in selected])
            b["frequency"] = mean([number(r["y"]) for r in selected])
    ratio = lambda a, b: a/b if b else None
    recall, specificity = ratio(tp, tp+fn), ratio(tn, tn+fp)
    return dict(rows=decisions, tp=tp, fp=fp, tn=tn, fn=fn, accuracy=(tp+tn)/len(rows),
                balancedAccuracy=(recall+specificity)/2 if recall is not None and specificity is not None else None,
                precision=ratio(tp, tp+fp), recall=recall, f1=ratio(2*tp, 2*tp+fp+fn),
                brier=mean(errors), logLoss=mean(logs) if None not in logs else None,
                logReason="Unbounded log loss: a true class has probability zero" if None in logs else None, bins=bins)


def numerics(t, delta):
    t, delta = number(t), number(delta)
    if not 1 <= t <= 1e12 or not 1e-12 <= delta <= .1:
        raise ValueError("Counterexample parameters out of bounds")
    root = math.sqrt(finite(mul(t, t)+1))
    rounded = finite(1 + delta)
    return dict(left=(1e16 + -1e16) + 1, right=1e16 + (-1e16 + 1),
                fragile=finite(root-t), stable=div(1, finite(root+t)),
                difference=finite(rounded-1), reciprocal=div(1, finite(rounded-1)),
                nominalReciprocal=div(1, delta), condition=div(abs(rounded)+1, abs(rounded-1)))


def experiment(s):
    validate(s)
    rows = s["rows"]
    board = split(rows, s["seed"], s["folds"])
    candidates = []
    for power, penalty in GRID:
        scores = []
        for fold in board["folds"]:
            model = fit(rows, fold["train"], power, penalty)
            validation = evaluate(rows, fold["validation"], model)
            scores.append(dict(model=model, validation=validation))
        candidates.append(dict(power=power, penalty=penalty, folds=scores,
                               meanValidation=mean([f["validation"]["mse"] for f in scores])))
    # Strict less-than: an exact tie retains the first (power ascending, penalty ascending).
    chosen = candidates[0]
    for c in candidates[1:]:
        if c["meanValidation"] < chosen["meanValidation"]:
            chosen = c
    final = fit(rows, board["development"], chosen["power"], chosen["penalty"])
    test = evaluate(rows, board["test"], final)
    fold = board["folds"][0]
    train_groups = [g for g in board["groups"][1:] if any(r["group"] == g and r["id"] in fold["train"] for r in rows)]
    curves = []
    for k in range(1, len(train_groups)+1):
        ids = [r["id"] for r in rows if r["group"] in train_groups[:k]]
        model = fit(rows, ids, chosen["power"], chosen["penalty"])
        curves.append(dict(n=len(ids), ids=ids, model=model, validation=evaluate(rows, fold["validation"], model)))
    proper = fit(rows, fold["train"], 1, 1)
    leaked = fit(rows, fold["train"], 1, 1, fold["train"]+fold["validation"])
    proper_score, leaked_score = evaluate(rows, fold["validation"], proper), evaluate(rows, fold["validation"], leaked)
    m = metrics(s["probabilities"], s["threshold"])
    tradeoff = [dict(threshold=t, **{k: v for k, v in metrics(s["probabilities"], t).items() if k in ("precision", "recall", "tp", "fp", "tn", "fn")})
                for t in sorted(set([0., 1.] + [number(r["p"]) for r in s["probabilities"]]))]
    return dict(board=board, candidates=candidates, selected=dict(power=chosen["power"], penalty=chosen["penalty"]),
                final=final, test=test, curves=curves, leakage=dict(proper=proper, leaked=leaked,
                properScore=proper_score, leakedScore=leaked_score, difference=finite(leaked_score["mse"]-proper_score["mse"])),
                metrics=m, tradeoff=tradeoff, numerics=numerics(s["t"], s["delta"]),
                provenance=dict(dataVersion=DATA["version"], data=DATA["provenance"], seed=s["seed"], folds=s["folds"],
                threshold=s["threshold"], model="scalar engineered-feature ridge with intercept", grid=[list(g) for g in GRID],
                split="UTF-16 sorted groups; Fisher–Yates descending; u32 LCG; first group test; remaining round-robin CV",
                selection="equal-weight mean fold MSE; first grid candidate on exact ties", arithmetic="constant-preserving binary64 sequential mean of divided terms"))


if __name__ == "__main__":
    try:
        request = json.load(sys.stdin) if not sys.stdin.isatty() else DEFAULT
        print(json.dumps(experiment(request), allow_nan=False))
    except (ValueError, TypeError, KeyError) as error:
        print(str(error), file=sys.stderr)
        sys.exit(1)

Connections and boundaries

The Book II prerequisite links cover representation, conditioning, cancellation and stable algorithms. The earlier chapters in this Part add sampling and leakage boundaries to arithmetic reliability. The bounded board implements no distributed trainer, environment lockfile generator or production model registry. It exposes the minimum complete experiment so those larger systems can be judged against concrete semantics.

Five graded decisions

Does recording seed 7 alone define this experiment?
What is the first u32 update from seed 0?
What does binary64 compute for the two 10¹⁶ addition orders?
Which expression avoids the t=10⁸ root subtraction?
Does a stable algorithm remove sensitivity when a≈b in 1/(a−b)?

What you can now explain

You can replay a fully specified seeded procedure, record transform and model provenance, calculate a nonassociativity counterexample and separate avoidable cancellation from input conditioning. Together with III-35 through III-38, these habits turn fitting into an inspectable experiment whose limits remain explicit.