• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //! [Criterion]'s statistics library.
2 //!
3 //! [Criterion]: https://github.com/bheisler/criterion.rs
4 //!
5 //! **WARNING** This library is criterion's implementation detail and there no plans to stabilize
6 //! it. In other words, the API may break at any time without notice.
7 
8 #[cfg(test)]
9 mod test;
10 
11 pub mod bivariate;
12 pub mod tuple;
13 pub mod univariate;
14 
15 mod float;
16 mod rand_util;
17 
18 use std::mem;
19 use std::ops::Deref;
20 
21 use crate::stats::float::Float;
22 use crate::stats::univariate::Sample;
23 
24 /// The bootstrap distribution of some parameter
25 #[derive(Clone)]
26 pub struct Distribution<A>(Box<[A]>);
27 
28 impl<A> Distribution<A>
29 where
30     A: Float,
31 {
32     /// Create a distribution from the given values
from(values: Box<[A]>) -> Distribution<A>33     pub fn from(values: Box<[A]>) -> Distribution<A> {
34         Distribution(values)
35     }
36 
37     /// Computes the confidence interval of the population parameter using percentiles
38     ///
39     /// # Panics
40     ///
41     /// Panics if the `confidence_level` is not in the `(0, 1)` range.
confidence_interval(&self, confidence_level: A) -> (A, A) where usize: cast::From<A, Output = Result<usize, cast::Error>>,42     pub fn confidence_interval(&self, confidence_level: A) -> (A, A)
43     where
44         usize: cast::From<A, Output = Result<usize, cast::Error>>,
45     {
46         let _0 = A::cast(0);
47         let _1 = A::cast(1);
48         let _50 = A::cast(50);
49 
50         assert!(confidence_level > _0 && confidence_level < _1);
51 
52         let percentiles = self.percentiles();
53 
54         // FIXME(privacy) this should use the `at_unchecked()` method
55         (
56             percentiles.at(_50 * (_1 - confidence_level)),
57             percentiles.at(_50 * (_1 + confidence_level)),
58         )
59     }
60 
61     /// Computes the "likelihood" of seeing the value `t` or "more extreme" values in the
62     /// distribution.
p_value(&self, t: A, tails: &Tails) -> A63     pub fn p_value(&self, t: A, tails: &Tails) -> A {
64         use std::cmp;
65 
66         let n = self.0.len();
67         let hits = self.0.iter().filter(|&&x| x < t).count();
68 
69         let tails = A::cast(match *tails {
70             Tails::One => 1,
71             Tails::Two => 2,
72         });
73 
74         A::cast(cmp::min(hits, n - hits)) / A::cast(n) * tails
75     }
76 }
77 
78 impl<A> Deref for Distribution<A> {
79     type Target = Sample<A>;
80 
deref(&self) -> &Sample<A>81     fn deref(&self) -> &Sample<A> {
82         let slice: &[_] = &self.0;
83 
84         unsafe { mem::transmute(slice) }
85     }
86 }
87 
88 /// Number of tails for significance testing
89 pub enum Tails {
90     /// One tailed test
91     One,
92     /// Two tailed test
93     Two,
94 }
95 
dot<A>(xs: &[A], ys: &[A]) -> A where A: Float,96 fn dot<A>(xs: &[A], ys: &[A]) -> A
97 where
98     A: Float,
99 {
100     xs.iter()
101         .zip(ys)
102         .fold(A::cast(0), |acc, (&x, &y)| acc + x * y)
103 }
104 
sum<A>(xs: &[A]) -> A where A: Float,105 fn sum<A>(xs: &[A]) -> A
106 where
107     A: Float,
108 {
109     use std::ops::Add;
110 
111     xs.iter().cloned().fold(A::cast(0), Add::add)
112 }
113