criterion/stats/univariate/
mixed.rs

1//! Mixed bootstrap
2
3use crate::stats::float::Float;
4use crate::stats::tuple::{Tuple, TupledDistributionsBuilder};
5use crate::stats::univariate::Resamples;
6use crate::stats::univariate::Sample;
7#[cfg(feature = "rayon")]
8use rayon::prelude::*;
9
10/// Performs a *mixed* two-sample bootstrap
11pub fn bootstrap<A, T, S>(
12    a: &Sample<A>,
13    b: &Sample<A>,
14    nresamples: usize,
15    statistic: S,
16) -> T::Distributions
17where
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}