pub fn gaussian_kernel(distance: f64, bandwidth: f64) -> f64 {
(-0.5 * distance / (bandwidth * bandwidth)).exp()
}
pub fn multiquadric_kernel(distance: f64, bandwidth: f64) -> f64 {
(distance + bandwidth * bandwidth).sqrt()
}
pub fn inverse_multi_kernel(distance: f64, bandwidth: f64) -> f64 {
1.0 / multiquadric_kernel(distance, bandwidth)
}
pub fn linear_kernel(distance: f64, _bandwidth: f64) -> f64 {
distance
}
pub fn cubic_kernel(distance: f64, _bandwidth: f64) -> f64 {
distance.powi(2)
}
pub fn polynomial_kernel(distance: f64, bandwidth: f64) -> f64 {
(distance + 1.0).powi(bandwidth as i32)
}
pub fn thin_plate_spline_kernel(distance: f64, _bandwidth: f64) -> f64 {
if distance == 0.0 {
0.0
} else {
distance.powi(2) * distance.ln()
}
}
pub fn exponential_kernel(distance: f64, bandwidth: f64) -> f64 {
(-distance / bandwidth).exp()
}
pub fn neural_tangent_kernel(distance: f64, bandwidth: f64) -> f64 {
let norm_distance = distance / bandwidth;
let theta = norm_distance.acos();
(1.0 - norm_distance * theta.sin() + norm_distance.powi(2) * (1.0 - theta.cos()))
.max(f64::EPSILON)
}
pub fn rational_quadratic_kernel(distance: f64, alpha: f64) -> f64 {
(1.0 + (distance.powi(2) / (2.0 * alpha))).powf(-alpha)
}
pub fn cauchy_kernel(distance: f64, sigma: f64) -> f64 {
1.0 / (1.0 + (distance.powi(2) / sigma.powi(2)))
}
pub fn laplacian_kernel(distance: f64, gamma: f64) -> f64 {
(-gamma * distance.abs()).exp()
}