use crate::error::{Error, Result};
use crate::math::gamma::{lowergammaf, lngammaf};
use crate::random::randgammaf;
pub fn randnakmf(m: f32, omega: f32) -> Result<f32> {
if m < 0.5 {
return Err(Error::Config("m cannot be less than 0.5".to_string()));
} else if omega <= 0.0 {
return Err(Error::Config("omega must be greater than zero".to_string()));
}
let alpha = m;
let beta = omega / m;
let x = randgammaf(alpha, beta)?;
Ok(x.sqrt())
}
pub fn randnakmf_pdf(x: f32, m: f32, omega: f32) -> Result<f32> {
if m < 0.5 {
return Err(Error::Config("m cannot be less than 0.5".to_string()));
} else if omega <= 0.0 {
return Err(Error::Config("omega must be greater than zero".to_string()));
}
if x <= 0.0 {
return Ok(0.0);
}
let t0 = lngammaf(m);
let t1 = m * (m / omega).ln();
let t2 = (2.0 * m - 1.0) * x.ln();
let t3 = -(m / omega) * x * x;
Ok(2.0 * (-t0 + t1 + t2 + t3).exp())
}
pub fn randnakmf_cdf(x: f32, m: f32, omega: f32) -> Result<f32> {
if m < 0.5 {
return Err(Error::Config("m cannot be less than 0.5".to_string()));
} else if omega <= 0.0 {
return Err(Error::Config("omega must be greater than zero".to_string()));
}
if x <= 0.0 {
return Ok(0.0);
}
let t0 = lowergammaf(m, x * x * m / omega);
let t1 = lngammaf(m);
Ok((t0 - t1).exp())
}