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
use crate::Range;
use rand::distributions::Distribution;
use rand::Rng;
pub use self::histogram::{HistogramEstimator, HistogramEstimatorBuilder};
pub use self::parzen::{ParzenEstimator, ParzenEstimatorBuilder};
mod histogram;
mod parzen;
pub trait DensityEstimator: Distribution<f64> {
fn log_pdf(&self, x: f64) -> f64;
}
pub trait BuildDensityEstimator {
type Estimator: DensityEstimator;
type Error: std::error::Error;
fn build_density_estimator<I>(
&self,
xs: I,
range: Range,
) -> Result<Self::Estimator, Self::Error>
where
I: Iterator<Item = f64> + Clone;
}
#[derive(Debug)]
#[allow(missing_docs)]
pub enum DefaultEstimator {
Parzen(ParzenEstimator),
Histogram(HistogramEstimator),
}
impl DensityEstimator for DefaultEstimator {
fn log_pdf(&self, x: f64) -> f64 {
match self {
Self::Parzen(t) => t.log_pdf(x),
Self::Histogram(t) => t.log_pdf(x),
}
}
}
impl Distribution<f64> for DefaultEstimator {
fn sample<R: Rng + ?Sized>(&self, rng: &mut R) -> f64 {
match self {
Self::Parzen(t) => t.sample(rng),
Self::Histogram(t) => t.sample(rng),
}
}
}
#[derive(Debug)]
#[allow(missing_docs)]
pub enum DefaultEstimatorBuilder {
Parzen(ParzenEstimatorBuilder),
Histogram(HistogramEstimatorBuilder),
}
impl BuildDensityEstimator for DefaultEstimatorBuilder {
type Estimator = DefaultEstimator;
type Error = std::convert::Infallible;
fn build_density_estimator<I>(
&self,
params: I,
range: Range,
) -> Result<Self::Estimator, Self::Error>
where
I: Iterator<Item = f64> + Clone,
{
match self {
Self::Parzen(t) => t
.build_density_estimator(params, range)
.map(DefaultEstimator::Parzen),
Self::Histogram(t) => t
.build_density_estimator(params, range)
.map(DefaultEstimator::Histogram),
}
}
}