1 //! Mixed bootstrap
2
3 use crate::stats::float::Float;
4 use crate::stats::tuple::{Tuple, TupledDistributionsBuilder};
5 use crate::stats::univariate::Resamples;
6 use crate::stats::univariate::Sample;
7 use rayon::prelude::*;
8
9 /// Performs a *mixed* two-sample bootstrap
bootstrap<A, T, S>( a: &Sample<A>, b: &Sample<A>, nresamples: usize, statistic: S, ) -> T::Distributions where A: Float, S: Fn(&Sample<A>, &Sample<A>) -> T + Sync, T: Tuple + Send, T::Distributions: Send, T::Builder: Send,10 pub fn bootstrap<A, T, S>(
11 a: &Sample<A>,
12 b: &Sample<A>,
13 nresamples: usize,
14 statistic: S,
15 ) -> T::Distributions
16 where
17 A: Float,
18 S: Fn(&Sample<A>, &Sample<A>) -> T + Sync,
19 T: Tuple + Send,
20 T::Distributions: Send,
21 T::Builder: Send,
22 {
23 let n_a = a.len();
24 let n_b = b.len();
25 let mut c = Vec::with_capacity(n_a + n_b);
26 c.extend_from_slice(a);
27 c.extend_from_slice(b);
28 let c = Sample::new(&c);
29
30 (0..nresamples)
31 .into_par_iter()
32 .map_init(
33 || Resamples::new(c),
34 |resamples, _| {
35 let resample = resamples.next();
36 let a: &Sample<A> = Sample::new(&resample[..n_a]);
37 let b: &Sample<A> = Sample::new(&resample[n_a..]);
38
39 statistic(a, b)
40 },
41 )
42 .fold(
43 || T::Builder::new(0),
44 |mut sub_distributions, sample| {
45 sub_distributions.push(sample);
46 sub_distributions
47 },
48 )
49 .reduce(
50 || T::Builder::new(0),
51 |mut a, mut b| {
52 a.extend(&mut b);
53 a
54 },
55 )
56 .complete()
57 }
58