use strafe_type::{FloatConstraint, LogProbability64, Positive64, Probability64, Real64};
use crate::traits::DPQ;
pub fn pexp<R: Into<Real64>, P: Into<Positive64>>(
x: R,
scale: P,
lower_tail: bool,
) -> Probability64 {
pexp_inner(x, scale, lower_tail, false).into()
}
pub fn log_pexp<R: Into<Real64>, P: Into<Positive64>>(
x: R,
scale: P,
lower_tail: bool,
) -> LogProbability64 {
pexp_inner(x, scale, lower_tail, true).into()
}
fn pexp_inner<R: Into<Real64>, P: Into<Positive64>>(
x: R,
scale: P,
lower_tail: bool,
log: bool,
) -> f64 {
let mut x = x.into().unwrap();
let scale = scale.into().unwrap();
if x <= 0.0 {
return f64::dt_0(lower_tail, log);
}
x = -(x / scale);
if log {
if lower_tail {
x.log1_exp()
} else {
x.d_exp(true)
}
} else if lower_tail {
-x.exp_m1()
} else {
x.d_exp(false)
}
}