1 #[cfg(test)] 2 macro_rules! test { 3 ($ty:ident) => { 4 mod $ty { 5 use approx::relative_eq; 6 use quickcheck::quickcheck; 7 use quickcheck::TestResult; 8 9 use crate::stats::univariate::{Sample, mixed, self}; 10 11 quickcheck!{ 12 fn mean(size: usize, start: usize, nresamples: usize) -> TestResult { 13 if let Some(v) = crate::stats::test::vec::<$ty>(size, start) { 14 let sample = Sample::new(&v[start..]); 15 16 let means = if nresamples > 0 { 17 sample.bootstrap(nresamples, |s| (s.mean(),)).0 18 } else { 19 return TestResult::discard(); 20 }; 21 22 let min = sample.min(); 23 let max = sample.max(); 24 25 TestResult::from_bool( 26 // Computed the correct number of resamples 27 means.len() == nresamples && 28 // No uninitialized values 29 means.iter().all(|&x| { 30 (x > min || relative_eq!(x, min)) && 31 (x < max || relative_eq!(x, max)) 32 }) 33 ) 34 } else { 35 TestResult::discard() 36 } 37 } 38 } 39 40 quickcheck!{ 41 fn mean_median(size: usize, start: usize, nresamples: usize) -> TestResult { 42 if let Some(v) = crate::stats::test::vec::<$ty>(size, start) { 43 let sample = Sample::new(&v[start..]); 44 45 let (means, medians) = if nresamples > 0 { 46 sample.bootstrap(nresamples, |s| (s.mean(), s.median())) 47 } else { 48 return TestResult::discard(); 49 }; 50 51 let min = sample.min(); 52 let max = sample.max(); 53 54 TestResult::from_bool( 55 // Computed the correct number of resamples 56 means.len() == nresamples && 57 medians.len() == nresamples && 58 // No uninitialized values 59 means.iter().all(|&x| { 60 (x > min || relative_eq!(x, min)) && 61 (x < max || relative_eq!(x, max)) 62 }) && 63 medians.iter().all(|&x| { 64 (x > min || relative_eq!(x, min)) && 65 (x < max || relative_eq!(x, max)) 66 }) 67 ) 68 } else { 69 TestResult::discard() 70 } 71 } 72 } 73 74 quickcheck!{ 75 fn mixed_two_sample( 76 a_size: usize, a_start: usize, 77 b_size: usize, b_start: usize, 78 nresamples: usize 79 ) -> TestResult { 80 if let (Some(a), Some(b)) = 81 (crate::stats::test::vec::<$ty>(a_size, a_start), crate::stats::test::vec::<$ty>(b_size, b_start)) 82 { 83 let a = Sample::new(&a); 84 let b = Sample::new(&b); 85 86 let distribution = if nresamples > 0 { 87 mixed::bootstrap(a, b, nresamples, |a, b| (a.mean() - b.mean(),)).0 88 } else { 89 return TestResult::discard(); 90 }; 91 92 let min = <$ty>::min(a.min() - b.max(), b.min() - a.max()); 93 let max = <$ty>::max(a.max() - b.min(), b.max() - a.min()); 94 95 TestResult::from_bool( 96 // Computed the correct number of resamples 97 distribution.len() == nresamples && 98 // No uninitialized values 99 distribution.iter().all(|&x| { 100 (x > min || relative_eq!(x, min)) && 101 (x < max || relative_eq!(x, max)) 102 }) 103 ) 104 } else { 105 TestResult::discard() 106 } 107 } 108 } 109 110 quickcheck!{ 111 fn two_sample( 112 a_size: usize, a_start: usize, 113 b_size: usize, b_start: usize, 114 nresamples: usize 115 ) -> TestResult { 116 if let (Some(a), Some(b)) = 117 (crate::stats::test::vec::<$ty>(a_size, a_start), crate::stats::test::vec::<$ty>(b_size, b_start)) 118 { 119 let a = Sample::new(&a[a_start..]); 120 let b = Sample::new(&b[b_start..]); 121 122 let distribution = if nresamples > 0 { 123 univariate::bootstrap(a, b, nresamples, |a, b| (a.mean() - b.mean(),)).0 124 } else { 125 return TestResult::discard(); 126 }; 127 128 let min = <$ty>::min(a.min() - b.max(), b.min() - a.max()); 129 let max = <$ty>::max(a.max() - b.min(), b.max() - a.min()); 130 131 // Computed the correct number of resamples 132 let pass = distribution.len() == nresamples && 133 // No uninitialized values 134 distribution.iter().all(|&x| { 135 (x > min || relative_eq!(x, min)) && 136 (x < max || relative_eq!(x, max)) 137 }); 138 139 if !pass { 140 println!("A: {:?} (len={})", a.as_ref(), a.len()); 141 println!("B: {:?} (len={})", b.as_ref(), b.len()); 142 println!("Dist: {:?} (len={})", distribution.as_ref(), distribution.len()); 143 println!("Min: {}, Max: {}, nresamples: {}", 144 min, max, nresamples); 145 } 146 147 TestResult::from_bool(pass) 148 } else { 149 TestResult::discard() 150 } 151 } 152 } 153 } 154 } 155 } 156 157 #[cfg(test)] 158 mod test { 159 test!(f32); 160 test!(f64); 161 } 162