use crate::error::StatsResult;
use crate::prob::erf;
use crate::utils::constants::SQRT_2;
#[inline]
pub fn normal_cumulative_distrib(z: f64) -> StatsResult<f64> {
Ok((1.0 + erf(z / SQRT_2)?) / 2.0)
}
#[cfg(test)]
mod tests {
use super::*;
const EPSILON: f64 = 1e-5;
#[test]
fn test_cdf_z_zero() {
let z = 0.0;
let result = normal_cumulative_distrib(z).unwrap();
let expected = 0.5; assert!(
(result - expected).abs() < EPSILON,
"CDF for z = 0.0 should be 0.5"
);
}
#[test]
fn test_cdf_positive_z() {
let z = 1.0;
let result = normal_cumulative_distrib(z).unwrap();
let expected = 0.841344746; assert!(
(result - expected).abs() < EPSILON,
"CDF for z = 1.0 should match expected"
);
}
#[test]
fn test_cdf_negative_z() {
let z = -1.0;
let result = normal_cumulative_distrib(z).unwrap();
let expected = 0.158655254; assert!(
(result - expected).abs() < EPSILON,
"CDF for z = -1.0 should match expected"
);
}
#[test]
fn test_cdf_large_positive_z() {
let z = 3.0;
let result = normal_cumulative_distrib(z).unwrap();
let expected = 0.998650102; assert!(
(result - expected).abs() < EPSILON,
"CDF for z = 3.0 should match expected"
);
}
#[test]
fn test_cdf_large_negative_z() {
let z = -3.0;
let result = normal_cumulative_distrib(z).unwrap();
let expected = 0.001349898; assert!(
(result - expected).abs() < EPSILON,
"CDF for z = -3.0 should match expected"
);
}
}