probability/distribution/
uniform.rs1#[allow(unused_imports)]
2use special::Primitive;
3
4use distribution;
5use source::Source;
6
7#[derive(Clone, Copy, Debug)]
9pub struct Uniform {
10 a: f64,
11 b: f64,
12}
13
14impl Uniform {
15 #[inline]
19 pub fn new(a: f64, b: f64) -> Self {
20 should!(a < b);
21 Uniform { a, b }
22 }
23
24 #[inline(always)]
26 pub fn a(&self) -> f64 {
27 self.a
28 }
29
30 #[inline(always)]
32 pub fn b(&self) -> f64 {
33 self.b
34 }
35}
36
37impl Default for Uniform {
38 #[inline]
39 fn default() -> Self {
40 Uniform::new(0.0, 1.0)
41 }
42}
43
44impl distribution::Continuous for Uniform {
45 #[inline]
46 fn density(&self, x: f64) -> f64 {
47 if x < self.a || x > self.b {
48 0.0
49 } else {
50 1.0 / (self.b - self.a)
51 }
52 }
53}
54
55impl distribution::Distribution for Uniform {
56 type Value = f64;
57
58 #[inline]
59 fn distribution(&self, x: f64) -> f64 {
60 if x <= self.a {
61 0.0
62 } else if x >= self.b {
63 1.0
64 } else {
65 (x - self.a) / (self.b - self.a)
66 }
67 }
68}
69
70impl distribution::Entropy for Uniform {
71 #[inline]
72 fn entropy(&self) -> f64 {
73 (self.b - self.a).ln()
74 }
75}
76
77impl distribution::Inverse for Uniform {
78 #[inline]
79 fn inverse(&self, p: f64) -> f64 {
80 should!((0.0..=1.0).contains(&p));
81 self.a + (self.b - self.a) * p
82 }
83}
84
85impl distribution::Kurtosis for Uniform {
86 #[inline]
87 fn kurtosis(&self) -> f64 {
88 -1.2
89 }
90}
91
92impl distribution::Mean for Uniform {
93 #[inline]
94 fn mean(&self) -> f64 {
95 (self.a + self.b) / 2.0
96 }
97}
98
99impl distribution::Median for Uniform {
100 #[inline]
101 fn median(&self) -> f64 {
102 use distribution::Mean;
103 self.mean()
104 }
105}
106
107impl distribution::Sample for Uniform {
108 #[inline]
109 fn sample<S>(&self, source: &mut S) -> f64
110 where
111 S: Source,
112 {
113 self.a + (self.b - self.a) * source.read::<f64>()
114 }
115}
116
117impl distribution::Skewness for Uniform {
118 #[inline]
119 fn skewness(&self) -> f64 {
120 0.0
121 }
122}
123
124impl distribution::Variance for Uniform {
125 #[inline]
126 fn variance(&self) -> f64 {
127 (self.b - self.a).powi(2) / 12.0
128 }
129}
130
131#[cfg(test)]
132mod tests {
133 use alloc::{vec, vec::Vec};
134 use prelude::*;
135
136 macro_rules! new(
137 ($a:expr, $b:expr) => (Uniform::new($a, $b));
138 );
139
140 #[test]
141 fn distribution() {
142 let d = new!(-1.0, 1.0);
143 let x = vec![-1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5];
144 let p = vec![0.0, 0.0, 0.25, 0.5, 0.75, 1.0, 1.0];
145
146 assert_eq!(
147 &x.iter().map(|&x| d.distribution(x)).collect::<Vec<_>>(),
148 &p
149 );
150 }
151
152 #[test]
153 fn density() {
154 let d = new!(-1.0, 1.0);
155 let x = vec![-1.5, -1.0, -0.5, 0.0, 0.5, 1.0, 1.5];
156 let p = vec![0.0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.0];
157
158 assert_eq!(&x.iter().map(|&x| d.density(x)).collect::<Vec<_>>(), &p);
159 }
160
161 #[test]
162 fn entropy() {
163 use core::f64::consts::E;
164 assert_eq!(new!(0.0, E).entropy(), 1.0);
165 }
166
167 #[test]
168 fn inverse() {
169 let d = new!(-1.0, 1.0);
170 let x = vec![-1.0, -0.5, 0.0, 0.5, 1.0];
171 let p = vec![0.0, 0.25, 0.5, 0.75, 1.0];
172
173 assert_eq!(&p.iter().map(|&p| d.inverse(p)).collect::<Vec<_>>(), &x);
174 }
175
176 #[test]
177 fn kurtosis() {
178 assert_eq!(new!(0.0, 2.0).kurtosis(), -1.2);
179 }
180
181 #[test]
182 fn mean() {
183 assert_eq!(new!(0.0, 2.0).mean(), 1.0);
184 }
185
186 #[test]
187 fn median() {
188 assert_eq!(new!(0.0, 2.0).median(), 1.0);
189 }
190
191 #[test]
192 fn sample() {
193 for x in Independent(&new!(7.0, 42.0), &mut source::default(42)).take(100) {
194 assert!(7.0 <= x && x <= 42.0);
195 }
196 }
197
198 #[test]
199 fn skewness() {
200 assert_eq!(new!(0.0, 2.0).skewness(), 0.0);
201 }
202
203 #[test]
204 fn variance() {
205 assert_eq!(new!(0.0, 12.0).variance(), 12.0);
206 }
207}