1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
use crate::distributions::*;
/// Implements the [Uniform](https://en.wikipedia.org/wiki/Uniform_distribution_(continuous))
/// distribution.
#[derive(Debug, Clone, Copy)]
pub struct Uniform {
/// Lower bound for the Uniform distribution.
lower: f64,
/// Upper bound for the Uniform distribution.
upper: f64,
}
impl Uniform {
/// Create a new Uniform distribution with lower bound `lower` and upper bound `upper`.
///
/// # Errors
/// Panics if `lower > upper`.
pub fn new(lower: f64, upper: f64) -> Self {
if lower > upper {
panic!("`Upper` must be larger than `lower`.");
}
Uniform { lower, upper }
}
pub fn set_lower(&mut self, lower: f64) -> &mut Self {
if lower > self.upper {
panic!("Upper must be larger than lower.")
}
self.lower = lower;
self
}
pub fn set_upper(&mut self, upper: f64) -> &mut Self {
if self.lower > upper {
panic!("Upper must be larger than lower.")
}
self.upper = upper;
self
}
}
impl Default for Uniform {
fn default() -> Self {
Self::new(0., 1.)
}
}
impl Distribution for Uniform {
type Output = f64;
/// Samples from the given Uniform distribution.
fn sample(&self) -> f64 {
(self.upper - self.lower) * alea::f64() + self.lower
}
}
impl Distribution1D for Uniform {
fn update(&mut self, params: &[f64]) {
self.set_lower(params[0]).set_upper(params[1]);
}
}
impl Continuous for Uniform {
type PDFType = f64;
/// Calculates the [probability density
/// function](https://en.wikipedia.org/wiki/Probability_density_function) for the given Uniform
/// distribution at `x`.
///
/// # Remarks
///
/// Returns `0.` if `x` is not in `[lower, upper]`
fn pdf(&self, x: f64) -> f64 {
if x < self.lower || x > self.upper {
0.
} else {
1. / (self.upper - self.lower)
}
}
}
impl Mean for Uniform {
type MeanType = f64;
/// Calculates the mean, which for a Uniform(a, b) distribution is given by `(a + b) / 2`.
fn mean(&self) -> f64 {
(self.lower + self.upper) / 2.
}
}
impl Variance for Uniform {
type VarianceType = f64;
/// Calculates the variance of the given Uniform distribution.
fn var(&self) -> f64 {
(self.upper - self.lower).powi(2) / 12.
}
}
#[test]
fn inrange() {
let u = self::Uniform::new(-2., 6.);
let samples = u.sample_n(100);
samples.into_iter().for_each(|x| {
assert!(-2. <= x);
assert!(x <= 6.);
})
}