#[cfg(not(feature = "std"))]
use alloc::vec::Vec;
#[cfg(feature = "std")]
use std::vec::Vec;
use num_traits::Float;
#[derive(Debug, Clone, PartialEq)]
pub struct HatMatrixStats<T> {
pub leverage: Vec<T>,
pub trace: T,
pub delta1: T,
pub delta2: T,
}
impl<T: Float> HatMatrixStats<T> {
pub fn from_leverage(leverage: Vec<T>) -> Self {
let n = T::from(leverage.len()).unwrap();
let trace = leverage.iter().fold(T::zero(), |acc, &l| acc + l);
let trace_l_sq = leverage.iter().fold(T::zero(), |acc, &l| acc + l * l);
let delta1 = n - T::from(2.0).unwrap() * trace + trace_l_sq;
let delta2 = delta1 * delta1 / n;
Self {
leverage,
trace,
delta1,
delta2,
}
}
pub fn compute_residual_scale(&self, rss: T) -> T {
if self.delta1 > T::zero() {
(rss / self.delta1).sqrt()
} else {
T::zero()
}
}
}