use crate::error::RobustError;
use crate::rho::RhoFunction;
#[derive(Debug, Clone, Copy)]
pub struct Welsch {
c: f64,
}
impl Welsch {
pub fn new(c: f64) -> Result<Self, RobustError> {
if c.is_finite() && c > 0.0 {
Ok(Self { c })
} else {
Err(RobustError::InvalidTuning { value: c })
}
}
}
impl Default for Welsch {
fn default() -> Self {
Self { c: 2.9846 }
}
}
impl RhoFunction for Welsch {
fn rho(&self, r: f64) -> f64 {
(self.c * self.c / 2.0) * (1.0 - (-(r / self.c).powi(2)).exp())
}
fn psi(&self, r: f64) -> f64 {
r * (-(r / self.c).powi(2)).exp()
}
fn weight(&self, r: f64) -> f64 {
(-(r / self.c).powi(2)).exp()
}
fn psi_prime(&self, r: f64) -> f64 {
let u2 = (r / self.c).powi(2);
(1.0 - 2.0 * u2) * (-u2).exp()
}
fn tuning(&self) -> f64 {
self.c
}
fn is_redescending(&self) -> bool {
true
}
fn rho_sup(&self) -> Option<f64> {
Some(self.c * self.c / 2.0)
}
}