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: usize, nresamples: usize) -> TestResult { 74 if size > 1 { 75 let v: Vec<_> = (0..size).map(|i| i as f32).collect(); 76 let sample = Sample::new(&v); 77 let mut resamples = Resamples::new(sample); 78 let sample = v.iter().map(|&x| x as i64).collect::<HashSet<_>>(); 79 80 TestResult::from_bool((0..nresamples).all(|_| { 81 let resample = resamples.next() 82 83 .iter() 84 .map(|&x| x as i64) 85 .collect::<HashSet<_>>(); 86 87 resample.is_subset(&sample) 88 })) 89 } else { 90 TestResult::discard() 91 } 92 } 93 } 94 95 #[test] different_subsets()96 fn different_subsets() { 97 let size = 1000; 98 let v: Vec<_> = (0..size).map(|i| i as f32).collect(); 99 let sample = Sample::new(&v); 100 let mut resamples = Resamples::new(sample); 101 102 // Hypothetically, we might see one duplicate, but more than one is likely to be a bug. 103 let mut num_duplicated = 0; 104 for _ in 0..1000 { 105 let sample_1 = resamples.next().iter().cloned().collect::<Vec<_>>(); 106 let sample_2 = resamples.next().iter().cloned().collect::<Vec<_>>(); 107 108 if sample_1 == sample_2 { 109 num_duplicated += 1; 110 } 111 } 112 113 if num_duplicated > 1 { 114 panic!("Found {} duplicate samples", num_duplicated); 115 } 116 } 117 } 118