Descriptive Statistics
# covariance function
packages/math/src/descriptive.ts:300covariance(xs: number[], ys: number[]): numberxs and
ys (divided by n − 1).Covariance measures the joint variability of two variables — a positive value means they tend to increase together; a negative value means one tends to decrease as the other increases.
Returns NaN when:
- Either array is empty.
- The arrays have different lengths.
- There is fewer than 2 paired observations.
Parameters
| Name | Type | Description |
|---|---|---|
| xs | number[] | Array of independent-variable values. |
| ys | number[] | Array of dependent-variable values (same length as xs). |
Returns
numberNaN for degenerate inputs.slope = cov(x, y) / var(x)), making it a foundational primitive for
@statili/stats regression methods.
Example
covariance([1, 2, 3], [4, 5, 6]) // 1 (perfect positive covariance)
covariance([1, 2, 3], [6, 5, 4]) // -1 (perfect negative covariance)
covariance([1, 2, 3], [3, 3, 3]) // 0 (no covariance)
# mad function
packages/math/src/descriptive.ts:266mad(numbers: number[]): numberMAD is a robust measure of spread that is far less sensitive to outliers
than standardDeviation. A scaled MAD (1.4826 × MAD) approximates the
standard deviation for normally-distributed data.
Returns NaN for an empty array.
Parameters
| Name | Type | Description |
|---|---|---|
| numbers | number[] | Array of finite numbers. |
Returns
numberNaN if the array is empty.median ± 3 × 1.4826 × MAD can be flagged as anomalies in a
distribution-agnostic way.
Example
mad([1, 1, 2, 2, 4, 6, 9]) // 1
mad([]) // NaN
# max function
packages/math/src/descriptive.ts:165max(numbers: number[]): numbernumbers.NaN for an empty array.Parameters
| Name | Type | Description |
|---|---|---|
| numbers | number[] | Array of finite numbers. |
Returns
numberNaN if the array is empty.Example
max([3, 1, 4, 1, 5, 9]) // 9
max([]) // NaN
# mean function
packages/math/src/descriptive.ts:36mean(numbers: number[]): numbernumbers.NaN for an empty array — there is no meaningful average of zero
values. Downstream consumers should guard with isNaN(result).Parameters
| Name | Type | Description |
|---|---|---|
| numbers | number[] | Array of finite numbers. |
Returns
numberNaN if the array is empty.mean and median
signals skew in the distribution.
Example
mean([2, 4, 6]) // 4
mean([]) // NaN
# median function
packages/math/src/descriptive.ts:64median(numbers: number[]): numbernumbers.- For an odd count the median is the exact middle element of the sorted array.
- For an even count it is the mean of the two middle elements.
Returns NaN for an empty array.
Parameters
| Name | Type | Description |
|---|---|---|
| numbers | number[] | Array of finite numbers (need not be pre-sorted). |
Returns
numberNaN if the array is empty.mean to detect skew: mean > median → right-skewed; mean < median →
left-skewed.
Example
median([3, 1, 4, 1, 5]) // 3
median([1, 2, 3, 4]) // 2.5
median([]) // NaN
# min function
packages/math/src/descriptive.ts:148min(numbers: number[]): numbernumbers.NaN for an empty array.Parameters
| Name | Type | Description |
|---|---|---|
| numbers | number[] | Array of finite numbers. |
Returns
numberNaN if the array is empty.Example
min([3, 1, 4, 1, 5, 9]) // 1
min([]) // NaN
# pearsonCorrelation function
packages/math/src/descriptive.ts:338pearsonCorrelation(xs: number[], ys: number[]): numberxs
and ys, always in the range [−1, 1].r ≈ 1→ strong positive linear relationshipr ≈ −1→ strong negative linear relationshipr ≈ 0→ no linear relationship
Returns NaN when:
- Either array is empty or their lengths differ.
- Either array has zero variance (all values identical), making the correlation mathematically undefined.
Parameters
| Name | Type | Description |
|---|---|---|
| xs | number[] | First variable (same length as ys). |
| ys | number[] | Second variable (same length as xs). |
Returns
number[−1, 1], or NaN for degenerate inputs.Pearson r is the square-root of R² for simple linear regression and directly quantifies linear association strength. Use it to:
- Pre-screen variables before running regression.
- Classify relationship strength (|r| ≥ 0.7 strong, 0.4–0.7 moderate,
< 0.4 weak) for
@statili/forgeinsight generation. - Surface pairwise correlations in heatmap / scatterplot matrix views.
Example
pearsonCorrelation([1, 2, 3], [4, 5, 6]) // 1
pearsonCorrelation([1, 2, 3], [6, 5, 4]) // -1
pearsonCorrelation([1, 2, 3], [3, 3, 3]) // NaN (zero variance in ys)
# quantile function
packages/math/src/descriptive.ts:230quantile(p: number, numbers: number[]): numberp using linear interpolation between
adjacent ranks (equivalent to R’s Type 7 / NumPy’s default method).The array does not need to be pre-sorted.
Partial-application pattern — p (the quantile level) is the
infrequently-changing argument; numbers (the data) is last:
const median = quantile(0.5);
const p25 = quantile(0.25);
const p75 = quantile(0.75);
const iqr = (data: number[]) => p75(data) - p25(data);
Parameters
| Name | Type | Description |
|---|---|---|
| p | number | Quantile level in [0, 1]. 0.5 = median, 0.25 = Q1,
0.75 = Q3. Throws a RangeError if outside [0, 1]. |
| numbers | number[] | Array of finite numbers. |
Returns
numberNaN if the array is empty.quantiles divide data into equal-probability regions. Common uses:
- Interquartile range (IQR) = Q3 − Q1 (robust spread, used in box-plots and outlier detection).
- Percentile ranks communicate where a value sits in a distribution.
- Tail analysis — extreme quantiles (p = 0.01, p = 0.99) surface outlier thresholds for anomaly-detection annotations in charts.
Example
quantile(0.5, [1, 2, 3, 4, 5]) // 3 (median)
quantile(0.25, [1, 2, 3, 4]) // 1.75 (Q1)
quantile(0.75, [1, 2, 3, 4]) // 3.25 (Q3)
quantile(0, [5, 3, 1]) // 1 (min)
quantile(1, [5, 3, 1]) // 5 (max)
# range function
packages/math/src/descriptive.ts:189range(numbers: number[]): numberNaN for an empty array.Parameters
| Name | Type | Description |
|---|---|---|
| numbers | number[] | Array of finite numbers. |
Returns
numbermax(numbers) − min(numbers), or NaN if the array is empty.standardDeviation or iqr (interquartile
range via quantile) for robust spread estimates.
Example
range([3, 1, 4, 1, 5, 9]) // 8 (9 − 1)
range([7]) // 0
range([]) // NaN
# standardDeviation function
packages/math/src/descriptive.ts:132standardDeviation(numbers: number[], ddof?: 0 | 1): numbernumbers (Bessel’s
correction, divided by n − 1).Use ddof: 0 for the population standard deviation.
Returns NaN for an empty array or a single-element array when ddof = 1.
Parameters
| Name | Type | Description |
|---|---|---|
| numbers | number[] | Array of finite numbers. |
| ddofoptional | 0 | 1 | Delta degrees of freedom: 1 (default) = sample std dev,
0 = population std dev. |
Returns
numberNaN for degenerate inputs.mad, std dev is sensitive to outliers.
Example
standardDeviation([2, 4, 4, 4, 5, 5, 7, 9]) // ≈ 2.138 (sample)
standardDeviation([2, 4, 4, 4, 5, 5, 7, 9], 0) // 2 (population)
# sum function
packages/math/src/descriptive.ts:14sum(numbers: number[]): numbernumbers.0 for an empty array (the additive identity), consistent with
standard mathematical convention and most statistics libraries.Parameters
| Name | Type | Description |
|---|---|---|
| numbers | number[] | Array of finite numbers. |
Returns
number0 if the array is empty.Example
sum([1, 2, 3, 4]) // 10
sum([]) // 0
# variance function
packages/math/src/descriptive.ts:100variance(numbers: number[], ddof?: 0 | 1): numbernumbers (Bessel’s correction, divided
by n − 1).Use ddof: 0 to obtain the population variance (divided by n), which
is appropriate when numbers represents an entire population rather than a
sample.
Returns NaN when:
- The array is empty.
ddof = 1and the array has fewer than 2 elements (variance is undefined for a single-element sample).
Parameters
| Name | Type | Description |
|---|---|---|
| numbers | number[] | Array of finite numbers. |
| ddofoptional | 0 | 1 | Delta degrees of freedom: 1 (default) = sample variance,
0 = population variance. |
Returns
numberNaN for degenerate inputs.standardDeviation.
Example
variance([2, 4, 4, 4, 5, 5, 7, 9]) // 4.571... (sample)
variance([2, 4, 4, 4, 5, 5, 7, 9], 0) // 4 (population)
variance([42]) // NaN (single-element sample)