use crate::dpois::dpois_raw;
use crate::dpq::r_d__0;
use crate::nmath::ml_warn_return_nan;
use crate::nmath::r_finite;
use crate::nmath::ML_POSINF;
use libm::log;
pub fn dgamma(x: f64, shape: f64, scale: f64, give_log: bool) -> f64 {
if x.is_nan() || shape.is_nan() || scale.is_nan() {
return x + shape + scale;
}
if shape < 0.0 || scale <= 0.0 {
return ml_warn_return_nan();
}
if x < 0.0 {
return r_d__0(give_log);
}
if shape == 0.0 {
return if x == 0.0 {
ML_POSINF
} else {
r_d__0(give_log)
};
}
if x == 0.0 {
if shape < 1.0 {
return ML_POSINF;
}
if shape > 1.0 {
return r_d__0(give_log);
}
return if give_log { -log(scale) } else { 1.0 / scale };
}
let pr: f64;
if shape < 1.0 {
pr = dpois_raw(shape, x / scale, give_log);
return if give_log {
pr + if r_finite(shape / x) {
log(shape / x)
} else {
log(shape) - log(x)
}
} else {
pr * shape / x
};
}
pr = dpois_raw(shape - 1.0, x / scale, give_log);
if give_log {
pr - log(scale)
} else {
pr / scale
}
}