u-numflow 0.5.0

Foundational mathematical primitives: statistics, probability distributions, random sampling, and collections.
Documentation

u-numflow

Domain-agnostic mathematical primitives in Rust

Crates.io docs.rs CI License

Overview

u-numflow provides foundational mathematical, statistical, and probabilistic building blocks. Entirely domain-agnostic with no external dependencies beyond rand.

Modules

Module Description
stats Descriptive statistics (mean, variance, skewness, kurtosis) with Welford's online algorithm and Neumaier summation
distributions Probability distributions: Uniform, Triangular, PERT, Normal, LogNormal
special Special functions: normal/t/F/chi² CDF, inverse normal CDF, regularized incomplete beta/gamma, erf
transforms Data transformations: Box-Cox (λ via MLE golden-section search), inverse Box-Cox
fourier Discrete Fourier transform of any length (radix-2 for powers of two, Bluestein otherwise): fft, ifft, rfft, Complex
matrix Dense matrix operations: determinant, inverse, Cholesky decomposition, Jacobi eigenvalue decomposition
random Seeded RNG, Fisher-Yates shuffle, weighted sampling, random subset selection
collections Specialized data structures: Union-Find with path compression and union-by-rank

Design Philosophy

  • Numerical stability first — Welford's algorithm for variance, Neumaier summation for accumulation
  • Reproducibility — Seeded RNG support for deterministic experiments
  • Property-based testing — Mathematical invariants verified via proptest

Quick Start

[dependencies]
u-numflow = "0.2"
use u_numflow::stats::OnlineStats;
use u_numflow::distributions::{PertDistribution, Distribution};
use u_numflow::random::Rng;

// Online statistics with numerical stability
let mut stats = OnlineStats::new();
for x in [1.0, 2.0, 3.0, 4.0, 5.0] {
    stats.push(x);
}
assert_eq!(stats.mean(), 3.0);

// PERT distribution sampling
let pert = PertDistribution::new(1.0, 4.0, 7.0);
let mut rng = Rng::seed_from_u64(42);
let sample = pert.sample(&mut rng);

// Seeded shuffling for reproducibility
let mut items = vec![1, 2, 3, 4, 5];
u_numflow::random::shuffle(&mut items, &mut rng);

// Box-Cox transformation (non-normal data normalization)
use u_numflow::transforms::{estimate_lambda, box_cox};
let data = [1.0, 2.0, 4.0, 8.0, 16.0];
let lambda = estimate_lambda(&data, -2.0, 2.0).unwrap(); // MLE via golden-section
let transformed = box_cox(&data, lambda).unwrap();

// Discrete Fourier transform of any length
use u_numflow::fourier::rfft;
let signal: Vec<f64> = (0..30).map(|j| (2.0 * std::f64::consts::PI * 3.0 * j as f64 / 30.0).sin()).collect();
let spectrum = rfft(&signal);           // 30 complex bins; bin 3 carries the energy
assert!(spectrum[3].norm() > 14.0);

Build & Test

cargo build
cargo test

Dependencies

  • rand 0.9 — Random number generation
  • proptest 1.4 — Property-based testing (dev only)

License

MIT License — see LICENSE.

npm (WebAssembly)

npm install @iyulab/u-numflow

The package resolves per environment via a conditional exports map:

Environment Entry
Bundlers (webpack, Vite, …) ESM + WebAssembly ESM-integration (default condition)
Node.js — require(), ESM import, CJS TS runners (tsx, ts-node) CJS glue loading the wasm from the filesystem (node condition) — no loader hooks or flags

Exported functions: mean, std_dev, variance, normal_cdf, box_cox, estimate_lambda, and rfft(data) -> Float64Array — the DFT of a real sequence of any length, interleaved as [re0, im0, re1, im1, …] (bins k and n − k are conjugates, so 0..=n/2 describes the spectrum).

Related