diff --git a/Cargo.toml b/Cargo.toml index 736fdd6..df20a3f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -4,9 +4,12 @@ name = "average" version = "0.1.0" license = "MIT/Apache-2.0" repository = "https://github.com/vks/average" -description = "Calculate the average of a sequence iteratively" -keywords = ["statistics", "stats"] +description = "Calculate the average of a sequence and its error iteratively" categories = ["science", "no-std"] +keywords = ["statistics", "stats"] [dependencies] conv = "0.3" + +[dev-dependencies] +rand = "0.3" diff --git a/src/lib.rs b/src/lib.rs index 760d52b..9314db9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,6 +1,8 @@ #![no_std] extern crate conv; +#[cfg(test)] extern crate rand; +#[cfg(test)] #[macro_use] extern crate std; use conv::ApproxFrom; @@ -76,6 +78,14 @@ impl core::iter::FromIterator for Average { } } + macro_rules! assert_almost_eq { + ($a:expr, $b:expr, $prec:expr) => ( + if ($a - $b).abs() > $prec { + panic!(format!("assertion failed: `abs(left - right) < {:e}`, (left: `{}`, right: `{}`)", $prec, $a, $b)); + } + ); + } + #[cfg(test)] mod tests { use super::*; @@ -99,6 +109,18 @@ mod tests { assert_eq!(a.avg(), 3.0); assert_eq!(a.len(), 5); assert_eq!(a.var(), 2.5); - assert!((a.err() - f64::sqrt(0.5)).abs() < 1e-16); + assert_almost_eq!(a.err(), f64::sqrt(0.5), 1e-16); + } + + #[test] + fn average_normal_distribution() { + use rand::distributions::{Normal, IndependentSample}; + let normal = Normal::new(2.0, 3.0); + let mut a = Average::new(); + for _ in 0..1000000 { + a.add(normal.ind_sample(&mut ::rand::thread_rng())); + } + assert_almost_eq!(a.avg(), 2.0, 1e-2); + assert_almost_eq!(a.var().sqrt(), 3.0, 1e-2); } }