Rust-Rolling-Stats

The rolling-stats library offers rolling statistics calculations (minimum, maximum, mean, standard deviation) over arbitrary floating point numbers. It uses Welford's Online Algorithm for these computations. This crate is no_std compatible.

For more information on the algorithm, visit Algorithms for calculating variance on Wikipedia.

Status

GitHub tag Build Status Crates.io Docs.rs

Usage

Single Thread Example

Below is an example of using rust-rolling-stats in a single-threaded context:

```rust use rollingstats::Stats; use randdistr::{Distribution, Normal}; use rand::SeedableRng;

type T = f64;

const MEAN: T = 0.0; const STDDEV: T = 1.0; const NUMSAMPLES: usize = 10_000; const SEED: u64 = 42;

let mut stats: Stats = Stats::new(); let mut rng = rand::rngs::StdRng::seedfromu64(SEED); // Seed the RNG for reproducibility let normal = Normal::::new(MEAN, STD_DEV).unwrap();

// Generate random data let randomdata: Vec = (0..NUMSAMPLES).map(|_x| normal.sample(&mut rng)).collect();

// Update the stats one by one randomdata.iter().foreach(|v| stats.update(*v));

// Print the stats println!("{}", stats); // Output: (avg: 0.00, std_dev: 1.00, min: -3.53, max: 4.11, count: 10000) ```

Multi Thread Example

This example showcases the usage of rust-rolling-stats in a multi-threaded context with the help of the rayon crate:

```rust use rollingstats::Stats; use randdistr::{Distribution, Normal}; use rand::SeedableRng; use rayon::prelude::*;

type T = f64;

const MEAN: T = 0.0; const STDDEV: T = 1.0; const NUMSAMPLES: usize = 500000; const SEED: u64 = 42; const CHUNKSIZE: usize = 1000;

let mut stats: Stats = Stats::new(); let mut rng = rand::rngs::StdRng::seedfromu64(SEED); // Seed the RNG for reproducibility let normal = Normal::::new(MEAN, STD_DEV).unwrap();

// Generate random data let randomdata: Vec = (0..NUMSAMPLES).map(|_x| normal.sample(&mut rng)).collect();

// Update the stats in parallel. New stats objects are created for each chunk of data. let stats: Vec> = randomdata .parchunks(CHUNKSIZE) // Multi-threaded parallelization via Rayon .map(|chunk| { let mut s: Stats = Stats::new(); chunk.iter().foreach(|v| s.update(*v)); s }) .collect();

// Check if there's more than one stat object assert!(stats.len() > 1);

// Accumulate the stats using the reduce method let mergedstats = stats.intoiter().reduce(|acc, s| acc.merge(&s)).unwrap();

// Print the stats println!("{}", mergedstats); // Output: (avg: -0.00, stddev: 1.00, min: -4.53, max: 4.57, count: 500000) ```

Feature Flags

The following feature flags are available:

License

The rolling-stats library is dual-licensed under the MIT and Apache License 2.0. By opening a pull request, you are implicitly agreeing to these licensing terms.