Skip to main content
kstats-core provides descriptive statistics as extension functions on DoubleArray and Iterable<Double>. It also includes Int and Long overloads for the most common operations.

Summary Snapshot

describe() is the fastest way to get a complete picture of a sample. It returns a DescriptiveStatistics object combining count, center, spread, quartiles, shape, and standard error.
variance() and standardDeviation() use the sample formula (dividing by n1n - 1) by default. Pass PopulationKind.POPULATION to use the population formula (dividing by nn).

Central Tendency

Different notions of “center” suit different data shapes. mean() is the arithmetic average, median() is the positional center, mode() returns the most frequent values, and the trimmed and weighted variants handle outliers and importance weights.
  • Geometric mean — use for growth rates and ratios. Requires all positive values.
  • Harmonic mean — use for rates and speed averages. Requires all positive values.
  • Trimmed mean — drops a proportion from each tail before averaging. Robust to outliers.
  • Weighted mean — each observation contributes proportionally to its weight.
xˉ=1ni=1nxi\bar{x} = \frac{1}{n}\sum_{i=1}^{n} x_ixˉgeo=(i=1nxi)1/n\bar{x}_{\text{geo}} = \left(\prod_{i=1}^{n} x_i\right)^{1/n}xˉharm=ni=1n1xi\bar{x}_{\text{harm}} = \frac{n}{\sum_{i=1}^{n} \frac{1}{x_i}}xˉw=i=1nwixii=1nwi\bar{x}_w = \frac{\sum_{i=1}^{n} w_i x_i}{\sum_{i=1}^{n} w_i}The trimmed mean drops pn\lfloor p \cdot n \rfloor observations from each end of the sorted sample, then computes the arithmetic mean of the remaining values.

Dispersion

Spread measures describe how far values deviate from the center.
semiVariance measures variability on one side of a threshold. DOWNSIDE captures risk below the threshold; UPSIDE captures variability above it.
s2=1n1i=1n(xixˉ)2,s=s2,SE=sns^2 = \frac{1}{n-1}\sum_{i=1}^{n}(x_i - \bar{x})^2, \qquad s = \sqrt{s^2}, \qquad SE = \frac{s}{\sqrt{n}}MAD=1ni=1nxixˉ\text{MAD} = \frac{1}{n}\sum_{i=1}^{n}|x_i - \bar{x}|SemiVardown(t)=1n1xi<t(xit)2\text{SemiVar}_{\text{down}}(t) = \frac{1}{n-1}\sum_{x_i < t}(x_i - t)^2

Quantiles and Position

Quantiles split the data at specified probability thresholds. percentile() takes a value on the 0–100 scale; quantile() takes a value on the 0–1 scale.
quantile() supports a QuantileInterpolation parameter with options: LINEAR (default), LOWER, HIGHER, NEAREST, and MIDPOINT. These control how the value is interpolated when the quantile falls between two data points.
With linear interpolation (the default), the quantile at probability pp for sorted data x(1),,x(n)x_{(1)}, \ldots, x_{(n)} is computed as:Q(p)=x(h)+(hh)(x(h)x(h))Q(p) = x_{(\lfloor h \rfloor)} + (h - \lfloor h \rfloor)(x_{(\lceil h \rceil)} - x_{(\lfloor h \rfloor)})where h=p(n1)+1h = p(n - 1) + 1.

Shape and Moments

Shape measures describe asymmetry and tail weight beyond what the mean and variance capture.
Skewness near zero suggests symmetry. Positive skewness indicates a longer right tail; negative indicates a longer left tail. Excess kurtosis near zero is similar to a normal distribution; positive values indicate heavier tails.
kurtosis() returns excess kurtosis by default (excess = true), meaning the value is shifted so that a normal distribution has excess kurtosis of 0. Pass excess = false for the raw fourth standardized moment.
g1=n(n1)(n2)i=1n(xixˉs)3g_1 = \frac{n}{(n-1)(n-2)} \sum_{i=1}^{n} \left(\frac{x_i - \bar{x}}{s}\right)^3g2=n(n+1)(n1)(n2)(n3)i=1n(xixˉs)43(n1)2(n2)(n3)g_2 = \frac{n(n+1)}{(n-1)(n-2)(n-3)} \sum_{i=1}^{n} \left(\frac{x_i - \bar{x}}{s}\right)^4 - \frac{3(n-1)^2}{(n-2)(n-3)}The rr-th central moment is μr=1ni=1n(xixˉ)r\mu_r = \frac{1}{n}\sum_{i=1}^{n}(x_i - \bar{x})^r. K-statistics (krk_r) are unbiased estimators of the corresponding cumulants.

Frequency Analysis

The Frequency class counts occurrences, proportions, and cumulative frequencies for any Comparable type. frequencyTable() groups numeric data into equal-width bins.
Frequency works with any Comparable type — strings, enums, integers, or custom classes. For numeric binning, use frequencyTable() with either a bin count or a bin width.

Streaming Statistics

OnlineStatistics computes mean, variance, skewness, and kurtosis incrementally without storing the full sample. Values can be added one at a time or in batches.
Use OnlineStatistics when data arrives incrementally (streaming, event-driven systems) or when buffering the full sample in memory is impractical.
OnlineStatistics uses Welford’s algorithm with the Terriberry extension for numerically stable single-pass computation of higher-order moments. The algorithm updates running sums of powers of deviations from the current mean, avoiding the catastrophic cancellation that affects naive two-pass formulas on large datasets.

Process Capability

Process capability indices quantify how well a process fits within its . processCapability(lsl, usl) returns four Statistical Process Control (SPC) indices in one call:
  • Cp, Cpk — potential and actual capability using the sample standard deviation (short-term, within-subgroup spread).
  • Pp, Ppk — the same formulas using the population standard deviation (long-term, overall spread).
