criterion_stats/bivariate/
resamples.rs1use 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}