use nalgebra::DMatrix;
use num_traits::Float;
use r2rs_nmath::{distribution::CauchyBuilder, traits::Distribution};
use strafe_type::FloatConstraint;
use crate::regression::glm::link::core::Link;
#[derive(Default, Clone, Debug)]
pub struct Cauchit {}
impl Cauchit {
pub fn new() -> Self {
Self::default()
}
}
impl Link for Cauchit {
fn link_func(&self, mu: &DMatrix<f64>) -> DMatrix<f64> {
let cauchy = CauchyBuilder::new().build();
let mut ret = mu.clone();
ret.iter_mut()
.for_each(|mu| *mu = cauchy.quantile(*mu, true).unwrap());
ret
}
fn link_inverse(&self, eta: &DMatrix<f64>) -> DMatrix<f64> {
let cauchy = CauchyBuilder::new().build();
let threshold = -cauchy.quantile(f64::epsilon(), true).unwrap();
let mut ret = eta.clone();
ret.iter_mut().for_each(|eta| {
*eta = cauchy
.probability(eta.max(-threshold).min(threshold), true)
.unwrap()
});
ret
}
fn mu_eta(&self, eta: &DMatrix<f64>) -> DMatrix<f64> {
let cauchy = CauchyBuilder::new().build();
let mut ret = eta.clone();
ret.iter_mut()
.for_each(|eta| *eta = cauchy.density(*eta).unwrap().max(f64::epsilon()));
ret
}
fn valid_eta(&self, _eta: &DMatrix<f64>) -> bool {
true
}
}