pub trait RegKernel {
fn eval(&self, x: f64, xi: f64) -> f64;
}
pub trait RegKernelMass: RegKernel {
fn eval_mass(&self, x: f64, a: f64, b: f64) -> f64;
}
#[derive(Debug,Clone,Copy)]
pub struct GaussianKernel {
bandwidth: f64
}
impl GaussianKernel {
pub fn new(bandwidth: f64) -> Self {
GaussianKernel { bandwidth }
}
}
impl RegKernel for GaussianKernel {
fn eval(&self, x: f64, xi: f64) -> f64 {
let z = (x - xi) / self.bandwidth;
(-z * z / 2.).exp()
}
}
pub struct NearestNeighborKernel {
bandwidth: f64
}
impl NearestNeighborKernel {
pub fn new(bandwidth: f64) -> Self {
Self { bandwidth }
}
}
impl RegKernel for NearestNeighborKernel {
fn eval(&self, x: f64, xi: f64) -> f64 {
if (x - xi).abs() < self.bandwidth {
1.0
} else {
0.0
}
}
}
impl RegKernelMass for NearestNeighborKernel {
fn eval_mass(&self, x: f64, a: f64, b: f64) -> f64 {
let h = self.bandwidth;
let up = b.min(x + h);
let dw = a.max(x - h);
up - dw
}
}
#[derive(Debug,Clone,Copy)]
pub struct EpanechnikovKernel {
bandwidth: f64
}
impl EpanechnikovKernel {
pub fn new(bandwidth: f64) -> Self {
Self { bandwidth }
}
}
impl RegKernel for EpanechnikovKernel {
fn eval(&self, x: f64, xi: f64) -> f64 {
if x.abs() > 1. {
0.
}
else {
let dx = (x - xi) / self.bandwidth;
0.75 * (1.0 - dx * dx)
}
}
}