viva_math/statistics
Descriptive statistics over List(Float).
All functions are pure and operate on lists. For large datasets prefer
viva_tensor and stream reductions; this module targets emotion-scale
data (10²–10⁴ samples).
Numerical notes
- Variance uses Welford’s online algorithm (
welford) to avoid catastrophic cancellation.variance/1materialises the result. - Population (N) and sample (N-1) variants are provided where the distinction matters.
- Percentile uses linear interpolation between adjacent order statistics (NumPy-style “linear” method).
Types
Values
pub fn covariance(
xs: List(Float),
ys: List(Float),
) -> Result(Float, Nil)
Population covariance Cov(X, Y) = E[(X - μₓ)(Y - μᵧ)].
pub fn cumulative_product(xs: List(Float)) -> List(Float)
Running product [x₀, x₀·x₁, x₀·x₁·x₂, …].
pub fn cumulative_sum(xs: List(Float)) -> List(Float)
Running sum [x₀, x₀+x₁, x₀+x₁+x₂, …].
pub fn ema(
xs: List(Float),
alpha: Float,
) -> Result(List(Float), Nil)
Exponential moving average with smoothing factor α ∈ (0, 1].
Recurrence: yₜ = α·xₜ + (1-α)·yₜ₋₁, y₀ = x₀.
pub fn ema_step(
previous: Float,
observation: Float,
alpha: Float,
) -> Float
Single-step EMA update. Useful for streaming.
pub fn geometric_mean(xs: List(Float)) -> Result(Float, Nil)
Geometric mean: ⁿ√(∏ xᵢ). Requires strictly positive inputs.
pub fn harmonic_mean(xs: List(Float)) -> Result(Float, Nil)
Harmonic mean: n / Σ(1/xᵢ). Requires non-zero inputs.
pub fn kurtosis(xs: List(Float)) -> Result(Float, Nil)
Excess kurtosis via Pébay online accumulator. Zero for a Gaussian.
pub fn linear_space(
start: Float,
stop: Float,
steps: Int,
endpoint: Bool,
) -> List(Float)
n evenly-spaced values between start and stop.
endpoint = True: includesstop(mimics NumPylinspace(...)).endpoint = False: excludesstop(half-open, mimicsarange-like).n <= 0→[].n == 1→[start]regardless ofendpoint.
pub fn logarithmic_space(
start: Float,
stop: Float,
steps: Int,
endpoint: Bool,
base: Float,
) -> List(Float)
n values logarithmically spaced (in base) between base^start and
base^stop. endpoint follows the same convention as linear_space.
pub fn mean(xs: List(Float)) -> Result(Float, Nil)
Arithmetic mean using Neumaier-compensated sum.
pub fn median(xs: List(Float)) -> Result(Float, Nil)
Median (50th percentile). Linearly interpolates for even-length lists.
pub fn min_max_normalize(
xs: List(Float),
) -> Result(List(Float), Nil)
Min-max normalisation to [0, 1].
pub fn moving_average(
xs: List(Float),
window: Int,
) -> Result(List(Float), Nil)
Simple moving average over a sliding window of size window.
Output has length len(xs) - window + 1. Errors if window > len or < 1.
pub fn pearson(
xs: List(Float),
ys: List(Float),
) -> Result(Float, Nil)
Pearson correlation coefficient. Result in [-1, 1].
pub fn percentile(
xs: List(Float),
q: Float,
) -> Result(Float, Nil)
Percentile q ∈ [0, 1] using linear interpolation (NumPy default).
pub fn quartiles(
xs: List(Float),
) -> Result(#(Float, Float, Float), Nil)
Quartiles Q1, Q2 (median), Q3 as a tuple.
pub fn sample_stddev(xs: List(Float)) -> Result(Float, Nil)
Sample standard deviation.
pub fn sample_variance(xs: List(Float)) -> Result(Float, Nil)
Sample variance s² = M₂ / (N - 1).
pub fn skewness(xs: List(Float)) -> Result(Float, Nil)
Skewness (Fisher-Pearson) via Pébay online accumulator.
Numerically stable: avoids the cancellation of Σ(x - μ)³ over a list.
pub fn sum(xs: List(Float)) -> Float
Sum of a list using Neumaier compensated summation. Returns 0.0 for empty.
Recovers up to 16 extra bits of precision vs naive fold (+.).
pub fn variance(xs: List(Float)) -> Result(Float, Nil)
Population variance σ² = M₂ / N.
pub fn weighted_mean(
xs: List(Float),
ws: List(Float),
) -> Result(Float, Nil)
Weighted mean: Σ(wᵢ · xᵢ) / Σwᵢ.