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