1 use std::mem; 2 3 use crate::stats::float::Float; 4 use crate::stats::rand_util::{new_rng, Rng}; 5 use crate::stats::univariate::Sample; 6 7 pub struct Resamples<'a, A> 8 where 9 A: Float, 10 { 11 rng: Rng, 12 sample: &'a [A], 13 stage: Option<Vec<A>>, 14 } 15 16 #[cfg_attr(feature = "cargo-clippy", allow(clippy::should_implement_trait))] 17 impl<'a, A> Resamples<'a, A> 18 where 19 A: 'a + Float, 20 { new(sample: &'a Sample<A>) -> Resamples<'a, A>21 pub fn new(sample: &'a Sample<A>) -> Resamples<'a, A> { 22 let slice = sample; 23 24 Resamples { 25 rng: new_rng(), 26 sample: slice, 27 stage: None, 28 } 29 } 30 next(&mut self) -> &Sample<A>31 pub fn next(&mut self) -> &Sample<A> { 32 let n = self.sample.len(); 33 let rng = &mut self.rng; 34 35 match self.stage { 36 None => { 37 let mut stage = Vec::with_capacity(n); 38 39 for _ in 0..n { 40 let idx = rng.rand_range(0u64..(self.sample.len() as u64)); 41 stage.push(self.sample[idx as usize]) 42 } 43 44 self.stage = Some(stage); 45 } 46 Some(ref mut stage) => { 47 for elem in stage.iter_mut() { 48 let idx = rng.rand_range(0u64..(self.sample.len() as u64)); 49 *elem = self.sample[idx as usize] 50 } 51 } 52 } 53 54 if let Some(ref v) = self.stage { 55 unsafe { mem::transmute::<&[_], _>(v) } 56 } else { 57 unreachable!(); 58 } 59 } 60 } 61 62 #[cfg(test)] 63 mod test { 64 use quickcheck::quickcheck; 65 use quickcheck::TestResult; 66 use std::collections::HashSet; 67 68 use crate::stats::univariate::resamples::Resamples; 69 use crate::stats::univariate::Sample; 70 71 // Check that the resample is a subset of the sample 72 quickcheck! { 73 fn subset(size: u8, nresamples: u8) -> TestResult { 74 let size = size as usize; 75 let nresamples = nresamples as usize; 76 if size > 1 { 77 let v: Vec<_> = (0..size).map(|i| i as f32).collect(); 78 let sample = Sample::new(&v); 79 let mut resamples = Resamples::new(sample); 80 let sample = v.iter().map(|&x| x as i64).collect::<HashSet<_>>(); 81 82 TestResult::from_bool((0..nresamples).all(|_| { 83 let resample = resamples.next() 84 85 .iter() 86 .map(|&x| x as i64) 87 .collect::<HashSet<_>>(); 88 89 resample.is_subset(&sample) 90 })) 91 } else { 92 TestResult::discard() 93 } 94 } 95 } 96 97 #[test] different_subsets()98 fn different_subsets() { 99 let size = 1000; 100 let v: Vec<_> = (0..size).map(|i| i as f32).collect(); 101 let sample = Sample::new(&v); 102 let mut resamples = Resamples::new(sample); 103 104 // Hypothetically, we might see one duplicate, but more than one is likely to be a bug. 105 let mut num_duplicated = 0; 106 for _ in 0..1000 { 107 let sample_1 = resamples.next().iter().cloned().collect::<Vec<_>>(); 108 let sample_2 = resamples.next().iter().cloned().collect::<Vec<_>>(); 109 110 if sample_1 == sample_2 { 111 num_duplicated += 1; 112 } 113 } 114 115 if num_duplicated > 1 { 116 panic!("Found {} duplicate samples", num_duplicated); 117 } 118 } 119 } 120