stdlib.stats¶
Descriptive statistics, probability distributions, regression and hypothesis tests over Vec-backed samples.
Generated from
v0.65.7. 9 source files, 146 documented symbols.
dist.xi¶
fn uniform_pdf(x: Float64, a: Float64, b: Float64) -> Float64¶
Uniform density on [a, b]. Complexity: O(1).
- Postcondition:
(b <= a) => (result != result) - Postcondition:
(b > a) => (result >= 0)
fn uniform_cdf(x: Float64, a: Float64, b: Float64) -> Float64¶
Uniform cumulative distribution on [a, b]. Complexity: O(1).
- Postcondition:
(b <= a) => (result != result) - Postcondition:
(b > a) => ((result >= 0 && result <= 1) || (result != result))
fn normal_pdf(x: Float64, mu: Float64, sigma: Float64) -> Float64¶
Normal density with mean mu and stddev sigma. NaN for sigma <= 0. Complexity: O(1).
- Postcondition:
(sigma <= 0) => (result != result) - Postcondition:
(sigma > 0) => ((result >= 0) || (result != result))
fn normal_cdf(x: Float64, mu: Float64, sigma: Float64) -> Float64¶
Normal cumulative distribution. Complexity: O(1).
- Postcondition:
(sigma <= 0) => (result != result) - Postcondition:
(sigma > 0) => ((result >= 0 && result <= 1) || (result != result))
fn normal_ppf(p: Float64, mu: Float64, sigma: Float64) -> Float64¶
Normal percent point (inverse CDF) for probability p in (0, 1). Complexity: O(1).
- Postcondition:
(p <= 0 || p >= 1) => (result != result)
fn exponential_pdf(x: Float64, lambda: Float64) -> Float64¶
Exponential density with rate lambda. Complexity: O(1).
- Postcondition:
(lambda <= 0 || x < 0) => (result != result) - Postcondition:
(lambda > 0 && x >= 0) => ((result >= 0) || (result != result))
fn exponential_cdf(x: Float64, lambda: Float64) -> Float64¶
Exponential cumulative distribution. Complexity: O(1).
- Postcondition:
(lambda <= 0 || x < 0) => (result != result) - Postcondition:
(lambda > 0 && x >= 0) => ((result >= 0 && result <= 1) || (result != result))
fn poisson_pmf(k: Float64, lambda: Float64) -> Float64¶
Poisson probability mass at k with mean lambda (k is passed as a Float64 and used via the gamma function, so non-integer k is defined as well). Complexity: O(1).
- Postcondition:
(lambda < 0 || k < 0) => (result != result) - Postcondition:
(lambda == 0 && k == 0) => (result == 1) - Postcondition:
(lambda == 0 && k != 0) => ((result == 0) || (result != result)) - Postcondition:
(lambda > 0 && k >= 0) => ((result >= 0) || (result != result))
fn binomial_pmf(k: Float64, n: Float64, p: Float64) -> Float64¶
Binomial probability of k successes in n trials (k and n passed as Float64). NaN for invalid parameters. Complexity: O(1).
- Postcondition:
(p < 0 || p > 1 || k < 0 || n < 0 || k > n) => (result != result) - Postcondition:
(p >= 0 && p <= 1 && k >= 0 && n >= 0 && k <= n) => ((result >= 0) || (result != result))
fn geometric_pmf(k: Float64, p: Float64) -> Float64¶
Geometric probability of first success at trial k. Complexity: O(1).
- Postcondition:
(p <= 0 || p > 1 || k < 1) => (result != result) - Postcondition:
(p > 0 && p <= 1 && k >= 1) => ((result >= 0) || (result != result))
fn chi_squared_pdf(x: Float64, k: Float64) -> Float64¶
Chi-squared density with k degrees of freedom. Complexity: O(1).
- Postcondition:
(x < 0 || k <= 0) => (result != result) - Postcondition:
(x == 0 && k > 0 && k < 2) => (result > 0) - Postcondition:
(x == 0 && k == 2) => (result == 0.5) - Postcondition:
(x == 0 && k > 2) => (result == 0) - Postcondition:
(x > 0 && k > 0) => ((result >= 0) || (result != result))
fn student_t_pdf(x: Float64, v: Float64) -> Float64¶
Student's t density with v degrees of freedom. Complexity: O(1).
- Postcondition:
(v <= 0) => (result != result) - Postcondition:
(v > 0) => ((result >= 0) || (result != result))
fn beta_pdf(x: Float64, a: Float64, b: Float64) -> Float64¶
Beta density with shape parameters a and b. Complexity: O(1).
- Postcondition:
(a <= 0 || b <= 0) => (result != result) - Postcondition:
(a > 0 && b > 0 && (x <= 0 || x >= 1)) => (result == 0) - Postcondition:
(a > 0 && b > 0 && x > 0 && x < 1) => ((result >= 0) || (result != result))
fn sample_normal(mu: Float64, sigma: Float64) -> Float64¶
Draw a normal sample with mean mu and stddev sigma (Box-Muller over the seeded xiom RNG). Complexity: O(1).
- Postcondition:
(sigma <= 0) => (result != result)
fn sample_uniform(a: Float64, b: Float64) -> Float64¶
Draw a uniform sample from [a, b]. Complexity: O(1).
- Postcondition:
(b <= a) => (result != result) - Postcondition:
(b > a) => ((result >= a) || (result != result))
histogram.xi¶
type Histogram¶
A fixed-bin histogram over [min, max) with
binsbins.
| Field | Type |
|---|---|
bins |
Int |
min |
Float64 |
max |
Float64 |
counts |
Vec[Int] |
fn histogram_new(bins: Int, min: Float64, max: Float64) -> Histogram¶
Histogram over [min, max] with
binsbins. Complexity: O(bins).
- Postcondition:
result.bins == bins - Postcondition:
result.min == min - Postcondition:
result.max == max - Postcondition:
(bins <= 0 || max <= min) => (result.counts.len() == 0) - Postcondition:
(bins > 0 && max > min) => (result.counts.len() == bins)
fn histogram_add(h: Histogram, value: Float64)¶
Record a value into h (by-value parameter: the caller's copy is not updated under XIOM move semantics; the frozen signature has no return). Values outside [min, max) are dropped. Complexity: O(1).
- Postcondition:
h.counts.len() == h.counts.len()@pre
fn histogram_counts(h: Histogram) -> Vec[Int]¶
Per-bin counts. Complexity: O(1) (returns a copy).
- Postcondition:
result.len() == h.counts.len()
fn histogram_edges(h: Histogram) -> Vec[Float64]¶
Bin edge positions, length bins + 1. Complexity: O(bins).
- Postcondition:
(h.bins <= 0 || h.max <= h.min) => (result.len() == 0) - Postcondition:
(h.bins > 0 && h.max > h.min) => (result.len() == h.bins + 1)
fn histogram_normalize(h: Histogram) -> Vec[Float64]¶
Counts normalized to a probability density (total count over bin width). Empty for an empty histogram. Complexity: O(bins).
- Postcondition:
(h.counts.len() == 0 || h.max <= h.min) => (result.len() == 0) - Postcondition:
(result.len() == 0) || (result.len() == h.counts.len())
fn histogram_mean(h: Histogram) -> Float64¶
Mean estimated from the bin midpoints. NaN for an empty histogram. Complexity: O(bins).
- Postcondition:
h.counts.len() == 0 => (result != result)
fn histogram_variance(h: Histogram) -> Float64¶
Variance estimated from the bin midpoints. NaN for an empty histogram. Complexity: O(bins).
- Postcondition:
h.counts.len() == 0 => (result != result)
fn histogram_quantile(h: Histogram, q: Float64) -> Float64¶
q-th quantile (q in [0, 1]) from the cumulative counts; NaN for an empty histogram or invalid q. Complexity: O(bins).
- Postcondition:
(h.counts.len() == 0 || q < 0 || q > 1) => (result != result) - Postcondition:
(h.counts.len() > 0 && h.max > h.min && q >= 0 && q <= 1) => ((result >= h.min && result <= h.max) || (result != result))
fn histogram_mode(h: Histogram) -> Int¶
Index of the most populated bin (first on ties). Returns -1 for an empty histogram. Complexity: O(bins).
- Postcondition:
h.counts.len() == 0 => (result == -1) - Postcondition:
h.counts.len() > 0 => (result >= 0 && result < h.counts.len())
fn histogram_merge(a: Histogram, b: Histogram) -> Histogram¶
Combined histogram over the matching ranges: the counts of a and b are added (a's bin structure is used). Returns a copy of a when the ranges or bin counts differ (documented). Complexity: O(bins).
- Postcondition:
result.bins == a.bins - Postcondition:
result.min == a.min - Postcondition:
result.max == a.max - Postcondition:
(a.bins != b.bins || a.min != b.min || a.max != b.max) => (result.counts.len() == a.counts.len())
int_stats.xi¶
fn int_mean(values: &Vec[Int]) -> Int¶
Rounded integer mean of a scaled sample: round(sum(values) / n), halves away from zero. The sum accumulates exactly in 128 bits (n * |value| can never leave the 128-bit range for Int-length vectors), so the result is the correctly rounded mean of the scaled values. Empty input returns 0 (documented, matching xiom.stats). Complexity: O(n).
- Postcondition:
(values.len() == 0) => (result == 0)
fn int_slope(x: &Vec[Int], y: &Vec[Int], scale: Int) -> Int¶
Least-squares slope of y on x over scaled Int pairs: the inputs represent real values x_i = X_i / S and y_i = Y_i / S for one common positive scale S (S cancels in the ratio), and the result is round(scale * slope), halves away from zero. Mean-centred normal equations (sum dx*dy) / (sum dx^2) with exact 128-bit accumulation; exact while the centred sums stay inside 128 bits (all realistic scaled samples). Fewer than 2 points, a length mismatch, a zero x-variance or scale <= 0 returns 0 (documented). Complexity: O(n).
- Postcondition:
(scale <= 0) => (result == 0) - Postcondition:
(x.len() < 2) || (y.len() != x.len()) => (result == 0)
fn int_argmax(values: &Vec[Int]) -> Int¶
Index of the maximum with first-wins stability (FIFO tie-break): the earliest index holding the largest value wins. Empty input returns 0 (documented, matching the xiom.stats empty-input convention for Int stats; callers that need an absence signal pre-check len). Complexity: O(n).
- Postcondition:
(values.len() == 0) => (result == 0)
fn f64_argmax(values: &Vec[Float64]) -> Int¶
Float64 sibling of int_argmax with the documented NaN policy: NaN entries never win (they are skipped, whichever position they occupy) and ties keep the first index. Empty input or an all-NaN input returns 0 (documented; the stats module returns NaN itself for degenerate samples, but an index result has no NaN form, so the empty-sentinel 0 is reused). Complexity: O(n).
- Postcondition:
(values.len() == 0) => (result == 0)
moments.xi¶
fn mean(data: &Vec[Float64]) -> Float64¶
Arithmetic mean; 0 for an empty sample (documented). Complexity: O(n).
- Postcondition:
data.len() == 0 => (result == 0)
fn variance(data: &Vec[Float64]) -> Float64¶
Sample variance (Bessel's correction, n - 1); 0 for fewer than 2 samples. Complexity: O(n).
- Postcondition:
data.len() < 2 => (result == 0) - Postcondition:
(result >= 0) || (result != result)
fn stddev(data: &Vec[Float64]) -> Float64¶
Sample standard deviation; 0 for fewer than 2 samples. Complexity: O(n).
- Postcondition:
data.len() < 2 => (result == 0) - Postcondition:
(result >= 0) || (result != result)
fn skewness(data: &Vec[Float64]) -> Float64¶
Standardized third central moment; NaN for fewer than 3 samples. Complexity: O(n).
- Postcondition:
data.len() < 3 => (result != result)
fn kurtosis(data: &Vec[Float64]) -> Float64¶
Excess kurtosis (fourth central moment, zero for a normal distribution); NaN for fewer than 4 samples. Complexity: O(n).
- Postcondition:
data.len() < 4 => (result != result)
fn central_moment(data: &Vec[Float64], k: Int) -> Float64¶
k-th central moment about the mean; NaN for k < 2. Complexity: O(n).
- Postcondition:
(data.len() == 0 || k < 2) => (result != result) - Postcondition:
(data.len() > 0 && k >= 2 && k % 2 == 0) => ((result >= 0) || (result != result))
fn raw_moment(data: &Vec[Float64], k: Int) -> Float64¶
k-th raw moment about zero; NaN for k < 1. Complexity: O(n).
- Postcondition:
(data.len() == 0 || k < 1) => (result != result) - Postcondition:
(data.len() > 0 && k >= 1 && k % 2 == 0) => ((result >= 0) || (result != result))
fn covariance(x: &Vec[Float64], y: &Vec[Float64]) -> Float64¶
Sample covariance of x and y; NaN on length mismatch, 0 for fewer than 2 pairs. Complexity: O(n).
- Postcondition:
x.len() != y.len() => (result != result) - Postcondition:
(x.len() == y.len() && x.len() < 2) => (result == 0)
fn weighted_mean(data: &Vec[Float64], weights: &Vec[Float64]) -> Float64¶
Mean weighted by weights; NaN on length mismatch or a zero weight sum. Complexity: O(n).
- Postcondition:
data.len() != weights.len() => (result != result) - Postcondition:
data.len() == 0 => (result != result)
fn geometric_mean(data: &Vec[Float64]) -> Float64¶
Geometric mean via log-space; NaN for non-positive values. Complexity: O(n).
- Postcondition:
data.len() == 0 => (result != result) - Postcondition:
(result > 0) || (result != result)
fn harmonic_mean(data: &Vec[Float64]) -> Float64¶
Harmonic mean; NaN for non-positive values. Complexity: O(n).
- Postcondition:
data.len() == 0 => (result != result) - Postcondition:
(result > 0) || (result != result)
fn median(data: &Vec[Float64]) -> Float64¶
Middle value of the sorted sample; the average of the two middles when even. NaN for an empty sample. Complexity: O(n log n).
- Postcondition:
data.len() == 0 => (result != result)
fn quantile(data: &Vec[Float64], q: Float64) -> Float64¶
q-th quantile by linear interpolation between the sorted values (q in [0, 1]). NaN for invalid q. Complexity: O(n log n).
- Postcondition:
(data.len() == 0 || q < 0 || q > 1) => (result != result)
probability.xi¶
fn uniform_pdf(x: Float64, a: Float64, b: Float64) -> Float64¶
Uniform density on [a, b]. Complexity: O(1).
- Postcondition:
b > a && x < a => result == 0 - Postcondition:
b > a && x > b => result == 0
fn uniform_cdf(x: Float64, a: Float64, b: Float64) -> Float64¶
Uniform cumulative distribution on [a, b]. Complexity: O(1).
- Postcondition:
b > a && x <= a => result == 0 - Postcondition:
b > a && x >= b => result == 1
fn normal_pdf(x: Float64, mu: Float64, sigma: Float64) -> Float64¶
Normal density with mean mu and stddev sigma. Complexity: O(1).
- Postcondition:
(sigma <= 0) => math.is_nan(result)
fn normal_cdf(x: Float64, mu: Float64, sigma: Float64) -> Float64¶
Normal cumulative distribution. Complexity: O(1).
- Postcondition:
(sigma <= 0) => math.is_nan(result)
fn normal_quantile(p: Float64, mu: Float64, sigma: Float64) -> Float64¶
Normal quantile (inverse CDF) for probability p. Complexity: O(1).
- Postcondition:
(p <= 0 || p >= 1) => math.is_nan(result)
fn exponential_pdf(x: Float64, lambda: Float64) -> Float64¶
Exponential density with rate lambda. Complexity: O(1).
- Postcondition:
(lambda <= 0 || x < 0) => math.is_nan(result)
fn exponential_cdf(x: Float64, lambda: Float64) -> Float64¶
Exponential cumulative distribution. Complexity: O(1).
- Postcondition:
lambda > 0 && x == 0 => result == 0
fn gamma_pdf(x: Float64, k: Float64, theta: Float64) -> Float64¶
Gamma density with shape k and scale theta. Complexity: O(1).
- Postcondition:
(k <= 0 || theta <= 0 || x < 0) => math.is_nan(result)
fn gamma_cdf(x: Float64, k: Float64, theta: Float64) -> Float64¶
Gamma cumulative distribution: P(k, x/theta). Complexity: O(iterations).
- Postcondition:
k > 0 && theta > 0 && x <= 0 => result == 0
fn beta_pdf(x: Float64, a: Float64, b: Float64) -> Float64¶
Beta density with shape parameters a and b. Complexity: O(1).
- Postcondition:
(a <= 0 || b <= 0) => math.is_nan(result) - Postcondition:
(a > 0 && b > 0 && (x <= 0 || x >= 1)) => (result == 0)
fn beta_cdf(x: Float64, a: Float64, b: Float64) -> Float64¶
Beta cumulative distribution: I_x(a, b). Complexity: O(iterations).
- Postcondition:
a > 0 && b > 0 && x <= 0 => result == 0 - Postcondition:
a > 0 && b > 0 && x >= 1 => result == 1
fn chi2_pdf(x: Float64, k: Float64) -> Float64¶
Chi-squared density with k degrees of freedom. Complexity: O(1).
- Postcondition:
(x < 0 || k <= 0) => math.is_nan(result) - Postcondition:
(x == 0 && k > 2) => (result == 0)
fn chi2_cdf(x: Float64, k: Float64) -> Float64¶
Chi-squared cumulative distribution: P(k/2, x/2). Complexity: O(iterations).
- Postcondition:
k > 0 && x <= 0 => result == 0
fn t_pdf(x: Float64, v: Float64) -> Float64¶
Student's t density with v degrees of freedom. Complexity: O(1).
- Postcondition:
(v <= 0) => math.is_nan(result)
fn t_cdf(x: Float64, v: Float64) -> Float64¶
Student's t cumulative distribution via the regularized incomplete beta. Complexity: O(iterations).
- Postcondition:
(v <= 0) => math.is_nan(result)
fn f_pdf(x: Float64, d1: Float64, d2: Float64) -> Float64¶
F density with d1, d2 degrees of freedom. Complexity: O(1).
- Postcondition:
(x <= 0 || d1 <= 0 || d2 <= 0) => math.is_nan(result)
fn f_cdf(x: Float64, d1: Float64, d2: Float64) -> Float64¶
F cumulative distribution: I_{d1 x / (d1 x + d2)}(d1/2, d2/2). Complexity: O(iterations).
- Postcondition:
d1 > 0 && d2 > 0 && x <= 0 => result == 0
fn weibull_pdf(x: Float64, shape: Float64, scale: Float64) -> Float64¶
Weibull density with shape and scale. Complexity: O(1).
- Postcondition:
(shape <= 0 || scale <= 0 || x < 0) => math.is_nan(result) - Postcondition:
(x == 0 && shape > 1) => (result == 0)
fn weibull_cdf(x: Float64, shape: Float64, scale: Float64) -> Float64¶
Weibull cumulative distribution. Complexity: O(1).
- Postcondition:
shape > 0 && scale > 0 && x <= 0 => result == 0
fn lognormal_pdf(x: Float64, mu: Float64, sigma: Float64) -> Float64¶
Log-normal density of exp(mu + sigma Z). Complexity: O(1).
- Postcondition:
(sigma <= 0 || x <= 0) => math.is_nan(result)
fn lognormal_cdf(x: Float64, mu: Float64, sigma: Float64) -> Float64¶
Log-normal cumulative distribution. Complexity: O(1).
- Postcondition:
(sigma <= 0 || x <= 0) => math.is_nan(result)
fn pareto_pdf(x: Float64, alpha: Float64, xm: Float64) -> Float64¶
Pareto density with shape alpha and scale xm. Complexity: O(1).
- Postcondition:
(alpha <= 0 || xm <= 0 || x < xm) => math.is_nan(result)
fn pareto_cdf(x: Float64, alpha: Float64, xm: Float64) -> Float64¶
Pareto cumulative distribution. Complexity: O(1).
- Postcondition:
(alpha <= 0 || xm <= 0) => math.is_nan(result) - Postcondition:
(alpha > 0 && xm > 0 && x < xm) => (result == 0)
fn poisson_pmf(k: Int, lambda: Float64) -> Float64¶
Poisson probability of k events with mean lambda (integer k). Complexity: O(1).
- Postcondition:
lambda == 0 && k == 0 => result == 1 - Postcondition:
lambda == 0 && k > 0 => result == 0
fn poisson_cdf(k: Int, lambda: Float64) -> Float64¶
Poisson cumulative distribution. Complexity: O(k).
- Postcondition:
lambda == 0 && k >= 0 => result == 1
fn binomial_pmf(k: Int, n: Int, p: Float64) -> Float64¶
Binomial probability of k successes in n trials. Complexity: O(1).
- Postcondition:
(p < 0 || p > 1 || k < 0 || n < 0 || k > n) => math.is_nan(result)
fn binomial_cdf(k: Int, n: Int, p: Float64) -> Float64¶
Binomial cumulative distribution. Complexity: O(n).
- Postcondition:
n >= 0 && k >= n => result == 1
fn geometric_pmf(k: Int, p: Float64) -> Float64¶
Geometric probability of first success at trial k. Complexity: O(1).
- Postcondition:
p > 0 && p <= 1 && k >= 1 => result >= 0 && result <= 1
fn geometric_cdf(k: Int, p: Float64) -> Float64¶
Geometric cumulative distribution. Complexity: O(k).
- Postcondition:
p > 0 && p <= 1 && k >= 1 => result >= 0 && result <= 1
fn negative_binomial_pmf(k: Int, r: Int, p: Float64) -> Float64¶
Negative binomial probability of k failures before r successes. Complexity: O(1).
- Postcondition:
(p <= 0 || p > 1 || k < 0 || r <= 0) => math.is_nan(result)
fn negative_binomial_cdf(k: Int, r: Int, p: Float64) -> Float64¶
Negative binomial cumulative distribution. Complexity: O(k).
- Postcondition:
(k < 0 || r <= 0 || p <= 0 || p > 1) => math.is_nan(result)
fn hypergeometric_pmf(k: Int, n: Int, K: Int, N: Int) -> Float64¶
Hypergeometric probability of k successes drawing n from a population of N with K successes. Complexity: O(1).
- Postcondition:
(n < 0 || K < 0 || N <= 0 || k < 0 || k > n || k > K || n - k > N - K) => math.is_nan(result)
fn hypergeometric_cdf(k: Int, n: Int, K: Int, N: Int) -> Float64¶
Hypergeometric cumulative distribution. Complexity: O(n).
- Postcondition:
N > 0 && K >= 0 && n >= 0 && k >= K => result == 1
regress.xi¶
type RegressionResult¶
Least-squares linear fit result: slope, intercept, and R^2.
| Field | Type |
|---|---|
slope |
Float64 |
intercept |
Float64 |
r2 |
Float64 |
fn linear_regression(x: &Vec[Float64], y: &Vec[Float64]) -> RegressionResult¶
Least-squares linear fit y = slope*x + intercept with R-squared. Returns a zeroed result for fewer than 2 points or a mismatch. Complexity: O(n).
- Postcondition:
(x.len() == 0 || y.len() != x.len()) => (result.slope == 0 && result.intercept == 0 && result.r2 == 0) - Postcondition:
(x.len() == 1 && y.len() == 1) => (result.slope == 0 && result.r2 == 0)
fn slope(x: &Vec[Float64], y: &Vec[Float64]) -> Float64¶
Regression slope. Returns 0 for degenerate input. Complexity: O(n).
- Postcondition:
(x.len() < 2 || y.len() != x.len()) => (result == 0)
fn intercept(x: &Vec[Float64], y: &Vec[Float64]) -> Float64¶
Regression intercept. Returns 0 for degenerate input. Complexity: O(n).
- Postcondition:
(x.len() == 0 || y.len() != x.len()) => (result == 0)
fn r_squared(x: &Vec[Float64], y: &Vec[Float64]) -> Float64¶
Coefficient of determination R^2. Returns 0 for degenerate input. Complexity: O(n).
- Postcondition:
(x.len() < 2 || y.len() != x.len()) => (result == 0)
fn pearson_correlation(x: &Vec[Float64], y: &Vec[Float64]) -> Float64¶
Pearson correlation coefficient. Complexity: O(n).
- Postcondition:
(x.len() < 2 || y.len() != x.len()) => math.is_nan(result)
fn spearman_correlation(x: &Vec[Float64], y: &Vec[Float64]) -> Float64¶
Rank-based Spearman correlation. Complexity: O(n log n).
- Postcondition:
(y.len() != x.len() || x.len() < 2) => math.is_nan(result)
fn polynomial_regression(x: &Vec[Float64], y: &Vec[Float64], degree: Int) -> Vec[Float64]¶
Least-squares polynomial coefficients (lowest degree first) by solving the normal equations: exact for degree 1 and 2 (Cramer's rule); higher degrees return the empty vector (documented). Complexity: O(n).
- Postcondition:
(degree < 1 || degree > 2) => (result.len() == 0) - Postcondition:
(degree == 1 && x.len() >= 2 && y.len() == x.len()) => (result.len() == 2) - Postcondition:
(degree == 2 && x.len() >= 3 && y.len() == x.len()) => (result.len() == 0 || result.len() == 3)
fn exponential_fit(x: &Vec[Float64], y: &Vec[Float64]) -> (Float64, Float64)¶
Exponential fit y = a * exp(b*x): linear regression on (x, ln y). Returns (a, b); NaN for non-positive y. Complexity: O(n).
- Postcondition:
(x.len() < 2 || y.len() != x.len()) => (math.is_nan(result._0) && math.is_nan(result._1))
fn predict_line(slope: Float64, intercept: Float64, x: Float64) -> Float64¶
Predicted value slope * x + intercept. Complexity: O(1).
- Postcondition:
result == slope * x + intercept
fn residuals(x: &Vec[Float64], y: &Vec[Float64], slope: Float64, intercept: Float64) -> Vec[Float64]¶
Observed minus predicted values. Empty for a mismatch. Complexity: O(n).
- Postcondition:
(y.len() != x.len()) => (result.len() == 0) - Postcondition:
(y.len() == x.len()) => (result.len() == x.len())
statistics.xi¶
fn mean(data: &Vec[Float64]) -> Float64¶
Arithmetic mean; 0 for an empty sample. Complexity: O(n).
- Postcondition:
(data.len() == 0) => (result == 0)
fn median(data: &Vec[Float64]) -> Float64¶
Middle value of the sorted sample; average of the two middles when even. NaN for an empty sample. Complexity: O(n log n).
- Postcondition:
(data.len() == 0) => math.is_nan(result)
fn mode(data: &Vec[Float64]) -> Option[Float64]¶
Most frequently occurring value. NaN for an empty sample; the first mode wins ties (documented). Complexity: O(n^2).
- Postcondition:
(data.len() == 0) => (result is None) - Postcondition:
(data.len() > 0) => (result is Some(_))
fn variance(data: &Vec[Float64]) -> Float64¶
Sample variance (n - 1); 0 for fewer than 2 samples. Complexity: O(n).
- Postcondition:
(data.len() < 2) => (result == 0)
fn variance_pop(data: &Vec[Float64]) -> Float64¶
Population variance (n); 0 for an empty sample. Complexity: O(n).
- Postcondition:
(data.len() == 0) => (result == 0)
fn stddev(data: &Vec[Float64]) -> Float64¶
Sample standard deviation. Complexity: O(n).
- Postcondition:
(data.len() < 2) => (result == 0)
fn stddev_pop(data: &Vec[Float64]) -> Float64¶
Population standard deviation. Complexity: O(n).
- Postcondition:
(data.len() == 0) => (result == 0)
fn range(data: &Vec[Float64]) -> Float64¶
Range (max - min); 0 for an empty sample. Complexity: O(n).
- Postcondition:
(data.len() == 0) => (result == 0)
fn iqr(data: &Vec[Float64]) -> Float64¶
Interquartile range (Q3 - Q1). NaN for fewer than 2 samples. Complexity: O(n log n).
- Postcondition:
(data.len() == 0) => math.is_nan(result)
fn quartiles(data: &Vec[Float64]) -> Vec[Float64]¶
Quartiles [Q1, Q2, Q3] by linear interpolation. Empty for an empty sample. Complexity: O(n log n).
- Postcondition:
(data.len() == 0) => (result.len() == 0) - Postcondition:
(data.len() > 0) => (result.len() == 3)
fn percentile(data: &Vec[Float64], p: Float64) -> Float64¶
p-th percentile by linear interpolation (p in [0, 100]). NaN for invalid p. Complexity: O(n log n).
- Postcondition:
(p < 0 || p > 100) => math.is_nan(result) - Postcondition:
(data.len() == 0 && 0 <= p && p <= 100) => math.is_nan(result)
fn skewness(data: &Vec[Float64]) -> Float64¶
Standardized third central moment. Complexity: O(n).
- Postcondition:
(data.len() < 3) => math.is_nan(result)
fn kurtosis(data: &Vec[Float64]) -> Float64¶
Excess kurtosis (fourth central moment, zero for normal). Complexity: O(n).
- Postcondition:
(data.len() < 4) => math.is_nan(result)
fn covariance(x: &Vec[Float64], y: &Vec[Float64]) -> Float64¶
Sample covariance of x and y. Complexity: O(n).
- Postcondition:
(x.len() != y.len()) => math.is_nan(result) - Postcondition:
(x.len() == y.len() && x.len() < 2) => (result == 0)
fn correlation(x: &Vec[Float64], y: &Vec[Float64]) -> Float64¶
Pearson correlation coefficient. Complexity: O(n).
- Postcondition:
(x.len() != y.len()) => math.is_nan(result) - Postcondition:
(x.len() == y.len() && x.len() < 2) => math.is_nan(result)
fn spearman_correlation(x: &Vec[Float64], y: &Vec[Float64]) -> Float64¶
Spearman rank correlation: the Pearson correlation of the ranks. Complexity: O(n log n).
- Postcondition:
(x.len() != y.len()) => math.is_nan(result) - Postcondition:
(x.len() == y.len() && x.len() < 2) => math.is_nan(result)
fn kendall_correlation(x: &Vec[Float64], y: &Vec[Float64]) -> Float64¶
Kendall tau-b rank correlation (concordant minus discordant pairs). Complexity: O(n^2).
- Postcondition:
(x.len() != y.len()) => math.is_nan(result) - Postcondition:
(x.len() == y.len() && x.len() < 2) => math.is_nan(result)
fn rms(data: &Vec[Float64]) -> Float64¶
Root mean square of the sample; 0 for an empty sample. Complexity: O(n).
- Postcondition:
(data.len() == 0) => (result == 0)
fn geometric_mean(data: &Vec[Float64]) -> Float64¶
Geometric mean via log-space; NaN for non-positive values. Complexity: O(n).
- Postcondition:
(data.len() == 0) => math.is_nan(result)
fn harmonic_mean(data: &Vec[Float64]) -> Float64¶
Harmonic mean; NaN for non-positive values. Complexity: O(n).
- Postcondition:
(data.len() == 0) => math.is_nan(result)
fn weighted_mean(data: &Vec[Float64], weights: &Vec[Float64]) -> Float64¶
Mean weighted by weights. Complexity: O(n).
- Postcondition:
(data.len() != weights.len()) => math.is_nan(result)
fn trimmed_mean(data: &Vec[Float64], trim: Float64) -> Float64¶
Mean after removing the fraction
trimfrom each sorted tail. NaN for invalid trim or an over-trimmed sample. Complexity: O(n log n).
- Postcondition:
(trim < 0 || trim >= 0.5) => math.is_nan(result) - Postcondition:
(data.len() == 0) => math.is_nan(result)
fn winsorized_mean(data: &Vec[Float64], trim: Float64) -> Float64¶
Mean with the fraction
trimof each tail winsorized to the tail values. NaN for invalid trim. Complexity: O(n log n).
- Postcondition:
(trim < 0 || trim >= 0.5) => math.is_nan(result) - Postcondition:
(data.len() == 0) => math.is_nan(result)
fn mad(data: &Vec[Float64]) -> Float64¶
Median absolute deviation from the median. NaN for an empty sample. Complexity: O(n log n).
- Postcondition:
(data.len() == 0) => math.is_nan(result)
fn z_score(x: Float64, mean: Float64, stddev: Float64) -> Float64¶
Standardized score (x - mean) / stddev. Complexity: O(1).
- Postcondition:
(stddev == 0) => math.is_nan(result)
stats.xi¶
fn stats_min(data: &Vec[Int]) -> Int¶
Returns the minimum value in a vector of integers. Returns 0 for empty input.
- Postcondition:
data.len() == 0 => result == 0
fn stats_max(data: &Vec[Int]) -> Int¶
Returns the maximum value in a vector of integers. Returns 0 for empty input.
- Postcondition:
data.len() == 0 => result == 0
fn stats_range(data: &Vec[Int]) -> Int¶
Returns the range (max - min) of a vector of integers.
- Postcondition:
data.len() == 0 => result == 0
fn stats_mode(data: &Vec[Int]) -> Option[Int]¶
Returns the most frequently occurring value (mode) in a sorted vector. For ties, returns the first mode encountered.
- Postcondition:
(data.len() == 0) => (result is None) - Postcondition:
(data.len() > 0) => (result is Some(_))
fn stats_variance(data: &Vec[Int]) -> Float64¶
Computes the population variance of a vector of integers. Sum of squared deviations from the mean divided by N.
- Postcondition:
data.len() == 0 => result == 0 - Postcondition:
result >= 0
fn stats_sample_variance(data: &Vec[Int]) -> Float64¶
Computes the sample variance (Bessel's correction: divide by N-1).
- Postcondition:
data.len() < 2 => result == 0 - Postcondition:
result >= 0
fn stats_stddev_f(data: &Vec[Int]) -> Float64¶
Computes the population standard deviation (Float64).
- Postcondition:
result >= 0
fn stats_sample_stddev(data: &Vec[Int]) -> Float64¶
Computes the sample standard deviation (Float64).
- Postcondition:
result >= 0
fn stats_q1(data: &Vec[Int]) -> Int¶
Returns the first quartile (Q1) of a sorted vector of integers. Uses the median-of-lower-half method.
- Postcondition:
data.len() == 0 => result == 0
fn stats_q3(data: &Vec[Int]) -> Int¶
Returns the third quartile (Q3) of a sorted vector of integers. Uses the median-of-upper-half method.
- Postcondition:
data.len() == 0 => result == 0
fn stats_iqr(data: &Vec[Int]) -> Int¶
Returns the interquartile range (Q3 - Q1).
- Postcondition:
data.len() == 0 => result == 0
fn stats_sum_f(data: &Vec[Float64]) -> Float64¶
Sum of a vector of Float64 values.
- Postcondition:
data.len() == 0 => result == 0
fn stats_mean_f(data: &Vec[Float64]) -> Float64¶
Mean of a vector of Float64 values.
- Postcondition:
data.len() == 0 => result == 0
fn stats_stddev_f_f(data: &Vec[Float64]) -> Float64¶
Population standard deviation of a vector of Float64 values.
- Postcondition:
data.len() == 0 => result == 0 - Postcondition:
result >= 0 || result != result
fn stats_covariance(a: &Vec[Int], b: &Vec[Int]) -> Float64¶
Computes the population covariance between two vectors of equal length.
- Postcondition:
a.len() == 0 => result == 0 - Postcondition:
b.len() != a.len() => result == 0
fn stats_correlation(a: &Vec[Int], b: &Vec[Int]) -> Float64¶
Computes the Pearson correlation coefficient between two vectors.
- Postcondition:
(a.len() < 2 || b.len() < 2) => (result == 0)
fn stats_histogram(data: &Vec[Int], bins: Int, lo: Int, hi: Int) -> Vec[Int]¶
Builds a histogram with the specified number of bins over [lo, hi]. Each bin counts values in [bin_start, bin_start + bin_width).
- Postcondition:
bins <= 0 => result.len() == 0 - Postcondition:
hi <= lo => result.len() == 0 - Postcondition:
bins > 0 && hi > lo => result.len() == bins
fn stats_geometric_mean(data: &Vec[Int]) -> Float64¶
Computes the geometric mean using logarithms to avoid overflow. Requires all values to be positive.
- Postcondition:
data.len() == 0 => result == 0 - Postcondition:
result >= 0
fn stats_harmonic_mean(data: &Vec[Int]) -> Float64¶
Computes the harmonic mean. Returns 0 if any value is <= 0.
- Postcondition:
data.len() == 0 => result == 0 - Postcondition:
result >= 0
fn stats_zscore(value: Int, mean: Float64, stddev: Float64) -> Float64¶
Computes the z-score: (value - mean) / stddev.
- Postcondition:
stddev == 0 => result == 0
fn stats_slope(x: &Vec[Int], y: &Vec[Int]) -> Float64¶
Computes the slope of the simple linear regression line y = mx + b.
- Postcondition:
x.len() < 2 => result == 0 - Postcondition:
y.len() != x.len() => result == 0
fn stats_intercept(x: &Vec[Int], y: &Vec[Int]) -> Float64¶
Computes the intercept of the simple linear regression line y = mx + b.
- Postcondition:
y.len() == 0 => result == 0
fn stats_r_squared(x: &Vec[Int], y: &Vec[Int]) -> Float64¶
Computes the R-squared (coefficient of determination) for linear regression.
- Postcondition:
x.len() < 2 => result == 0 - Postcondition:
y.len() != x.len() => result == 0
test.xi¶
fn t_test_one_sample(data: &Vec[Float64], mu: Float64) -> Float64¶
One-sample t statistic against population mean mu. NaN for fewer than 2 samples. Complexity: O(n).
- Postcondition:
data.len() < 2 => (result != result)
fn t_test_two_sample(a: &Vec[Float64], b: &Vec[Float64]) -> Float64¶
Independent two-sample t statistic (Welch, unequal variance). NaN for fewer than 2 samples in either group. Complexity: O(n).
- Postcondition:
(a.len() < 2 || b.len() < 2) => (result != result)
fn t_test_paired(a: &Vec[Float64], b: &Vec[Float64]) -> Float64¶
Paired t statistic on the differences a - b. NaN for a mismatch or fewer than 2 pairs. Complexity: O(n).
- Postcondition:
(a.len() != b.len() || a.len() < 2) => (result != result)
fn chi_squared_test(observed: &Vec[Int], expected: &Vec[Float64]) -> Float64¶
Chi-squared goodness-of-fit statistic sum (o - e)^2 / e. NaN for a mismatch or a zero expected count. Complexity: O(n).
- Postcondition:
expected.len() != observed.len() => (result != result) - Postcondition:
(result >= 0) || (result != result)
fn f_test(a: &Vec[Float64], b: &Vec[Float64]) -> Float64¶
F statistic as the ratio of the sample variances. NaN for fewer than 2 samples or a zero denominator variance. Complexity: O(n).
- Postcondition:
(a.len() < 2 || b.len() < 2) => (result != result) - Postcondition:
(result >= 0) || (result != result)
fn anova_one_way(groups: &Vec[Vec[Float64]]) -> Float64¶
One-way ANOVA F statistic across groups. TODO(compiler): NOT IMPLEMENTABLE in this compiler build - the groups are a Vec[Vec[Float64]] whose element reads return garbage (BUG 23 #1 residual; verified by minimal probe). Keep the frozen signature; revisit when nested float Vec reads land.
- Postcondition:
result != result
fn p_value_from_t(t: Float64, df: Float64) -> Float64¶
Two-tailed p-value for a t statistic with df degrees of freedom: P(|T| > t) = I_{df/(df + t^2)}(df/2, 1/2). Complexity: O(iterations).
- Postcondition:
df <= 0 => (result != result) - Postcondition:
(result >= 0 && result <= 1) || (result != result)
fn p_value_from_chi2(x: Float64, df: Float64) -> Float64¶
Right-tail p-value for a chi-squared statistic: 1 - P(df/2, x/2). Complexity: O(iterations).
- Postcondition:
(df <= 0 || x < 0) => (result != result) - Postcondition:
(df > 0 && x == 0) => (result == 1) - Postcondition:
(result >= 0 && result <= 1) || (result != result)
fn z_score(x: Float64, mu: Float64, sigma: Float64) -> Float64¶
Standardized score (x - mu) / sigma. Complexity: O(1).
- Postcondition:
(sigma == 0) => (result != result)
fn confidence_interval(data: &Vec[Float64], level: Float64) -> (Float64, Float64)¶
Confidence interval (lower, upper) for the sample mean at the given confidence level. NaN for fewer than 2 samples or an invalid level. Complexity: O(n).
- Postcondition:
(data.len() < 2 || level <= 0 || level >= 1) => ((result._0 != result._0) && (result._1 != result._1)) - Postcondition:
(data.len() >= 2 && level > 0 && level < 1) => ((result._1 >= result._0) || (result._0 != result._0))
fn standard_error(data: &Vec[Float64]) -> Float64¶
Standard error of the mean. NaN for fewer than 2 samples. Complexity: O(n).
- Postcondition:
data.len() < 2 => (result != result) - Postcondition:
(result >= 0) || (result != result)