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