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::hyper::HyperGeometricBuilder,
reset_statics,
rng::MarsagliaMulticarry,
traits::{Distribution, RNG},
};
pub fn density_inner(x: f64, group_1: f64, group_2: f64, number_drawn: f64) {
let mut builder = HyperGeometricBuilder::new();
builder.with_group_1(group_1);
builder.with_group_2(group_2);
builder.with_number_drawn(number_drawn);
let hyper = builder.build().expect("Build error");
let rust_ans = hyper.density(x);
let r_ans = RTester::new()
.set_display(&RString::from_string(format!(
"dhyper({}, {}, {}, {}, log={})",
RString::from_f64(x),
RString::from_f64(group_1),
RString::from_f64(group_2),
RString::from_f64(number_drawn),
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, group_1: f64, group_2: f64, number_drawn: f64) {
let mut builder = HyperGeometricBuilder::new();
builder.with_group_1(group_1);
builder.with_group_2(group_2);
builder.with_number_drawn(number_drawn);
let hyper = builder.build().expect("Build error");
let rust_ans = hyper.log_density(x);
let r_ans = RTester::new()
.set_display(&RString::from_string(format!(
"dhyper({}, {}, {}, {}, log={})",
RString::from_f64(x),
RString::from_f64(group_1),
RString::from_f64(group_2),
RString::from_f64(number_drawn),
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, group_1: f64, group_2: f64, number_drawn: f64, lower_tail: bool) {
let mut builder = HyperGeometricBuilder::new();
builder.with_group_1(group_1);
builder.with_group_2(group_2);
builder.with_number_drawn(number_drawn);
let hyper = builder.build().expect("Build error");
let rust_ans = hyper.probability(q, lower_tail);
let r_ans = RTester::new()
.set_display(&RString::from_string(format!(
"phyper({}, {}, {}, {}, lower.tail={}, log={})",
RString::from_f64(q),
RString::from_f64(group_1),
RString::from_f64(group_2),
RString::from_f64(number_drawn),
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,
group_1: f64,
group_2: f64,
number_drawn: f64,
lower_tail: bool,
) {
let mut builder = HyperGeometricBuilder::new();
builder.with_group_1(group_1);
builder.with_group_2(group_2);
builder.with_number_drawn(number_drawn);
let hyper = builder.build().expect("Build error");
let rust_ans = hyper.log_probability(q, lower_tail);
let r_ans = RTester::new()
.set_display(&RString::from_string(format!(
"phyper({}, {}, {}, {}, lower.tail={}, log={})",
RString::from_f64(q),
RString::from_f64(group_1),
RString::from_f64(group_2),
RString::from_f64(number_drawn),
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, group_1: f64, group_2: f64, number_drawn: f64, lower_tail: bool) {
let mut builder = HyperGeometricBuilder::new();
builder.with_group_1(group_1);
builder.with_group_2(group_2);
builder.with_number_drawn(number_drawn);
let hyper = builder.build().expect("Build error");
let rust_ans = hyper.quantile(p, lower_tail);
let r_ans = RTester::new()
.set_display(&RString::from_string(format!(
"qhyper({}, {}, {}, {}, lower.tail={}, log={})",
RString::from_f64(p),
RString::from_f64(group_1),
RString::from_f64(group_2),
RString::from_f64(number_drawn),
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, group_1: f64, group_2: f64, number_drawn: f64, lower_tail: bool) {
let mut builder = HyperGeometricBuilder::new();
builder.with_group_1(group_1);
builder.with_group_2(group_2);
builder.with_number_drawn(number_drawn);
let hyper = builder.build().expect("Build error");
let rust_ans = hyper.log_quantile(p, lower_tail);
let r_ans = RTester::new()
.set_display(&RString::from_string(format!(
"qhyper({}, {}, {}, {}, lower.tail={}, log={})",
RString::from_f64(p),
RString::from_f64(group_1),
RString::from_f64(group_2),
RString::from_f64(number_drawn),
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, group_1: f64, group_2: f64, number_drawn: 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!(
"rhyper({}, {}, {}, {})",
RString::from_f64(num),
RString::from_f64(group_1),
RString::from_f64(group_2),
RString::from_f64(number_drawn),
)))
.run()
.unwrap()
.as_f64_vec()
.unwrap();
let mut builder = HyperGeometricBuilder::new();
builder.with_group_1(group_1);
builder.with_group_2(group_2);
builder.with_number_drawn(number_drawn);
let hyper = builder.build().expect("Build error");
reset_statics();
let rust_ret = (0..num)
.map(|_| hyper.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());
}
}