kernel_density_estimation/bandwidth/
silverman.rs1use crate::bandwidth::Bandwidth;
4use crate::float::{float, KDEFloat};
5use crate::internal::{interquartile_range, variance};
6
7#[derive(Clone, Copy, Debug)]
9pub struct Silverman;
10
11impl<F: KDEFloat> Bandwidth<F> for Silverman {
12 fn bandwidth(&self, data: &[F]) -> F {
13 let var = variance(data);
14 let var_term = var.sqrt();
15 let iqr = interquartile_range(data);
16 let iqr_term = iqr / float!(1.349);
17 let n = float!(data.len());
18 let m = if var_term < iqr_term {
19 var_term
20 } else {
21 iqr_term
22 };
23 let numerator = float!(0.9) * m;
24 let denominator = n.powf(float!(0.2));
25 numerator / denominator
26 }
27}
28
29#[cfg(test)]
30mod tests {
31 use super::{Bandwidth, Silverman};
32 use approx::*;
33
34 #[test]
35 fn silverman() {
36 let data = vec![1.0, 1.5, 2.0, 2.5, 3.0];
37 let res = Silverman.bandwidth(&data);
38 assert_relative_eq!(res, 0.51568, epsilon = 1.0e-5);
39 }
40}