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