use std::str::FromStr;
use strafe_testing::{
r::{RString, RTester},
r_assert_relative_equal, r_assert_relative_equal_result,
};
use strafe_type::FloatConstraint;
use crate::{
distribution::cauchy::CauchyBuilder,
reset_statics,
rng::MarsagliaMulticarry,
traits::{Distribution, RNG},
};
pub fn density_inner(x: f64, location: f64, scale: f64) {
let mut builder = CauchyBuilder::new();
builder.with_location(location);
builder.with_scale(scale);
let cauchy = builder.build();
let rust_ans = cauchy.density(x);
let r_ans = RTester::new()
.set_display(&RString::from_string(format!(
"dcauchy({}, {}, {}, log={})",
RString::from_f64(x),
RString::from_f64(location),
RString::from_f64(scale),
RString::from_bool(false),
)))
.run()
.expect("R running error")
.as_f64();
r_assert_relative_equal_result!(r_ans, &rust_ans);
}
pub fn log_density_inner(x: f64, location: f64, scale: f64) {
let mut builder = CauchyBuilder::new();
builder.with_location(location);
builder.with_scale(scale);
let cauchy = builder.build();
let rust_ans = cauchy.log_density(x);
let r_ans = RTester::new()
.set_display(&RString::from_string(format!(
"dcauchy({}, {}, {}, log={})",
RString::from_f64(x),
RString::from_f64(location),
RString::from_f64(scale),
RString::from_bool(true),
)))
.run()
.expect("R running error")
.as_f64();
r_assert_relative_equal_result!(r_ans, &rust_ans);
}
pub fn probability_inner(q: f64, location: f64, scale: f64, lower_tail: bool) {
let mut builder = CauchyBuilder::new();
builder.with_location(location);
builder.with_scale(scale);
let cauchy = builder.build();
let rust_ans = cauchy.probability(q, lower_tail);
let r_ans = RTester::new()
.set_display(&RString::from_string(format!(
"pcauchy({}, {}, {}, lower.tail={}, log={})",
RString::from_f64(q),
RString::from_f64(location),
RString::from_f64(scale),
RString::from_bool(lower_tail),
RString::from_bool(false),
)))
.run()
.expect("R running error")
.as_f64();
r_assert_relative_equal_result!(r_ans, &rust_ans);
}
pub fn log_probability_inner(q: f64, location: f64, scale: f64, lower_tail: bool) {
let mut builder = CauchyBuilder::new();
builder.with_location(location);
builder.with_scale(scale);
let cauchy = builder.build();
let rust_ans = cauchy.log_probability(q, lower_tail);
let r_ans = RTester::new()
.set_display(&RString::from_string(format!(
"pcauchy({}, {}, {}, lower.tail={}, log={})",
RString::from_f64(q),
RString::from_f64(location),
RString::from_f64(scale),
RString::from_bool(lower_tail),
RString::from_bool(true),
)))
.run()
.expect("R running error")
.as_f64();
r_assert_relative_equal_result!(r_ans, &rust_ans);
}
pub fn quantile_inner(p: f64, location: f64, scale: f64, lower_tail: bool) {
let mut builder = CauchyBuilder::new();
builder.with_location(location);
builder.with_scale(scale);
let cauchy = builder.build();
let rust_ans = cauchy.quantile(p, lower_tail);
let r_ans = RTester::new()
.set_display(&RString::from_string(format!(
"qcauchy({}, {}, {}, lower.tail={}, log={})",
RString::from_f64(p),
RString::from_f64(location),
RString::from_f64(scale),
RString::from_bool(lower_tail),
RString::from_bool(false),
)))
.run()
.expect("R running error")
.as_f64();
r_assert_relative_equal_result!(r_ans, &rust_ans);
}
pub fn log_quantile_inner(p: f64, location: f64, scale: f64, lower_tail: bool) {
let mut builder = CauchyBuilder::new();
builder.with_location(location);
builder.with_scale(scale);
let cauchy = builder.build();
let rust_ans = cauchy.log_quantile(p, lower_tail);
let r_ans = RTester::new()
.set_display(&RString::from_string(format!(
"qcauchy({}, {}, {}, lower.tail={}, log={})",
RString::from_f64(p),
RString::from_f64(location),
RString::from_f64(scale),
RString::from_bool(lower_tail),
RString::from_bool(true),
)))
.run()
.expect("R running error")
.as_f64();
r_assert_relative_equal_result!(r_ans, &rust_ans);
}
pub fn random_inner(seed: u16, location: f64, scale: f64) {
let num = 50;
let r_state = RTester::new()
.set_seed(seed)
.set_display(&RString::from_str(".Random.seed").unwrap())
.run()
.unwrap()
.as_f64_vec()
.unwrap()
.into_iter()
.skip(1)
.map(|i| i as i32)
.collect::<Vec<_>>();
let mut rust_rng = MarsagliaMulticarry::new();
rust_rng.set_seed(seed as u32);
let rust_state = rust_rng.get_state();
for (r, rust) in r_state.iter().zip(rust_state.iter()) {
assert_eq!(r, rust, "States not equal!");
}
let r_ret = RTester::new()
.set_seed(seed)
.set_display(&RString::from_string(format!(
"rcauchy({}, {}, {})",
RString::from_f64(num),
RString::from_f64(location),
RString::from_f64(scale),
)))
.run()
.unwrap()
.as_f64_vec()
.unwrap();
let mut builder = CauchyBuilder::new();
builder.with_location(location);
builder.with_scale(scale);
let cauchy = builder.build();
reset_statics();
let rust_ret = (0..num)
.map(|_| cauchy.random_sample(&mut rust_rng))
.collect::<Vec<_>>();
for (r, rust) in r_ret.iter().zip(rust_ret.iter()) {
r_assert_relative_equal!(*r, rust.unwrap());
}
}