nexus-stats
Fixed-memory, zero-allocation streaming statistics for real-time systems.
Every primitive is O(1) per update, fixed memory after construction, and
no_std compatible. Designed for event loops, trading systems, and
anywhere you need statistics without latency jitter.
Quick Start
use ;
// Detect latency shifts with CUSUM
let mut cusum = builder // target: 100μs baseline
.slack // sensitivity
.threshold // decision boundary
.min_samples // warmup
.build.unwrap;
for latency in samples
// Smooth noisy measurements with EMA
let mut ema = builder
.span // ~20-sample smoothing window
.min_samples
.build.unwrap;
if let Some = ema.update
// Track running statistics with Welford
let mut stats = new;
stats.update;
if let Some = stats.mean
Algorithms
55+ algorithms across 10 categories. See full documentation for deep-dives on each algorithm.
Change Detection
| Type | What It Detects | p50 |
|---|---|---|
CusumF64 |
Persistent mean shifts (up or down) | 5 |
MosumF64 |
Transient spikes within a window | 6 |
ShiryaevRobertsF64 |
Mean shifts with optimal detection delay | 17 |
MultiGateF64 |
Graded anomalies: Accept/Unusual/Suspect/Reject | 12 |
RobustZScoreF64 |
MAD-based outlier scoring with estimator freeze | 12 |
AdaptiveThresholdF64 |
Z-score anomalies with self-learning baseline | 15 |
Smoothing & Filtering
| Type | What It Computes | p50 |
|---|---|---|
EmaF64 / EmaI64 |
Exponential moving average (float / integer) | 5 |
AsymEmaF64 |
Different alpha for rising vs falling | 11 |
KamaF64 |
Kaufman adaptive MA (adapts to trend/noise) | 16 |
Kalman1dF64 |
1D Kalman filter with velocity tracking | 25 |
HoltF64 |
Double exponential (level + trend) | 11 |
SpringF64 |
Critically damped spring (smooth target chasing) | 12 |
SlewF64 |
Hard rate-of-change clamp | 3 |
WindowedMedianF64 |
Robust median filter (outlier-immune) | 132 |
Statistics
| Type | What It Computes | p50 |
|---|---|---|
WelfordF64 |
Online mean, variance, std dev (Chan's merge) | 10 |
MomentsF64 |
Online skewness & kurtosis (Pébay, 2008). Merge support | 24 |
EwmaVarF64 |
Exponentially weighted variance | 12 |
CovarianceF64 |
Online covariance + Pearson correlation | 12 |
HarmonicMeanF64 |
Correct average for rates/throughputs | 5 |
Regression
| Type | What It Computes | p50 |
|---|---|---|
LinearRegressionF64 |
Online OLS linear fit (y = ax + b) |
TBD |
EwLinearRegressionF64 |
Exponentially-weighted linear fit | TBD |
PolynomialRegressionF64 |
Online polynomial fit (.builder().degree(2), .degree(3), ...) |
TBD |
EwPolynomialRegressionF64 |
Exponentially-weighted polynomial fit | TBD |
ExponentialRegressionF64 |
Exponential fit (y = ae^(bx)) |
TBD |
LogarithmicRegressionF64 |
Logarithmic fit (y = a·ln(x) + b) |
TBD |
PowerRegressionF64 |
Power law fit (y = ax^b) |
TBD |
Signal Analysis
| Type | What It Computes | p50 |
|---|---|---|
AutocorrelationF64 |
Self-correlation at fixed lag (trending vs reverting) | 12 |
CrossCorrelationF64 |
Two-stream correlation with lead/lag detection | 39 |
Information Theory (std|libm)
| Type | What It Computes | p50 |
|---|---|---|
EntropyF64 |
Shannon entropy over K categories | 3 |
TransferEntropyF64 (alloc, std|libm) |
Directed information flow (Granger causality) | 14 |
Monitoring
| Type | What It Tracks | p50 |
|---|---|---|
DrawdownF64 |
Peak-to-trough decline, max drawdown | 5 |
RunningMinF64 / RunningMaxF64 |
All-time extrema | 5 |
WindowedMaxF64 / WindowedMinF64 |
Sliding window extrema (Nichols'/BBR) | 9 |
PeakHoldF64 |
Peak envelope with hold + decay | 7 |
MaxGaugeF64 |
Reset-on-read maximum (Netflix pattern) | 5 |
LivenessF64 |
Source alive/dead detection | 6 |
EventRateF64 |
Smoothed events per unit time | 6 |
CoDelI64 |
Queue backpressure detection (CoDel-inspired) | 7 |
SaturationF64 |
Resource utilization threshold (USE method) | 6 |
ErrorRateF64 |
Failure rate with weighted severity | 6 |
TrendAlertF64 |
Trend direction (Stable/Rising/Falling) | 12 |
JitterF64 |
Signal variability measurement | 6 |
Frequency & Scoring
| Type | What It Tracks | p50 |
|---|---|---|
TopK<K, CAP> |
Space-Saving top-K frequent items | 42 |
FlexProportionGlobal/Entity |
Per-entity fraction with lazy decay | O(1) |
DecayAccumF64 |
Event-driven score with time decay | O(1) |
Utilities
| Type | What It Does | p50 |
|---|---|---|
DebounceU32 |
N consecutive events before triggering | 2 |
DeadBandF64 |
Suppress changes below threshold | 2 |
HysteresisF64 |
Binary decision with different rising/falling thresholds | 3 |
BoolWindow |
Sliding pass/fail rate over last N events | 6 |
PeakDetectorF64 |
Local maxima/minima with prominence | 3 |
LevelCrossingF64 |
Threshold crossing counter | 2 |
FirstDiffF64 |
Discrete derivative (rate of change) | 2 |
SecondDiffF64 |
Discrete acceleration | 2 |
Type Variants
Explicit concrete types — no generics to fight with. Float types use FMA intrinsics; integer types use bit-shift arithmetic.
| Algorithm | f32 | f64 | i32 | i64 | i128 |
|---|---|---|---|---|---|
| CUSUM, Drawdown | ✓ | ✓ | ✓ | ✓ | ✓ |
| RunningMin/Max, WindowedMin/Max | ✓ | ✓ | ✓ | ✓ | ✓ |
| SlewLimiter, DeadBand, Hysteresis | ✓ | ✓ | ✓ | ✓ | ✓ |
| PeakHold, PeakDetector, LevelCrossing | ✓ | ✓ | ✓ | ✓ | ✓ |
| FirstDiff, SecondDiff, MOSUM | ✓ | ✓ | ✓ | ✓ | ✓ |
| MaxGauge, CoDel | ✓ | ✓ | ✓ | ||
| EMA, Jitter, AsymEMA | ✓ | ✓ | ✓ | ✓ | |
| Liveness, EventRate | ✓ | ✓ | ✓ | ✓ | |
| Welford, EwmaVar, Covariance, HarmonicMean | ✓ | ✓ | |||
| Moments, Autocorrelation | ✓ | ✓ | ✓ | ✓ | |
| CrossCorrelation, Entropy | ✓ | ✓ | |||
| TransferEntropy | ✓ | ||||
| Holt, KAMA, Kalman1D, Spring | ✓ | ✓ | |||
| MultiGate, RobustZScore, AdaptiveThreshold | ✓ | ✓ | |||
| Saturation, ErrorRate, TrendAlert | ✓ | ✓ | |||
| ShiryaevRoberts | ✓ |
Common API Patterns
All types follow consistent conventions:
- Builder pattern for config-driven types (
CusumF64::builder(target)) const fn new()for zero-config types (WelfordF64::new())- Priming — returns
Noneuntilmin_samplesreached is_primed()— check if enough data has been seencount()— total samples processedreset()— clear state for operational/admin resetseed()— skip warmup with pre-loaded baseline (CUSUM, EMA, AdaptiveThreshold)#[must_use]— compiler warns if you ignore return values
Documentation
Comprehensive documentation including:
- Which algorithm do I need? — decision tree
- Quick start recipes — copy-paste examples
- Parameter tuning guide — how to set alpha, slack, etc.
- Composing primitives — building monitors from parts
- 40 algorithm deep-dives with ASCII diagrams, domain examples, and performance data
- 10 use-case guides (latency, backpressure, anomaly detection, feed health, networking, gaming, SRE, capacity planning, industrial, rate management)
Performance
All measurements in CPU cycles (rdtsc), pinned to a single core.
Batch of 64 updates per sample to amortize timing overhead.
Data Quality & Error Policy
nexus-stats distinguishes two failure categories:
- Data errors (NaN, Inf) — All float update methods return
Result<_, DataError>. The library rejects the input and leaves state unchanged. The caller declares the policy:.unwrap()to crash, log and continue, or trigger a circuit breaker. - Programmer errors (wrong dimensions, out-of-range) — The library panics. Fix the code.
The library makes no assumptions about which policy is correct. Each system has different implications.
// Production: log and continue
if let Err = stats.update
// Testing: crash hard
stats.update.unwrap;
Features
| Feature | Default | What |
|---|---|---|
std |
yes | Hardware intrinsics for sqrt/exp |
libm |
no | Pure Rust math fallback for no_std |
alloc |
no | Runtime-sized windows (MOSUM, WindowedMedian, KAMA, BoolWindow) |
One of std or libm must be enabled. Update hot paths never use
transcendentals — sqrt and exp are only used in queries (std_dev())
and construction (halflife()).
License
Licensed under either of Apache License, Version 2.0 or MIT License at your option.