criterion_stats/bivariate/
resamples.rs

1use float::Float;
2use rand::distributions::{IndependentSample, Range};
3use rand::{Rng, XorShiftRng};
4
5use bivariate::Data;
6
7pub struct Resamples<'a, X, Y>
8where
9    X: 'a + Float,
10    Y: 'a + Float,
11{
12    range: Range<usize>,
13    rng: XorShiftRng,
14    data: (&'a [X], &'a [Y]),
15    stage: Option<(Vec<X>, Vec<Y>)>,
16}
17
18#[cfg_attr(feature = "cargo-clippy", allow(clippy::should_implement_trait))]
19impl<'a, X, Y> Resamples<'a, X, Y>
20where
21    X: 'a + Float,
22    Y: 'a + Float,
23{
24    pub fn new(data: Data<'a, X, Y>) -> Resamples<'a, X, Y> {
25        Resamples {
26            range: Range::new(0, data.0.len()),
27            rng: ::rand::thread_rng().gen(),
28            data: (data.x(), data.y()),
29            stage: None,
30        }
31    }
32
33    pub fn next(&mut self) -> Data<X, Y> {
34        let n = self.data.0.len();
35        let rng = &mut self.rng;
36
37        match self.stage {
38            None => {
39                let mut stage = (Vec::with_capacity(n), Vec::with_capacity(n));
40
41                for _ in 0..n {
42                    let i = self.range.ind_sample(rng);
43
44                    stage.0.push(self.data.0[i]);
45                    stage.1.push(self.data.1[i]);
46                }
47
48                self.stage = Some(stage);
49            }
50            Some(ref mut stage) => {
51                for i in 0..n {
52                    let j = self.range.ind_sample(rng);
53
54                    stage.0[i] = self.data.0[j];
55                    stage.1[i] = self.data.1[j];
56                }
57            }
58        }
59
60        if let Some((ref x, ref y)) = self.stage {
61            Data(x, y)
62        } else {
63            unreachable!();
64        }
65    }
66}