use num_traits::Float;
use strafe_type::{FloatConstraint, Positive64, Real64};
use crate::traits::DPQ;
pub fn dlnorm<R1: Into<Real64>, R2: Into<Real64>, P: Into<Positive64>>(
x: R1,
meanlog: R2,
sdlog: P,
log: bool,
) -> Real64 {
let x = x.into().unwrap();
let meanlog = meanlog.into().unwrap();
let sdlog = sdlog.into().unwrap();
let mut y = 0.0;
if !x.is_finite() && x.ln() == meanlog {
return f64::nan().into();
}
if sdlog == 0.0 {
return if x.ln() == meanlog {
f64::infinity()
} else {
f64::d_0(log)
}
.into();
}
if x <= 0.0 {
return f64::d_0(log).into();
}
y = (x.ln() - meanlog) / sdlog;
if log {
-(strafe_consts::LN_SQRT_2TPI + 0.5 * y * y + (x * sdlog).ln())
} else {
(strafe_consts::_1DSQRT_2TPI * (-0.5 * y * y).exp()) / (x * sdlog)
}
.into()
}