use strafe_type::{FloatConstraint, LogProbability64, Positive64, Probability64, Real64};
use crate::{
distribution::norm::{log_pnorm, pnorm},
traits::DPQ,
};
pub fn plnorm<R1: Into<Real64>, R2: Into<Real64>, P: Into<Positive64>>(
x: R1,
meanlog: R2,
sdlog: P,
lower_tail: bool,
) -> Probability64 {
plnorm_inner(x, meanlog, sdlog, lower_tail, false).into()
}
pub fn log_plnorm<R1: Into<Real64>, R2: Into<Real64>, P: Into<Positive64>>(
x: R1,
meanlog: R2,
sdlog: P,
lower_tail: bool,
) -> LogProbability64 {
plnorm_inner(x, meanlog, sdlog, lower_tail, true).into()
}
fn plnorm_inner<R1: Into<Real64>, R2: Into<Real64>, P: Into<Positive64>>(
x: R1,
meanlog: R2,
sdlog: P,
lower_tail: bool,
log: bool,
) -> f64 {
let x = x.into().unwrap();
let meanlog = meanlog.into().unwrap();
let sdlog = sdlog.into().unwrap();
if x > 0.0 {
if log {
log_pnorm(x.ln(), meanlog, sdlog, lower_tail).unwrap()
} else {
pnorm(x.ln(), meanlog, sdlog, lower_tail).unwrap()
}
} else {
f64::dt_0(lower_tail, log)
}
}