criterion/stats/bivariate/
mod.rsmod bootstrap;
mod resamples;
pub mod regression;
use rayon::prelude::*;
use stats::float::Float;
use stats::bivariate::resamples::Resamples;
use stats::tuple::{Tuple, TupledDistributionsBuilder};
use stats::univariate::Sample;
pub struct Data<'a, X, Y>(&'a [X], &'a [Y])
where
X: 'a,
Y: 'a;
impl<'a, X, Y> Copy for Data<'a, X, Y> {}
#[cfg_attr(feature = "cargo-clippy", allow(clippy::expl_impl_clone_on_copy))]
impl<'a, X, Y> Clone for Data<'a, X, Y> {
fn clone(&self) -> Data<'a, X, Y> {
*self
}
}
impl<'a, X, Y> Data<'a, X, Y> {
pub fn len(&self) -> usize {
self.0.len()
}
pub fn iter(&self) -> Pairs<'a, X, Y> {
Pairs {
data: *self,
state: 0,
}
}
}
impl<'a, X, Y> Data<'a, X, Y>
where
X: Float,
Y: Float,
{
pub fn new(xs: &'a [X], ys: &'a [Y]) -> Data<'a, X, Y> {
assert!(
xs.len() == ys.len()
&& xs.len() > 1
&& xs.iter().all(|x| !x.is_nan())
&& ys.iter().all(|y| !y.is_nan())
);
Data(xs, ys)
}
pub fn bootstrap<T, S>(&self, nresamples: usize, statistic: S) -> T::Distributions
where
S: Fn(Data<X, Y>) -> T,
S: Sync,
T: Tuple + Send,
T::Distributions: Send,
T::Builder: Send,
{
(0..nresamples)
.into_par_iter()
.map_init(
|| Resamples::new(*self),
|resamples, _| statistic(resamples.next()),
)
.fold(
|| T::Builder::new(0),
|mut sub_distributions, sample| {
sub_distributions.push(sample);
sub_distributions
},
)
.reduce(
|| T::Builder::new(0),
|mut a, mut b| {
a.extend(&mut b);
a
},
)
.complete()
}
pub fn x(&self) -> &'a Sample<X> {
Sample::new(&self.0)
}
pub fn y(&self) -> &'a Sample<Y> {
Sample::new(&self.1)
}
}
pub struct Pairs<'a, X: 'a, Y: 'a> {
data: Data<'a, X, Y>,
state: usize,
}
impl<'a, X, Y> Iterator for Pairs<'a, X, Y> {
type Item = (&'a X, &'a Y);
fn next(&mut self) -> Option<(&'a X, &'a Y)> {
if self.state < self.data.len() {
let i = self.state;
self.state += 1;
debug_assert!(i < self.data.0.len());
debug_assert!(i < self.data.1.len());
unsafe { Some((self.data.0.get_unchecked(i), self.data.1.get_unchecked(i))) }
} else {
None
}
}
}