Small stats helpers used by the box-plot, Q-Q, and histogram routines. Intentionally narrow — this is not a general stats library.
Summary
Functions
Computes a box-plot summary — quartiles plus Tukey fences for whisker
endpoints. Outliers are observations beyond 1.5·IQR (default).
Arithmetic mean of the finite values. Empty input returns 0.0.
Inverse standard-normal CDF (probit). Uses the Beasley-Springer / Moro approximation — accurate to about 1e-9 across the usual range.
Linearly-interpolated quantile (type-7, R's default). p is in
[0, 1].
quantile/2 for input that is already sorted ascending.
Sample standard deviation, Bessel-corrected (n-1). Fewer than two
observations returns 0.0.
Standard error of the mean: sample_std / sqrt(n).
Inverse Student-t CDF for df degrees of freedom.
Functions
Computes a box-plot summary — quartiles plus Tukey fences for whisker
endpoints. Outliers are observations beyond 1.5·IQR (default).
Returns %{min, q1, median, q3, max, outliers} where min/max are
the whisker endpoints (not the raw extrema — those are captured in
:outliers).
iex> s = Bland.Stats.boxplot_stats([1, 2, 3, 4, 5, 6, 7, 100])
iex> {s.median, length(s.outliers)}
{4.5, 1}
Arithmetic mean of the finite values. Empty input returns 0.0.
iex> Bland.Stats.mean([1, 2, 3, 4])
2.5
Inverse standard-normal CDF (probit). Uses the Beasley-Springer / Moro approximation — accurate to about 1e-9 across the usual range.
iex> abs(Bland.Stats.normal_quantile(0.5)) < 1.0e-9
true
iex> Float.round(Bland.Stats.normal_quantile(0.975), 4)
1.96
Linearly-interpolated quantile (type-7, R's default). p is in
[0, 1].
iex> Bland.Stats.quantile([1, 2, 3, 4, 5], 0.5)
3.0
quantile/2 for input that is already sorted ascending.
Callers computing several quantiles of the same sample — boxplot_stats/2
wants three — should sort once and come through here rather than paying
for a sort per quantile.
iex> Bland.Stats.quantile_sorted([1, 2, 3, 4, 5], 0.25)
2.0
Sample standard deviation, Bessel-corrected (n-1). Fewer than two
observations returns 0.0.
iex> Bland.Stats.sample_std([2, 4, 4, 4, 5, 5, 7, 9])
2.138089935299395
Standard error of the mean: sample_std / sqrt(n).
iex> Float.round(Bland.Stats.sem([1, 2, 3, 4, 5]), 6)
0.707107
@spec student_t_quantile(number(), non_neg_integer()) :: float() | nil
Inverse Student-t CDF for df degrees of freedom.
Exact for df <= 2; a Cornish-Fisher expansion above that, which sits
within about 5e-3 of the true quantile at df = 3 and tightens rapidly
— ample for sizing an error bar. df of 0 falls back to the normal
quantile. Returns nil outside (0, 1), matching normal_quantile/1.
iex> Float.round(Bland.Stats.student_t_quantile(0.975, 10), 3)
2.228