use num_traits::Float;
use strafe_type::{Finite64, FloatConstraint, LogProbability64, Probability64, Real64};
use crate::traits::DPQ;
pub fn punif<R: Into<Real64>, F1: Into<Finite64>, F2: Into<Finite64>>(
x: R,
a: F1,
b: F2,
lower_tail: bool,
) -> Probability64 {
punif_inner(x, a, b, lower_tail, false).into()
}
pub fn log_punif<R: Into<Real64>, F1: Into<Finite64>, F2: Into<Finite64>>(
x: R,
a: F1,
b: F2,
lower_tail: bool,
) -> LogProbability64 {
punif_inner(x, a, b, lower_tail, true).into()
}
fn punif_inner<R: Into<Real64>, F1: Into<Finite64>, F2: Into<Finite64>>(
x: R,
a: F1,
b: F2,
lower_tail: bool,
log: bool,
) -> f64 {
let x = x.into().unwrap();
let a = a.into().unwrap();
let b = b.into().unwrap();
if b < a {
return f64::nan();
}
if x >= b {
return f64::dt_1(lower_tail, log);
}
if x <= a {
return f64::dt_0(lower_tail, log);
}
return if lower_tail {
((x - a) / (b - a)).d_val(log)
} else {
((b - x) / (b - a)).d_val(log)
};
}