use crate::error::RobustError;
use crate::rho::RhoFunction;
#[derive(Debug, Clone, Copy)]
pub struct Cauchy {
c: f64,
}
impl Cauchy {
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 Cauchy {
fn default() -> Self {
Self { c: 2.3849 }
}
}
impl RhoFunction for Cauchy {
fn rho(&self, r: f64) -> f64 {
(self.c * self.c / 2.0) * (1.0 + (r / self.c).powi(2)).ln()
}
fn psi(&self, r: f64) -> f64 {
r / (1.0 + (r / self.c).powi(2))
}
fn weight(&self, r: f64) -> f64 {
1.0 / (1.0 + (r / self.c).powi(2))
}
fn psi_prime(&self, r: f64) -> f64 {
let u2 = (r / self.c).powi(2);
(1.0 - u2) / (1.0 + u2).powi(2)
}
fn tuning(&self) -> f64 {
self.c
}
fn is_redescending(&self) -> bool {
true
}
fn rho_sup(&self) -> Option<f64> {
None
}
}