blob: 21c914011e554d178087e4746875a704c7e1a9be [file] [log] [blame]
#[cfg(test)]
macro_rules! test {
($ty:ident) => {
mod $ty {
use approx::relative_eq;
use quickcheck::quickcheck;
use quickcheck::TestResult;
use crate::stats::univariate::{Sample, mixed, self};
quickcheck!{
fn mean(size: u8, start: u8, nresamples: u8) -> TestResult {
let size = size as usize;
let start = start as usize;
let nresamples = nresamples as usize;
if let Some(v) = crate::stats::test::vec::<$ty>(size, start) {
let sample = Sample::new(&v[start..]);
let means = if nresamples > 0 {
sample.bootstrap(nresamples, |s| (s.mean(),)).0
} else {
return TestResult::discard();
};
let min = sample.min();
let max = sample.max();
TestResult::from_bool(
// Computed the correct number of resamples
means.len() == nresamples &&
// No uninitialized values
means.iter().all(|&x| {
(x > min || relative_eq!(x, min)) &&
(x < max || relative_eq!(x, max))
})
)
} else {
TestResult::discard()
}
}
}
quickcheck!{
fn mean_median(size: u8, start: u8, nresamples: u8) -> TestResult {
let size = size as usize;
let start = start as usize;
let nresamples = nresamples as usize;
if let Some(v) = crate::stats::test::vec::<$ty>(size, start) {
let sample = Sample::new(&v[start..]);
let (means, medians) = if nresamples > 0 {
sample.bootstrap(nresamples, |s| (s.mean(), s.median()))
} else {
return TestResult::discard();
};
let min = sample.min();
let max = sample.max();
TestResult::from_bool(
// Computed the correct number of resamples
means.len() == nresamples &&
medians.len() == nresamples &&
// No uninitialized values
means.iter().all(|&x| {
(x > min || relative_eq!(x, min)) &&
(x < max || relative_eq!(x, max))
}) &&
medians.iter().all(|&x| {
(x > min || relative_eq!(x, min)) &&
(x < max || relative_eq!(x, max))
})
)
} else {
TestResult::discard()
}
}
}
quickcheck!{
fn mixed_two_sample(
a_size: u8, a_start: u8,
b_size: u8, b_start: u8,
nresamples: u8
) -> TestResult {
let a_size = a_size as usize;
let b_size = b_size as usize;
let a_start = a_start as usize;
let b_start = b_start as usize;
let nresamples = nresamples as usize;
if let (Some(a), Some(b)) =
(crate::stats::test::vec::<$ty>(a_size, a_start), crate::stats::test::vec::<$ty>(b_size, b_start))
{
let a = Sample::new(&a);
let b = Sample::new(&b);
let distribution = if nresamples > 0 {
mixed::bootstrap(a, b, nresamples, |a, b| (a.mean() - b.mean(),)).0
} else {
return TestResult::discard();
};
let min = <$ty>::min(a.min() - b.max(), b.min() - a.max());
let max = <$ty>::max(a.max() - b.min(), b.max() - a.min());
TestResult::from_bool(
// Computed the correct number of resamples
distribution.len() == nresamples &&
// No uninitialized values
distribution.iter().all(|&x| {
(x > min || relative_eq!(x, min)) &&
(x < max || relative_eq!(x, max))
})
)
} else {
TestResult::discard()
}
}
}
quickcheck!{
fn two_sample(
a_size: u8, a_start: u8,
b_size: u8, b_start: u8,
nresamples: u8
) -> TestResult {
let a_size = a_size as usize;
let b_size = b_size as usize;
let a_start = a_start as usize;
let b_start = b_start as usize;
let nresamples = nresamples as usize;
if let (Some(a), Some(b)) =
(crate::stats::test::vec::<$ty>(a_size, a_start), crate::stats::test::vec::<$ty>(b_size, b_start))
{
let a = Sample::new(&a[a_start..]);
let b = Sample::new(&b[b_start..]);
let distribution = if nresamples > 0 {
univariate::bootstrap(a, b, nresamples, |a, b| (a.mean() - b.mean(),)).0
} else {
return TestResult::discard();
};
let min = <$ty>::min(a.min() - b.max(), b.min() - a.max());
let max = <$ty>::max(a.max() - b.min(), b.max() - a.min());
// Computed the correct number of resamples
let pass = distribution.len() == nresamples &&
// No uninitialized values
distribution.iter().all(|&x| {
(x > min || relative_eq!(x, min)) &&
(x < max || relative_eq!(x, max))
});
if !pass {
println!("A: {:?} (len={})", a.as_ref(), a.len());
println!("B: {:?} (len={})", b.as_ref(), b.len());
println!("Dist: {:?} (len={})", distribution.as_ref(), distribution.len());
println!("Min: {}, Max: {}, nresamples: {}",
min, max, nresamples);
}
TestResult::from_bool(pass)
} else {
TestResult::discard()
}
}
}
}
}
}
#[cfg(test)]
mod test {
test!(f32);
test!(f64);
}