From d25f267529da19fc18b1c2c1e8cf15fec18202c5 Mon Sep 17 00:00:00 2001 From: Vinzent Steinberg Date: Fri, 19 May 2017 15:54:13 +0200 Subject: [PATCH] Move some tests from src to tests --- src/average.rs | 50 ------------------------- src/weighted_average.rs | 49 ------------------------ src/weighted_average2.rs | 61 ------------------------------ tests/average.rs | 76 ++++++++++++++++++++++++-------------- tests/streaming_stats.rs | 35 ++++++++++++++++++ tests/weighted_average.rs | 54 +++++++++++++++++++++++++++ tests/weighted_average2.rs | 66 +++++++++++++++++++++++++++++++++ 7 files changed, 204 insertions(+), 187 deletions(-) create mode 100644 tests/streaming_stats.rs create mode 100644 tests/weighted_average.rs create mode 100644 tests/weighted_average2.rs diff --git a/src/average.rs b/src/average.rs index 1bcf5dd..3cadd5e 100644 --- a/src/average.rs +++ b/src/average.rs @@ -141,56 +141,6 @@ impl core::iter::FromIterator for Average { mod tests { use super::*; - use core::iter::Iterator; - - #[test] - fn trivial() { - let mut a = Average::new(); - assert_eq!(a.len(), 0); - a.add(1.0); - assert_eq!(a.mean(), 1.0); - assert_eq!(a.len(), 1); - assert_eq!(a.sample_variance(), 0.0); - assert_eq!(a.population_variance(), 0.0); - assert_eq!(a.error(), 0.0); - a.add(1.0); - assert_eq!(a.mean(), 1.0); - assert_eq!(a.len(), 2); - assert_eq!(a.sample_variance(), 0.0); - assert_eq!(a.population_variance(), 0.0); - assert_eq!(a.error(), 0.0); - } - - #[test] - fn simple() { - let a: Average = (1..6).map(f64::from).collect(); - assert_eq!(a.mean(), 3.0); - assert_eq!(a.len(), 5); - assert_eq!(a.sample_variance(), 2.5); - assert_almost_eq!(a.error(), f64::sqrt(0.5), 1e-16); - } - - #[test] - fn numerically_unstable() { - // The naive algorithm fails for this example due to cancelation. - let big = 1e9; - let sample = &[big + 4., big + 7., big + 13., big + 16.]; - let a: Average = sample.iter().map(|x| *x).collect(); - assert_eq!(a.sample_variance(), 30.); - } - - #[test] - fn normal_distribution() { - use rand::distributions::{Normal, IndependentSample}; - let normal = Normal::new(2.0, 3.0); - let mut a = Average::new(); - for _ in 0..1_000_000 { - a.add(normal.ind_sample(&mut ::rand::thread_rng())); - } - assert_almost_eq!(a.mean(), 2.0, 1e-2); - assert_almost_eq!(a.sample_variance().sqrt(), 3.0, 1e-2); - } - #[test] fn merge() { let sequence: &[f64] = &[1., 2., 3., 4., 5., 6., 7., 8., 9.]; diff --git a/src/weighted_average.rs b/src/weighted_average.rs index 4ef5992..0c39595 100644 --- a/src/weighted_average.rs +++ b/src/weighted_average.rs @@ -144,55 +144,6 @@ impl core::iter::FromIterator<(f64, f64)> for WeightedAverage { mod tests { use super::*; - use core::iter::Iterator; - - #[test] - fn trivial() { - let mut a = WeightedAverage::new(); - assert_eq!(a.sum_weights(), 0.); - a.add(1.0, 1.0); - assert_eq!(a.mean(), 1.0); - assert_eq!(a.sum_weights(), 1.0); - assert_eq!(a.population_variance(), 0.0); - assert_eq!(a.error(), 0.0); - a.add(1.0, 1.0); - assert_eq!(a.mean(), 1.0); - assert_eq!(a.sum_weights(), 2.0); - assert_eq!(a.population_variance(), 0.0); - assert_eq!(a.error(), 0.0); - } - - #[test] - fn simple() { - let a: WeightedAverage = (1..6).map(|x| (f64::from(x), 1.0)).collect(); - assert_eq!(a.mean(), 3.0); - assert_eq!(a.sum_weights(), 5.0); - assert_eq!(a.sample_variance(), 2.5); - assert_almost_eq!(a.error(), f64::sqrt(0.5), 1e-16); - } - - #[test] - fn reference() { - // Example from http://www.analyticalgroup.com/download/WEIGHTED_MEAN.pdf. - let values = &[5., 5., 4., 4., 3., 4., 3., 2., 2., 1.]; - let weights = &[1.23, 2.12, 1.23, 0.32, 1.53, 0.59, 0.94, 0.94, 0.84, 0.73]; - let a: WeightedAverage = values.iter().zip(weights.iter()) - .map(|(x, w)| (*x, *w)).collect(); - assert_almost_eq!(a.mean(), 3.53486, 1e-5); - assert_almost_eq!(a.sample_variance(), 1.8210, 1e-4); - assert_eq!(a.sum_weights(), 10.47); - assert_almost_eq!(a.error(), f64::sqrt(0.1739), 1e-4); - } - - #[test] - fn error_corner_case() { - let values = &[1., 2.]; - let weights = &[0.5, 0.5]; - let a: WeightedAverage = values.iter().zip(weights.iter()) - .map(|(x, w)| (*x, *w)).collect(); - assert_eq!(a.error(), 0.5); - } - #[test] fn merge_unweighted() { let sequence: &[f64] = &[1., 2., 3., 4., 5., 6., 7., 8., 9.]; diff --git a/src/weighted_average2.rs b/src/weighted_average2.rs index 34bc42f..479b6bf 100644 --- a/src/weighted_average2.rs +++ b/src/weighted_average2.rs @@ -187,67 +187,6 @@ impl core::iter::FromIterator<(f64, f64)> for WeightedAverage { mod tests { use super::*; - use core::iter::Iterator; - - #[test] - fn trivial() { - let mut a = WeightedAverage::new(); - assert_eq!(a.len(), 0); - assert_eq!(a.sum_weights(), 0.); - assert_eq!(a.sum_weights_sq(), 0.); - a.add(1.0, 1.0); - assert_eq!(a.len(), 1); - assert_eq!(a.weighted_mean(), 1.0); - assert_eq!(a.unweighted_mean(), 1.0); - assert_eq!(a.sum_weights(), 1.0); - assert_eq!(a.sum_weights_sq(), 1.0); - assert_eq!(a.population_variance(), 0.0); - assert_eq!(a.error(), 0.0); - a.add(1.0, 1.0); - assert_eq!(a.len(), 2); - assert_eq!(a.weighted_mean(), 1.0); - assert_eq!(a.unweighted_mean(), 1.0); - assert_eq!(a.sum_weights(), 2.0); - assert_eq!(a.sum_weights_sq(), 2.0); - assert_eq!(a.population_variance(), 0.0); - assert_eq!(a.error(), 0.0); - } - - #[test] - fn simple() { - let a: WeightedAverage = (1..6).map(|x| (f64::from(x), 1.0)).collect(); - assert_eq!(a.len(), 5); - assert_eq!(a.weighted_mean(), 3.0); - assert_eq!(a.unweighted_mean(), 3.0); - assert_eq!(a.sum_weights(), 5.0); - assert_eq!(a.sample_variance(), 2.5); - assert_almost_eq!(a.error(), f64::sqrt(0.5), 1e-16); - } - - #[test] - fn reference() { - // Example from http://www.analyticalgroup.com/download/WEIGHTED_MEAN.pdf. - let values = &[5., 5., 4., 4., 3., 4., 3., 2., 2., 1.]; - let weights = &[1.23, 2.12, 1.23, 0.32, 1.53, 0.59, 0.94, 0.94, 0.84, 0.73]; - let a: WeightedAverage = values.iter().zip(weights.iter()) - .map(|(x, w)| (*x, *w)).collect(); - assert_almost_eq!(a.weighted_mean(), 3.53486, 1e-5); - assert_almost_eq!(a.sample_variance(), 1.7889, 1e-4); - assert_eq!(a.sum_weights(), 10.47); - assert_eq!(a.len(), 10); - assert_almost_eq!(a.effective_len(), 8.2315, 1e-4); - assert_almost_eq!(a.error(), f64::sqrt(0.2173), 1e-4); - } - - #[test] - fn error_corner_case() { - let values = &[1., 2.]; - let weights = &[0.5, 0.5]; - let a: WeightedAverage = values.iter().zip(weights.iter()) - .map(|(x, w)| (*x, *w)).collect(); - assert_eq!(a.error(), 0.5); - } - #[test] fn merge_unweighted() { let sequence: &[f64] = &[1., 2., 3., 4., 5., 6., 7., 8., 9.]; diff --git a/tests/average.rs b/tests/average.rs index e6892f4..a48dd07 100644 --- a/tests/average.rs +++ b/tests/average.rs @@ -1,35 +1,57 @@ #[macro_use] extern crate average; +extern crate core; + extern crate rand; -extern crate stats; -/// Create a random vector by sampling from a normal distribution. -fn initialize_vec(size: usize) -> Vec { +use core::iter::Iterator; + +use average::Average; + +#[test] +fn trivial() { + let mut a = Average::new(); + assert_eq!(a.len(), 0); + a.add(1.0); + assert_eq!(a.mean(), 1.0); + assert_eq!(a.len(), 1); + assert_eq!(a.sample_variance(), 0.0); + assert_eq!(a.population_variance(), 0.0); + assert_eq!(a.error(), 0.0); + a.add(1.0); + assert_eq!(a.mean(), 1.0); + assert_eq!(a.len(), 2); + assert_eq!(a.sample_variance(), 0.0); + assert_eq!(a.population_variance(), 0.0); + assert_eq!(a.error(), 0.0); +} + +#[test] +fn simple() { + let a: Average = (1..6).map(f64::from).collect(); + assert_eq!(a.mean(), 3.0); + assert_eq!(a.len(), 5); + assert_eq!(a.sample_variance(), 2.5); + assert_almost_eq!(a.error(), f64::sqrt(0.5), 1e-16); +} + +#[test] +fn numerically_unstable() { + // The naive algorithm fails for this example due to cancelation. + let big = 1e9; + let sample = &[big + 4., big + 7., big + 13., big + 16.]; + let a: Average = sample.iter().map(|x| *x).collect(); + assert_eq!(a.sample_variance(), 30.); +} + +#[test] +fn normal_distribution() { use rand::distributions::{Normal, IndependentSample}; - use rand::{XorShiftRng, SeedableRng}; let normal = Normal::new(2.0, 3.0); - let mut values = Vec::with_capacity(size); - let mut rng = XorShiftRng::from_seed([1, 2, 3, 4]); - for _ in 0..size { - values.push(normal.ind_sample(&mut rng)); + let mut a = Average::new(); + for _ in 0..1_000_000 { + a.add(normal.ind_sample(&mut ::rand::thread_rng())); } - values -} - -#[test] -fn average_vs_streaming_stats_small() { - let values = initialize_vec(100); - let a: average::Average = values.iter().map(|x| *x).collect(); - let b: stats::OnlineStats = values.iter().map(|x| *x).collect(); - assert_almost_eq!(a.mean(), b.mean(), 1e-16); - assert_almost_eq!(a.population_variance(), b.variance(), 1e-16); -} - -#[test] -fn average_vs_streaming_stats_large() { - let values = initialize_vec(1_000_000); - let a: average::Average = values.iter().map(|x| *x).collect(); - let b: stats::OnlineStats = values.iter().map(|x| *x).collect(); - assert_almost_eq!(a.mean(), b.mean(), 1e-16); - assert_almost_eq!(a.population_variance(), b.variance(), 1e-13); + assert_almost_eq!(a.mean(), 2.0, 1e-2); + assert_almost_eq!(a.sample_variance().sqrt(), 3.0, 1e-2); } diff --git a/tests/streaming_stats.rs b/tests/streaming_stats.rs new file mode 100644 index 0000000..e6892f4 --- /dev/null +++ b/tests/streaming_stats.rs @@ -0,0 +1,35 @@ +#[macro_use] extern crate average; + +extern crate rand; +extern crate stats; + +/// Create a random vector by sampling from a normal distribution. +fn initialize_vec(size: usize) -> Vec { + use rand::distributions::{Normal, IndependentSample}; + use rand::{XorShiftRng, SeedableRng}; + let normal = Normal::new(2.0, 3.0); + let mut values = Vec::with_capacity(size); + let mut rng = XorShiftRng::from_seed([1, 2, 3, 4]); + for _ in 0..size { + values.push(normal.ind_sample(&mut rng)); + } + values +} + +#[test] +fn average_vs_streaming_stats_small() { + let values = initialize_vec(100); + let a: average::Average = values.iter().map(|x| *x).collect(); + let b: stats::OnlineStats = values.iter().map(|x| *x).collect(); + assert_almost_eq!(a.mean(), b.mean(), 1e-16); + assert_almost_eq!(a.population_variance(), b.variance(), 1e-16); +} + +#[test] +fn average_vs_streaming_stats_large() { + let values = initialize_vec(1_000_000); + let a: average::Average = values.iter().map(|x| *x).collect(); + let b: stats::OnlineStats = values.iter().map(|x| *x).collect(); + assert_almost_eq!(a.mean(), b.mean(), 1e-16); + assert_almost_eq!(a.population_variance(), b.variance(), 1e-13); +} diff --git a/tests/weighted_average.rs b/tests/weighted_average.rs new file mode 100644 index 0000000..05f0053 --- /dev/null +++ b/tests/weighted_average.rs @@ -0,0 +1,54 @@ +#[macro_use] extern crate average; + +extern crate core; + +use core::iter::Iterator; + +use average::WeightedAverage; + +#[test] +fn trivial() { + let mut a = WeightedAverage::new(); + assert_eq!(a.sum_weights(), 0.); + a.add(1.0, 1.0); + assert_eq!(a.mean(), 1.0); + assert_eq!(a.sum_weights(), 1.0); + assert_eq!(a.population_variance(), 0.0); + assert_eq!(a.error(), 0.0); + a.add(1.0, 1.0); + assert_eq!(a.mean(), 1.0); + assert_eq!(a.sum_weights(), 2.0); + assert_eq!(a.population_variance(), 0.0); + assert_eq!(a.error(), 0.0); +} + +#[test] +fn simple() { + let a: WeightedAverage = (1..6).map(|x| (f64::from(x), 1.0)).collect(); + assert_eq!(a.mean(), 3.0); + assert_eq!(a.sum_weights(), 5.0); + assert_eq!(a.sample_variance(), 2.5); + assert_almost_eq!(a.error(), f64::sqrt(0.5), 1e-16); +} + +#[test] +fn reference() { + // Example from http://www.analyticalgroup.com/download/WEIGHTED_MEAN.pdf. + let values = &[5., 5., 4., 4., 3., 4., 3., 2., 2., 1.]; + let weights = &[1.23, 2.12, 1.23, 0.32, 1.53, 0.59, 0.94, 0.94, 0.84, 0.73]; + let a: WeightedAverage = values.iter().zip(weights.iter()) + .map(|(x, w)| (*x, *w)).collect(); + assert_almost_eq!(a.mean(), 3.53486, 1e-5); + assert_almost_eq!(a.sample_variance(), 1.8210, 1e-4); + assert_eq!(a.sum_weights(), 10.47); + assert_almost_eq!(a.error(), f64::sqrt(0.1739), 1e-4); +} + +#[test] +fn error_corner_case() { + let values = &[1., 2.]; + let weights = &[0.5, 0.5]; + let a: WeightedAverage = values.iter().zip(weights.iter()) + .map(|(x, w)| (*x, *w)).collect(); + assert_eq!(a.error(), 0.5); +} diff --git a/tests/weighted_average2.rs b/tests/weighted_average2.rs new file mode 100644 index 0000000..d4cf3f1 --- /dev/null +++ b/tests/weighted_average2.rs @@ -0,0 +1,66 @@ +#[macro_use] extern crate average; + +extern crate core; + +use core::iter::Iterator; + +use average::WeightedAverage2 as WeightedAverage; + +#[test] +fn trivial() { + let mut a = WeightedAverage::new(); + assert_eq!(a.len(), 0); + assert_eq!(a.sum_weights(), 0.); + assert_eq!(a.sum_weights_sq(), 0.); + a.add(1.0, 1.0); + assert_eq!(a.len(), 1); + assert_eq!(a.weighted_mean(), 1.0); + assert_eq!(a.unweighted_mean(), 1.0); + assert_eq!(a.sum_weights(), 1.0); + assert_eq!(a.sum_weights_sq(), 1.0); + assert_eq!(a.population_variance(), 0.0); + assert_eq!(a.error(), 0.0); + a.add(1.0, 1.0); + assert_eq!(a.len(), 2); + assert_eq!(a.weighted_mean(), 1.0); + assert_eq!(a.unweighted_mean(), 1.0); + assert_eq!(a.sum_weights(), 2.0); + assert_eq!(a.sum_weights_sq(), 2.0); + assert_eq!(a.population_variance(), 0.0); + assert_eq!(a.error(), 0.0); +} + +#[test] +fn simple() { + let a: WeightedAverage = (1..6).map(|x| (f64::from(x), 1.0)).collect(); + assert_eq!(a.len(), 5); + assert_eq!(a.weighted_mean(), 3.0); + assert_eq!(a.unweighted_mean(), 3.0); + assert_eq!(a.sum_weights(), 5.0); + assert_eq!(a.sample_variance(), 2.5); + assert_almost_eq!(a.error(), f64::sqrt(0.5), 1e-16); +} + +#[test] +fn reference() { + // Example from http://www.analyticalgroup.com/download/WEIGHTED_MEAN.pdf. + let values = &[5., 5., 4., 4., 3., 4., 3., 2., 2., 1.]; + let weights = &[1.23, 2.12, 1.23, 0.32, 1.53, 0.59, 0.94, 0.94, 0.84, 0.73]; + let a: WeightedAverage = values.iter().zip(weights.iter()) + .map(|(x, w)| (*x, *w)).collect(); + assert_almost_eq!(a.weighted_mean(), 3.53486, 1e-5); + assert_almost_eq!(a.sample_variance(), 1.7889, 1e-4); + assert_eq!(a.sum_weights(), 10.47); + assert_eq!(a.len(), 10); + assert_almost_eq!(a.effective_len(), 8.2315, 1e-4); + assert_almost_eq!(a.error(), f64::sqrt(0.2173), 1e-4); +} + +#[test] +fn error_corner_case() { + let values = &[1., 2.]; + let weights = &[0.5, 0.5]; + let a: WeightedAverage = values.iter().zip(weights.iter()) + .map(|(x, w)| (*x, *w)).collect(); + assert_eq!(a.error(), 0.5); +}