March Docs

Stats

Stats module: descriptive statistics on List(Float).

All functions are pure — no side effects. Primary input type: List(Float).

Functions that require non-empty input panic on empty list. sum and count always succeed (return 0.0 / 0 for empty).

Design: all sorting uses List.sort_by with Float comparison. Variance uses Welford's online algorithm for numerical stability.

Types

typeQuantileMethodQuantileMethod =#

Functions

fncorrelationcorrelation(xs : {List(Float) | len(_) >= 2},#

Pearson correlation coefficient. Returns value in [-1, 1]. Panics if lists have different lengths, fewer than 2 elements, or if either list has zero standard deviation.

The two *structural* preconditions are declared in the signature (`xs` has at
least 2 elements; `ys` has exactly as many as `xs`), so a provable violation
of either is a compile error. The zero-standard-deviation panic is
data-dependent — it turns on the `Float` *values* in the lists, not on their
shape — so no measure can express it and it stays a runtime check.
fncountcount(xs : List(Float)) : Int#

Number of elements.

fncovariancecovariance(xs : {List(Float) | len(_) >= 2},#

Sample covariance of two equal-length lists. Panics if lengths differ or if either list has fewer than 2 elements.

Both structural preconditions are declared in the signature — `xs` must have
at least 2 elements and `ys` must have exactly as many as `xs` — so a call the
compiler can prove violates either is a compile error rather than a runtime
panic. Lengths it cannot relate are accepted in silence (March reports only
definite failures) and the `panic`s below remain the runtime backstop.
fnfive_number_summaryfive_number_summary(xs : {List(Float) | len(_) > 0}, method : QuantileMethod) : (Float, Float, Float, Float, Float)#

Five-number summary with selectable method: (min, Q1, median, Q3, max). Panics on empty list.

fniqriqr(xs : List(Float), method : QuantileMethod) : Float#

Interquartile range: Q3 − Q1 using the given method.

Uses the same sorted list for both quartiles (one sort, not two).
Panics on empty input.
fniqr_defaultiqr_default(xs : List(Float)) : Float#

Interquartile range using Linear (Type 7) interpolation.

fnlinear_regressionlinear_regression(xs : {List(Float) | len(_) >= 2},#

Simple linear regression: y = slope * x + intercept. Returns (slope, intercept). Panics if lists have different lengths or fewer than 2 elements, or if xs has zero variance (vertical line).

The two *structural* preconditions are declared in the signature (`xs` has at
least 2 points; `ys` has exactly as many as `xs`), so a provable violation of
either is a compile error. The zero-variance panic is data-dependent — it
turns on the `Float` *values* in `xs`, not on their shape — so no measure can
express it and it stays a runtime check.
fnmax_safemax_safe(xs : List(Float)) : Result(Float, String)#

Maximum value, returning Err on empty list.

fnmax_valmax_val(xs : {List(Float) | len(_) > 0}) : Float#

Maximum value. Panics on empty list.

fnmeanmean(xs : {List(Float) | len(_) > 0}) : Float#

Arithmetic mean. Panics on empty list.

fnmean_safemean_safe(xs : List(Float)) : Result(Float, String)#

Mean, returning Err on empty list instead of panicking.

fnmedianmedian(xs : List(Float)) : Float#

Median (50th percentile). Panics on empty list.

fnmin_safemin_safe(xs : List(Float)) : Result(Float, String)#

Minimum value, returning Err on empty list.

fnmin_valmin_val(xs : {List(Float) | len(_) > 0}) : Float#

Minimum value. Panics on empty list.

fnmodemode(xs : {List(Float) | len(_) > 0}) : Float#

Mode: the most frequently occurring value. When there are ties, returns the first value encountered (in sorted order). Panics on empty list.

fnpercentilepercentile(xs : {List(Float) | len(_) > 0}, p : {Float | _ >= 0.0 && _ <= 100.0}) : Float#

Percentile using linear interpolation. p must be in [0.0, 100.0]. Panics on empty list or out-of-range p.

fnquantilequantile(xs : {List(Float) | len(_) > 0}, q : {Float | _ >= 0.0 && _ <= 1.0}, method : QuantileMethod) : Float#

Quantile at probability q ∈ [0.0, 1.0] using the given interpolation method. Panics on empty list or out-of-range q.

For a percentile-style API (q in 0..100), see `percentile`.  The
existing `percentile(xs, p)` is equivalent to
`quantile(xs, p / 100.0, Linear)`.
fnquantile_defaultquantile_default(xs : List(Float), q : Float) : Float#

Quantile with Linear interpolation (Type 7, R/numpy default). Convenience alias for quantile(xs, q, Linear).

fnquantilesquantiles(xs : {List(Float) | len(_) > 0}, qs : List(Float), method : QuantileMethod) : List(Float)#

Batched quantiles: returns [quantile(xs, q, method) for q in qs]. Sorts the input once and reuses it for each q.

fnstd_devstd_dev(xs : List(Float)) : Float#

Sample standard deviation. Returns 0.0 for single element. Panics on empty.

fnstd_dev_popstd_dev_pop(xs : List(Float)) : Float#

Population standard deviation.

fnstd_dev_safestd_dev_safe(xs : List(Float)) : Result(Float, String)#

Sample standard deviation, returning Err on empty or single-element list.

fnsumsum(xs : List(Float)) : Float#

Sum of all elements. Returns 0.0 for empty list.

fnvariancevariance(xs : {List(Float) | len(_) > 0}) : Float#

Sample variance (denominator n-1). Returns 0.0 for a single element. Panics on empty list.

Uses Welford's online algorithm for numerical stability on inputs
where the naive two-pass sum-of-squares would suffer catastrophic
cancellation (near-constant data, shifted distributions).
fnvariance_popvariance_pop(xs : List(Float)) : Float#

Population variance (denominator n). Returns 0.0 for a single element or empty list.

Uses Welford's online algorithm (same stability benefit as `variance`).
fnvariance_safevariance_safe(xs : List(Float)) : Result(Float, String)#

Sample variance, returning Err on empty list.