criterion/stats/univariate/
mod.rs
1mod bootstrap;
4mod percentiles;
5mod resamples;
6mod sample;
7
8pub mod kde;
9pub mod mixed;
10pub mod outliers;
11
12use rayon::prelude::*;
13use stats::float::Float;
14use std::cmp;
15
16use stats::tuple::{Tuple, TupledDistributionsBuilder};
17
18use self::resamples::Resamples;
19
20pub use self::percentiles::Percentiles;
21pub use self::sample::Sample;
22
23#[cfg_attr(feature = "cargo-clippy", allow(clippy::cast_lossless))]
29pub fn bootstrap<A, B, T, S>(
30 a: &Sample<A>,
31 b: &Sample<B>,
32 nresamples: usize,
33 statistic: S,
34) -> T::Distributions
35where
36 A: Float,
37 B: Float,
38 S: Fn(&Sample<A>, &Sample<B>) -> T,
39 S: Sync,
40 T: Tuple + Send,
41 T::Distributions: Send,
42 T::Builder: Send,
43{
44 let nresamples_sqrt = (nresamples as f64).sqrt().ceil() as usize;
45 let per_chunk = (nresamples + nresamples_sqrt - 1) / nresamples_sqrt;
46
47 (0..nresamples_sqrt)
48 .into_par_iter()
49 .map_init(
50 || (Resamples::new(a), Resamples::new(b)),
51 |(a_resamples, b_resamples), i| {
52 let start = i * per_chunk;
53 let end = cmp::min((i + 1) * per_chunk, nresamples);
54 let a_resample = a_resamples.next();
55
56 let mut sub_distributions: T::Builder =
57 TupledDistributionsBuilder::new(end - start);
58
59 for _ in start..end {
60 let b_resample = b_resamples.next();
61 sub_distributions.push(statistic(a_resample, b_resample));
62 }
63 sub_distributions
64 },
65 )
66 .reduce(
67 || T::Builder::new(0),
68 |mut a, mut b| {
69 a.extend(&mut b);
70 a
71 },
72 )
73 .complete()
74}