//! [Criterion]'s statistics library. //! //! [Criterion]: https://github.com/bheisler/criterion.rs //! //! **WARNING** This library is criterion's implementation detail and there no plans to stabilize //! it. In other words, the API may break at any time without notice. #[cfg(test)] mod test; pub mod bivariate; pub mod tuple; pub mod univariate; mod float; mod rand_util; use std::mem; use std::ops::Deref; use crate::stats::float::Float; use crate::stats::univariate::Sample; /// The bootstrap distribution of some parameter #[derive(Clone)] pub struct Distribution(Box<[A]>); impl Distribution where A: Float, { /// Create a distribution from the given values pub fn from(values: Box<[A]>) -> Distribution { Distribution(values) } /// Computes the confidence interval of the population parameter using percentiles /// /// # Panics /// /// Panics if the `confidence_level` is not in the `(0, 1)` range. pub fn confidence_interval(&self, confidence_level: A) -> (A, A) where usize: cast::From>, { let _0 = A::cast(0); let _1 = A::cast(1); let _50 = A::cast(50); assert!(confidence_level > _0 && confidence_level < _1); let percentiles = self.percentiles(); // FIXME(privacy) this should use the `at_unchecked()` method ( percentiles.at(_50 * (_1 - confidence_level)), percentiles.at(_50 * (_1 + confidence_level)), ) } /// Computes the "likelihood" of seeing the value `t` or "more extreme" values in the /// distribution. pub fn p_value(&self, t: A, tails: &Tails) -> A { use std::cmp; let n = self.0.len(); let hits = self.0.iter().filter(|&&x| x < t).count(); let tails = A::cast(match *tails { Tails::One => 1, Tails::Two => 2, }); A::cast(cmp::min(hits, n - hits)) / A::cast(n) * tails } } impl Deref for Distribution { type Target = Sample; fn deref(&self) -> &Sample { let slice: &[_] = &self.0; unsafe { mem::transmute(slice) } } } /// Number of tails for significance testing pub enum Tails { /// One tailed test One, /// Two tailed test Two, } fn dot(xs: &[A], ys: &[A]) -> A where A: Float, { xs.iter() .zip(ys) .fold(A::cast(0), |acc, (&x, &y)| acc + x * y) } fn sum(xs: &[A]) -> A where A: Float, { use std::ops::Add; xs.iter().cloned().fold(A::cast(0), Add::add) }