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 #[cfg(feature = "rayon")]
8 use rayon::prelude::*;
9 
10 /// 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,11 pub fn bootstrap<A, T, S>(
12     a: &Sample<A>,
13     b: &Sample<A>,
14     nresamples: usize,
15     statistic: S,
16 ) -> T::Distributions
17 where
18     A: Float,
19     S: Fn(&Sample<A>, &Sample<A>) -> T + Sync,
20     T: Tuple + Send,
21     T::Distributions: Send,
22     T::Builder: Send,
23 {
24     let n_a = a.len();
25     let n_b = b.len();
26     let mut c = Vec::with_capacity(n_a + n_b);
27     c.extend_from_slice(a);
28     c.extend_from_slice(b);
29     let c = Sample::new(&c);
30 
31     #[cfg(feature = "rayon")]
32     {
33         (0..nresamples)
34             .into_par_iter()
35             .map_init(
36                 || Resamples::new(c),
37                 |resamples, _| {
38                     let resample = resamples.next();
39                     let a: &Sample<A> = Sample::new(&resample[..n_a]);
40                     let b: &Sample<A> = Sample::new(&resample[n_a..]);
41 
42                     statistic(a, b)
43                 },
44             )
45             .fold(
46                 || T::Builder::new(0),
47                 |mut sub_distributions, sample| {
48                     sub_distributions.push(sample);
49                     sub_distributions
50                 },
51             )
52             .reduce(
53                 || T::Builder::new(0),
54                 |mut a, mut b| {
55                     a.extend(&mut b);
56                     a
57                 },
58             )
59             .complete()
60     }
61     #[cfg(not(feature = "rayon"))]
62     {
63         let mut resamples = Resamples::new(c);
64         (0..nresamples)
65             .map(|_| {
66                 let resample = resamples.next();
67                 let a: &Sample<A> = Sample::new(&resample[..n_a]);
68                 let b: &Sample<A> = Sample::new(&resample[n_a..]);
69 
70                 statistic(a, b)
71             })
72             .fold(T::Builder::new(0), |mut sub_distributions, sample| {
73                 sub_distributions.push(sample);
74                 sub_distributions
75             })
76             .complete()
77     }
78 }
79