Skip to content

Commit

Permalink
test: treat tests on NIST data as integration tests
Browse files Browse the repository at this point in the history
also modify assert_almost_equal macro to support
option single trailing comma
  • Loading branch information
YeungOnion committed May 27, 2024
1 parent 12f7bf4 commit 977277b
Show file tree
Hide file tree
Showing 3 changed files with 154 additions and 121 deletions.
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@ extern crate approx;

#[macro_export]
macro_rules! assert_almost_eq {
($a:expr, $b:expr, $prec:expr) => {
($a:expr, $b:expr, $prec:expr $(,)?) => {
if !$crate::prec::almost_eq($a, $b, $prec) {
panic!(
"assertion failed: `abs(left - right) < {:e}`, (left: `{}`, right: `{}`)",
Expand Down
120 changes: 0 additions & 120 deletions src/statistics/iter_statistics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -252,126 +252,6 @@ mod tests {
use crate::generate::{InfinitePeriodic, InfiniteSinusoidal};
use crate::testing;

#[test]
fn test_mean() {
let mut data = testing::load_data("nist/lottery.txt");
assert_almost_eq!((&data).mean(), 518.958715596330, 1e-12);

data = testing::load_data("nist/lew.txt");
assert_almost_eq!((&data).mean(), -177.435000000000, 1e-13);

data = testing::load_data("nist/mavro.txt");
assert_almost_eq!((&data).mean(), 2.00185600000000, 1e-15);

data = testing::load_data("nist/michaelso.txt");
assert_almost_eq!((&data).mean(), 299.852400000000, 1e-13);

data = testing::load_data("nist/numacc1.txt");
assert_eq!((&data).mean(), 10000002.0);

data = testing::load_data("nist/numacc2.txt");
assert_almost_eq!((&data).mean(), 1.2, 1e-15);

data = testing::load_data("nist/numacc3.txt");
assert_eq!((&data).mean(), 1000000.2);

data = testing::load_data("nist/numacc4.txt");
assert_almost_eq!((&data).mean(), 10000000.2, 1e-8);
}

#[test]
fn test_std_dev() {
let mut data = testing::load_data("nist/lottery.txt");
assert_almost_eq!((&data).std_dev(), 291.699727470969, 1e-13);

data = testing::load_data("nist/lew.txt");
assert_almost_eq!((&data).std_dev(), 277.332168044316, 1e-12);

data = testing::load_data("nist/mavro.txt");
assert_almost_eq!((&data).std_dev(), 0.000429123454003053, 1e-15);

data = testing::load_data("nist/michaelso.txt");
assert_almost_eq!((&data).std_dev(), 0.0790105478190518, 1e-13);

data = testing::load_data("nist/numacc1.txt");
assert_eq!((&data).std_dev(), 1.0);

data = testing::load_data("nist/numacc2.txt");
assert_almost_eq!((&data).std_dev(), 0.1, 1e-16);

data = testing::load_data("nist/numacc3.txt");
assert_almost_eq!((&data).std_dev(), 0.1, 1e-10);

data = testing::load_data("nist/numacc4.txt");
assert_almost_eq!((&data).std_dev(), 0.1, 1e-9);
}

#[test]
fn test_min_max_short() {
let data = [-1.0, 5.0, 0.0, -3.0, 10.0, -0.5, 4.0];
assert_eq!(data.min(), -3.0);
assert_eq!(data.max(), 10.0);
}

#[test]
fn test_mean_variance_stability() {
let seed = [
0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18,
19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31
];
let mut rng: StdRng = SeedableRng::from_seed(seed);
let normal = Normal::new(1e9, 2.0).unwrap();
let samples = (0..10000).map(|_| normal.sample::<StdRng>(&mut rng)).collect::<Vec<f64>>();
assert_almost_eq!((&samples).mean(), 1e9, 10.0);
assert_almost_eq!((&samples).variance(), 4.0, 0.1);
assert_almost_eq!((&samples).std_dev(), 2.0, 0.01);
assert_almost_eq!((&samples).quadratic_mean(), 1e9, 10.0);
}

#[test]
fn test_covariance_consistent_with_variance() {
let mut data = testing::load_data("nist/lottery.txt");
assert_almost_eq!((&data).variance(), (&data).covariance(&data), 1e-10);

data = testing::load_data("nist/lew.txt");
assert_almost_eq!((&data).variance(), (&data).covariance(&data), 1e-10);

data = testing::load_data("nist/mavro.txt");
assert_almost_eq!((&data).variance(), (&data).covariance(&data), 1e-10);

data = testing::load_data("nist/michaelso.txt");
assert_almost_eq!((&data).variance(), (&data).covariance(&data), 1e-10);

data = testing::load_data("nist/numacc1.txt");
assert_almost_eq!((&data).variance(), (&data).covariance(&data), 1e-10);
}

#[test]
fn test_pop_covar_consistent_with_pop_var() {
let mut data = testing::load_data("nist/lottery.txt");
assert_almost_eq!((&data).population_variance(), (&data).population_covariance(&data), 1e-10);

data = testing::load_data("nist/lew.txt");
assert_almost_eq!((&data).population_variance(), (&data).population_covariance(&data), 1e-10);

data = testing::load_data("nist/mavro.txt");
assert_almost_eq!((&data).population_variance(), (&data).population_covariance(&data), 1e-10);

data = testing::load_data("nist/michaelso.txt");
assert_almost_eq!((&data).population_variance(), (&data).population_covariance(&data), 1e-10);

data = testing::load_data("nist/numacc1.txt");
assert_almost_eq!((&data).population_variance(), (&data).population_covariance(&data), 1e-10);
}

#[test]
fn test_covariance_is_symmetric() {
let data_a = &testing::load_data("nist/lottery.txt")[0..200];
let data_b = &testing::load_data("nist/lew.txt")[0..200];
assert_almost_eq!(data_a.covariance(data_b), data_b.covariance(data_a), 1e-10);
assert_almost_eq!(data_a.population_covariance(data_b), data_b.population_covariance(data_a), 1e-11);
}

#[test]
fn test_empty_data_returns_nan() {
let data = [0.0; 0];
Expand Down
153 changes: 153 additions & 0 deletions tests/nist_tests.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
// #![cfg(test)]
use statrs::assert_almost_eq;
use statrs::statistics::Statistics;
use std::io::{BufRead, BufReader};
use std::{env, fs};

#[cfg(test)]
const NIST_DATA_DIR_ENV: &str = "STATRS_NIST_DATA_DIR";

fn load_data(pathname: String) -> Vec<f64> {
let f = fs::File::open(pathname).unwrap();
let mut reader = BufReader::new(f);

let mut buf = String::new();
let mut data: Vec<f64> = vec![];
while reader.read_line(&mut buf).unwrap() > 0 {
data.push(buf.trim().parse::<f64>().unwrap());
buf.clear();
}
data
}

#[test]
#[ignore = "NIST tests should not run from typical `cargo test` calls"]
fn nist_test_mean() {
let path_dir = env::var(NIST_DATA_DIR_ENV).unwrap();
let mut data = load_data(dbg!(path_dir.clone() + "lottery.txt"));
assert_almost_eq!((&data).mean(), 518.958715596330, 1e-12);

data = load_data(dbg!(path_dir.clone() + "lew.txt"));
assert_almost_eq!((&data).mean(), -177.435000000000, 1e-13);

data = load_data(dbg!(path_dir.clone() + "mavro.txt"));
assert_almost_eq!((&data).mean(), 2.00185600000000, 1e-15);

data = load_data(dbg!(path_dir.clone() + "michaelso.txt"));
assert_almost_eq!((&data).mean(), 299.852400000000, 1e-13);

data = load_data(dbg!(path_dir.clone() + "numacc1.txt"));
assert_eq!((&data).mean(), 10000002.0);

data = load_data(dbg!(path_dir.clone() + "numacc2.txt"));
assert_almost_eq!((&data).mean(), 1.2, 1e-15);

data = load_data(dbg!(path_dir.clone() + "numacc3.txt"));
assert_eq!((&data).mean(), 1000000.2);

data = load_data(dbg!(path_dir.clone() + "numacc4.txt"));
assert_almost_eq!((&data).mean(), 10000000.2, 1e-8);
}

#[test]
#[ignore = "NIST tests should not run from typical `cargo test` calls"]
fn nist_test_std_dev() {
let path_dir = env::var(NIST_DATA_DIR_ENV).unwrap();
let mut data = load_data(dbg!(path_dir.clone() + "lottery.txt"));
assert_almost_eq!((&data).std_dev(), 291.699727470969, 1e-13);

data = load_data(dbg!(path_dir.clone() + "lew.txt"));
assert_almost_eq!((&data).std_dev(), 277.332168044316, 1e-12);

data = load_data(dbg!(path_dir.clone() + "mavro.txt"));
assert_almost_eq!((&data).std_dev(), 0.000429123454003053, 1e-15);

data = load_data(dbg!(path_dir.clone() + "michaelso.txt"));
assert_almost_eq!((&data).std_dev(), 0.0790105478190518, 1e-13);

data = load_data(dbg!(path_dir.clone() + "numacc1.txt"));
assert_eq!((&data).std_dev(), 1.0);

data = load_data(dbg!(path_dir.clone() + "numacc2.txt"));
assert_almost_eq!((&data).std_dev(), 0.1, 1e-16);

data = load_data(dbg!(path_dir.clone() + "numacc3.txt"));
assert_almost_eq!((&data).std_dev(), 0.1, 1e-10);

data = load_data(dbg!(path_dir.clone() + "numacc4.txt"));
assert_almost_eq!((&data).std_dev(), 0.1, 1e-9);
}

#[test]
#[ignore = "NIST tests should not run from typical `cargo test` calls"]
fn nist_test_covariance_consistent_with_variance() {
let path_dir = env::var(NIST_DATA_DIR_ENV).unwrap();
let mut data = load_data(dbg!(path_dir.clone() + "lottery.txt"));
assert_almost_eq!((&data).variance(), (&data).covariance(&data), 1e-10);

data = load_data(dbg!(path_dir.clone() + "lew.txt"));
assert_almost_eq!((&data).variance(), (&data).covariance(&data), 1e-10);

data = load_data(dbg!(path_dir.clone() + "mavro.txt"));
assert_almost_eq!((&data).variance(), (&data).covariance(&data), 1e-10);

data = load_data(dbg!(path_dir.clone() + "michaelso.txt"));
assert_almost_eq!((&data).variance(), (&data).covariance(&data), 1e-10);

data = load_data(dbg!(path_dir.clone() + "numacc1.txt"));
assert_almost_eq!((&data).variance(), (&data).covariance(&data), 1e-10);
}

#[test]
#[ignore = "NIST tests should not run from typical `cargo test` calls"]
fn nist_test_pop_covar_consistent_with_pop_var() {
let path_dir = env::var(NIST_DATA_DIR_ENV).unwrap();
let mut data = load_data(dbg!(path_dir.clone() + "lottery.txt"));
assert_almost_eq!(
(&data).population_variance(),
(&data).population_covariance(&data),
1e-10,
);

data = load_data(dbg!(path_dir.clone() + "lew.txt"));
assert_almost_eq!(
(&data).population_variance(),
(&data).population_covariance(&data),
1e-10,
);

data = load_data(dbg!(path_dir.clone() + "mavro.txt"));
assert_almost_eq!(
(&data).population_variance(),
(&data).population_covariance(&data),
1e-10,
);

data = load_data(dbg!(path_dir.clone() + "michaelso.txt"));
assert_almost_eq!(
(&data).population_variance(),
(&data).population_covariance(&data),
1e-10,
);

data = load_data(dbg!(path_dir.clone() + "numacc1.txt"));
assert_almost_eq!(
(&data).population_variance(),
(&data).population_covariance(&data),
1e-10,
);
}

#[test]
#[ignore = "NIST tests should not run from typical `cargo test` calls"]
fn nist_test_covariance_is_symmetric() {
let path_dir = env::var(NIST_DATA_DIR_ENV).unwrap();
let data_a = &load_data(dbg!(path_dir.clone() + "lottery.txt"))[0..200];
let data_b = &load_data(dbg!(path_dir.clone() + "lew.txt"))[0..200];
assert_almost_eq!(data_a.covariance(data_b), data_b.covariance(data_a), 1e-10);
assert_almost_eq!(
data_a.population_covariance(data_b),
data_b.population_covariance(data_a),
1e-11,
);
}

0 comments on commit 977277b

Please sign in to comment.