fuzzyworld

explodorama / files / tools / balance / stats.ts

stats.ts

Blame: the commit that last changed each line · file · history

d3e4ed26 2026-10-25 Pavel Safronov1/** Mean and a 95% confidence interval's half-width, for paired differences and plain samples. */
2export interface Estimate {
3 mean: number
4 /** Half the 95% interval: the true mean is within mean ± ci, 19 times in 20. */
5 ci: number
6 n: number
7}
8
9export function estimate(xs: number[]): Estimate {
10 const n = xs.length
11 if (!n) return { mean: 0, ci: 0, n }
12 const mean = xs.reduce((a, b) => a + b, 0) / n
13 const variance = n > 1 ? xs.reduce((a, x) => a + (x - mean) ** 2, 0) / (n - 1) : 0
14 return { mean, ci: 1.96 * Math.sqrt(variance / n), n }
15}
16
17/** "+1.2 ± 0.3", or "+1.2 ± 0.3 ✱" when the interval leaves out 0 (a real difference). */
18export function signed(e: Estimate, digits = 2): string {
19 const sign = e.mean > 0 ? '+' : e.mean < 0 ? '−' : ' '
20 const real = e.n > 1 && Math.abs(e.mean) > e.ci ? ' ✱' : ''
21 return `${sign}${Math.abs(e.mean).toFixed(digits)} ± ${e.ci.toFixed(digits)}${real}`
22}