wilson_interval

Function wilson_interval 

Source
pub fn wilson_interval(
    successes: u64,
    trials: u64,
    level: ConfidenceLevel,
) -> (f64, f64)
Expand description

Wilson score interval for a Bernoulli proportion at fixed n.

n == 0 returns (0.0, 1.0) – total ignorance, not an error: with zero trials nothing is known about the proportion beyond it lying in [0, 1], so the widest possible interval is the honest answer rather than a divide-by-zero or a panic.

successes above trials is not a domain error either: it saturates at trials (p = 1.0), so the call reports exactly the interval a fully-successful run of that size would. This is deliberate, not merely tolerated: for p only just above 1.0 the radicand below does not reliably go negative (z^2/(4n^2) can outweigh a small negative p(1-p)/n), so an unclamped implementation would silently return a plausible-looking wrong interval rather than a loud NaN – saturating p at the input removes that failure mode entirely instead of documenting around it.

Unlike the naive Wald interval (p +- z * sqrt(p(1-p)/n)), the Wilson interval stays inside [0, 1] and has correct coverage even at small n or p near 0 or 1 – exactly the regime a hit-probability Monte Carlo run starts in before enough trials have accumulated. Computed directly in “center +- spread” form (Wilson 1927; worked example in Newcombe 1998, cross-checked by this module’s tests):

center = (p + z^2 / (2n)) / (1 + z^2 / n)
spread = (z / (1 + z^2 / n)) * sqrt(p(1-p)/n + z^2/(4n^2))

where p = min(successes / trials, 1.0) and z is ConfidenceLevel::z. The result is additionally clamped to [0, 1]: floating-point rounding in center +- spread can overshoot by up to a few ULP right at the p == 0 / p == 1 edges, and a probability bound outside [0, 1] is a worse answer than one that is merely maximally uninformative.