use strafe_type::{FloatConstraint, LogProbability64, Natural64, Probability64, Real64};
use crate::traits::DPQ;
pub fn pcauchy<R1: Into<Real64>, R2: Into<Real64>, N: Into<Natural64>>(
x: R1,
location: R2,
scale: N,
lower_tail: bool,
) -> Probability64 {
pcauchy_inner(x, location, scale, lower_tail, false).into()
}
pub fn log_pcauchy<R1: Into<Real64>, R2: Into<Real64>, N: Into<Natural64>>(
x: R1,
location: R2,
scale: N,
lower_tail: bool,
) -> LogProbability64 {
pcauchy_inner(x, location, scale, lower_tail, true).into()
}
fn pcauchy_inner<R1: Into<Real64>, R2: Into<Real64>, N: Into<Natural64>>(
x: R1,
location: R2,
scale: N,
lower_tail: bool,
log: bool,
) -> f64 {
let mut x = x.into().unwrap();
let location = location.into().unwrap();
let scale = scale.into().unwrap();
x = (x - location) / scale;
if !x.is_finite() {
return if x < 0.0 {
f64::dt_0(lower_tail, log)
} else {
f64::dt_1(lower_tail, log)
};
}
if !lower_tail {
x = -x
}
if x.abs() > 1.0 {
let y = (1.0 / x).atan() / std::f64::consts::PI;
if x > 0.0 {
y.d_clog(log)
} else {
(-y).d_val(log)
}
} else {
(0.5 + x.atan() / std::f64::consts::PI).d_val(log)
}
}