criterion/stats/univariate/kde/
kernel.rs
1use stats::float::Float;
4
5pub trait Kernel<A>: Copy + Sync
7where
8 A: Float,
9{
10 fn evaluate(&self, x: A) -> A;
12}
13
14#[derive(Clone, Copy)]
16pub struct Gaussian;
17
18impl<A> Kernel<A> for Gaussian
19where
20 A: Float,
21{
22 fn evaluate(&self, x: A) -> A {
23 use std::f32::consts::PI;
24
25 (x.powi(2).exp() * A::cast(2. * PI)).sqrt().recip()
26 }
27}
28
29#[cfg(test)]
30macro_rules! test {
31 ($ty:ident) => {
32 mod $ty {
33 mod gaussian {
34 use quickcheck::TestResult;
35
36 use stats::univariate::kde::kernel::{Gaussian, Kernel};
37
38 quickcheck! {
39 fn symmetric(x: $ty) -> bool {
40 relative_eq!(Gaussian.evaluate(-x), Gaussian.evaluate(x))
41 }
42 }
43
44 quickcheck! {
46 fn integral(a: $ty, b: $ty) -> TestResult {
47 const DX: $ty = 1e-3;
48
49 if a > b {
50 TestResult::discard()
51 } else {
52 let mut acc = 0.;
53 let mut x = a;
54 let mut y = Gaussian.evaluate(a);
55
56 while x < b {
57 acc += DX * y / 2.;
58
59 x += DX;
60 y = Gaussian.evaluate(x);
61
62 acc += DX * y / 2.;
63 }
64
65 TestResult::from_bool(
66 (acc > 0. || relative_eq!(acc, 0.)) &&
67 (acc < 1. || relative_eq!(acc, 1.)))
68 }
69 }
70 }
71 }
72 }
73 };
74}
75
76#[cfg(test)]
77mod test {
78 test!(f32);
79 test!(f64);
80}