The -k variants penalize a process that is off-center relative to the midpoint of the spec, so Cpk is never larger than Cp.
Use these indices only on a process that is already in statistical control (stable over time — see Shewhart Control Charts below). For an unstable process the measured spread is not a fixed property of the process.
Values ≥ 1.33 are usually considered capable; ≥ 1.67 highly capable. When Cpk ≪ Cp, re-center the process before trying to reduce variance.
Cp=USLLSL6σs,Cpk=min ⁣(USLxˉ3σs, xˉLSL3σs)\mathrm{Cp} = \frac{\mathrm{USL} - \mathrm{LSL}}{6\sigma_s}, \qquad \mathrm{Cpk} = \min\!\left(\frac{\mathrm{USL} - \bar{x}}{3\sigma_s},\ \frac{\bar{x} - \mathrm{LSL}}{3\sigma_s}\right)Pp and Ppk use the population standard deviation σp\sigma_p (divisor nn) in place of the sample standard deviation σs\sigma_s (divisor n1n-1). processCapability computes both in a single numerically stable Welford pass.

Shewhart Control Charts

Shewhart plot subgroup statistics over time with three-sigma control limits. xBarRChart() monitors the process mean together with the range within each subgroup; xBarSChart() uses the sample standard deviation instead — more efficient for subgroup sizes above 10. Both require equal-sized subgroups of 2–25 observations.
Control limits use the standard SPC constants A2,A3,D3,D4,B3,B4,c4A_2, A_3, D_3, D_4, B_3, B_4, c_4 (Montgomery, Introduction to Statistical Quality Control, Appendix VI) available for subgroup sizes 2–25 through spcConstants(n).
For kk subgroups of size nn with subgroup means xˉi\bar{x}_i, ranges RiR_i, and standard deviations sis_i:xˉ-R:UCL/LCL=xˉˉ±A2Rˉ,R-chart: [D3Rˉ, D4Rˉ]\text{x̄-R:}\quad \mathrm{UCL}/\mathrm{LCL} = \bar{\bar{x}} \pm A_2 \bar{R}, \quad R\text{-chart: } [D_3 \bar{R},\ D_4 \bar{R}]xˉ-S:UCL/LCL=xˉˉ±A3sˉ,S-chart: [B3sˉ, B4sˉ]\text{x̄-S:}\quad \mathrm{UCL}/\mathrm{LCL} = \bar{\bar{x}} \pm A_3 \bar{s}, \quad S\text{-chart: } [B_3 \bar{s},\ B_4 \bar{s}]

CUSUM Chart

A Shewhart chart reacts slowly to drifts of less than 2σ because every point is judged in isolation. cusum() accumulates deviations from target over time, so a 0.5σ–1σ drift is detected within a few observations. The two-sided tabular form tracks an upper sum C+C^+ that catches upward shifts and a lower sum CC^- for downward shifts. An alarm fires on the first index where either sum exceeds the decision interval HH.
Tune k to half the shift size you want to detect, in units of σ — a common default is K0.5σK \approx 0.5\sigma targeting a 1σ drift. Set h to 4σ–5σ to match the in-control run length of a 3σ Shewhart chart while reacting much faster to small shifts.
Ci+=max(0,  Ci1++(xiμ0K)),Ci=max(0,  Ci1+(μ0Kxi))C^+_i = \max\bigl(0,\; C^+_{i-1} + (x_i - \mu_0 - K)\bigr), \qquad C^-_i = \max\bigl(0,\; C^-_{i-1} + (\mu_0 - K - x_i)\bigr)starting from C0±=0C^\pm_0 = 0, with an alarm the first time Ci+>HC^+_i > H or Ci>HC^-_i > H.

EWMA Chart

EWMA (Roberts, 1959) is the other classic small-shift detector. Instead of an unbounded cumulative sum, ewma() maintains a weighted moving average that gives recent observations more influence while retaining memory of the past. Control limits widen with time until they reach a steady state, so the chart is most sensitive early — useful for catching an initial shift.
λ=0.2\lambda = 0.2 with L2.7L \approx 2.73.03.0 is a common default. Smaller λ\lambda emphasizes memory and detects smaller shifts; λ=1\lambda = 1 collapses EWMA into a Shewhart individuals chart.
Zt=λxt+(1λ)Zt1,Z0=μ0Z_t = \lambda x_t + (1 - \lambda) Z_{t-1}, \qquad Z_0 = \mu_0UCLt/LCLt=μ0±Lσλ2λ(1(1λ)2t)\mathrm{UCL}_t/\mathrm{LCL}_t = \mu_0 \pm L \sigma \sqrt{\frac{\lambda}{2 - \lambda}\,\bigl(1 - (1 - \lambda)^{2t}\bigr)}

Western Electric Rules

westernElectricRules() extends a Shewhart chart beyond the basic ±3σ check with four run-length heuristics that catch trends, clusters, and prolonged one-sided runs. Each rule’s array contains the trigger indices — the observation whose arrival completes the offending pattern.
Combine a Shewhart chart (large shifts) with CUSUM or EWMA (small shifts) and Western Electric Rules (patterns) — the three views together catch the widest range of out-of-control conditions.

Error Handling

Empty arrays throw InsufficientDataException. Functions that require at least two observations (variance, standard deviation, skewness) throw InsufficientDataException for single-element input. Functions requiring positive data (geometricMean, harmonicMean) throw InvalidParameterException for non-positive values.

API Reference

Full API Reference

Browse all public types, functions, parameter overloads, and return types in the Dokka-generated reference.
Last modified on April 23, 2026