pub fn evpdf(x: f64, mu: f64, sigma: f64) -> f64 {
if x.is_nan() || mu.is_nan() || sigma.is_nan() || sigma <= 0.0 {
return f64::NAN;
}
let z = (x - mu) / sigma;
if z == f64::INFINITY || z > 700.0 {
return 0.0;
}
if z == f64::NEG_INFINITY {
return 0.0;
}
(z - z.exp()).exp() / sigma
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_standard_extreme_value_pdf() {
let result = evpdf(0.0, 0.0, 1.0);
let expected = (-1.0f64).exp();
assert!((result - expected).abs() < 1e-15);
}
#[test]
fn test_invalid_scale() {
assert!(evpdf(1.0, 0.0, 0.0).is_nan());
assert!(evpdf(1.0, 0.0, -1.5).is_nan());
assert!(evpdf(f64::NAN, 0.0, 1.0).is_nan());
}
#[test]
fn test_extreme_tails() {
assert_eq!(evpdf(1000.0, 0.0, 1.0), 0.0);
assert_eq!(evpdf(f64::INFINITY, 0.0, 1.0), 0.0);
assert_eq!(evpdf(-1000.0, 0.0, 1.0), 0.0);
assert_eq!(evpdf(f64::NEG_INFINITY, 0.0, 1.0), 0.0);
}
#[test]
fn test_shifted_distribution() {
let result = evpdf(10.0, 10.0, 2.0);
let expected = (-1.0f64).exp() / 2.0;
assert!((result - expected).abs() < 1e-15);
}
}