use num_traits::Float;
use strafe_type::{FloatConstraint, Rational64, Real64};
use crate::traits::DPQ;
pub fn dweibull<RE: Into<Real64>, RA1: Into<Rational64>, RA2: Into<Rational64>>(
x: RE,
shape: RA1,
scale: RA2,
log: bool,
) -> Real64 {
let x = x.into().unwrap();
let shape = shape.into().unwrap();
let scale = scale.into().unwrap();
let mut tmp1 = 0.0;
let mut tmp2 = 0.0;
if x < 0.0 {
return f64::d_0(log).into();
}
if !x.is_finite() {
return f64::d_0(log).into();
}
if x == 0.0 && shape < 1.0 {
return f64::infinity().into();
}
tmp1 = (x / scale).powf(shape - 1.0);
tmp2 = tmp1 * (x / scale);
if log {
let x = -tmp2;
let y = (shape * tmp1 / scale).ln();
if x.is_infinite() && y.is_infinite() && x.signum() != y.signum() {
0.0
} else {
x + y
}
} else if (-tmp2).exp() == 0.0 {
0.0
} else {
(shape * tmp1 * (-tmp2).exp()) / scale
}
.into()
}