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