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                            // Computed the correct number of resamples
25                            means.len() == nresamples &&
26                            // No uninitialized values
27                            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                            // Computed the correct number of resamples
54                            means.len() == nresamples &&
55                            medians.len() == nresamples &&
56                            // No uninitialized values
57                            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                            // Computed the correct number of resamples
95                            distribution.len() == nresamples &&
96                            // No uninitialized values
97                            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                        // Computed the correct number of resamples
130                        let pass = distribution.len() == nresamples &&
131                            // No uninitialized values
132                            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}