use crate::dag_sampling::memoization::Memoization;
use deep_causality_algebra::RealField;
use deep_causality_num::FromPrimitive;
#[inline]
fn from_usize<T: FromPrimitive>(n: usize) -> T {
<T as FromPrimitive>::from_usize(n).expect("count is representable in every RealField")
}
pub(crate) fn factorial<T: RealField + FromPrimitive>(
n: usize,
memoization: &mut [Option<T>],
) -> T {
if let Some(res) = memoization[n] {
return res;
}
let mut result = T::one();
for i in 1..n + 1 {
result *= from_usize::<T>(i);
}
memoization[n] = Some(result);
result
}
pub(crate) fn rho<T: RealField + FromPrimitive>(
x: &[usize],
memoization: &mut Memoization<T>,
) -> T {
let x_vec = x.to_vec();
if let Some(res) = memoization.rho.get(&x_vec) {
return *res;
}
let mut result = factorial(x[0], &mut memoization.factorial);
for i in 1..x.len() {
let lead = factorial(x[0] - x[i], &mut memoization.factorial);
let tail = rho(&x[i..], memoization);
result -= lead * tail;
}
memoization.rho.insert(x_vec, result);
result
}