use robust_rs_core::error::RobustError;
fn sort_and_trim_count(data: &[f64], alpha: f64) -> Result<(Vec<f64>, usize), RobustError> {
let n = data.len();
if n == 0 {
return Err(RobustError::InsufficientData { needed: 1, got: 0 });
}
if !(0.0..0.5).contains(&alpha) {
return Err(RobustError::InvalidTuning { value: alpha });
}
let g = (alpha * n as f64).floor() as usize; let mut buf = data.to_vec();
buf.sort_unstable_by(f64::total_cmp);
Ok((buf, g))
}
pub fn trimmed_mean(data: &[f64], alpha: f64) -> Result<f64, RobustError> {
let (buf, g) = sort_and_trim_count(data, alpha)?;
let n = buf.len();
let kept = &buf[g..n - g]; Ok(kept.iter().sum::<f64>() / kept.len() as f64)
}
pub fn winsorized_mean(data: &[f64], alpha: f64) -> Result<f64, RobustError> {
let (buf, g) = sort_and_trim_count(data, alpha)?;
let n = buf.len();
let lo = buf[g]; let hi = buf[n - 1 - g]; let middle: f64 = buf[g..n - g].iter().sum();
Ok((g as f64 * lo + middle + g as f64 * hi) / n as f64)
}