diff --git a/Cargo.toml b/Cargo.toml index 34549647..a8b6e4ca 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,7 +25,6 @@ rand = "0.8" nalgebra = { version = "0.32", features = ["rand"] } approx = "0.5.0" num-traits = "0.2.14" -lazy_static = "1.4.0" [dev-dependencies] criterion = "0.3.3" diff --git a/src/function/factorial.rs b/src/function/factorial.rs index e06e9bcf..77bcaa5b 100644 --- a/src/function/factorial.rs +++ b/src/function/factorial.rs @@ -90,26 +90,34 @@ pub fn checked_multinomial(n: u64, ni: &[u64]) -> Result { // Initialization for pre-computed cache of 171 factorial // values 0!...170! -lazy_static! { - static ref FCACHE: [f64; MAX_FACTORIAL + 1] = { - let mut fcache = [1.0; MAX_FACTORIAL + 1]; - fcache - .iter_mut() - .enumerate() - .skip(1) - .fold(1.0, |acc, (i, elt)| { - let fac = acc * i as f64; - *elt = fac; - fac - }); - fcache - }; -} +const FCACHE: [f64; MAX_FACTORIAL + 1] = { + let mut fcache = [1.0; MAX_FACTORIAL + 1]; + + // `const` only allow while loops + let mut i = 1; + while i < MAX_FACTORIAL + 1 { + fcache[i] = fcache[i - 1] * i as f64; + i += 1; + } + + fcache +}; #[cfg(test)] mod tests { use super::*; + #[test] + fn test_fcache() { + assert!((FCACHE[0] - 1.0).abs() < f64::EPSILON); + assert!((FCACHE[1] - 1.0).abs() < f64::EPSILON); + assert!((FCACHE[2] - 2.0).abs() < f64::EPSILON); + assert!((FCACHE[3] - 6.0).abs() < f64::EPSILON); + assert!((FCACHE[4] - 24.0).abs() < f64::EPSILON); + assert!((FCACHE[70] - 1197857166996989e85).abs() < f64::EPSILON); + assert!((FCACHE[170] - 7257415615307994e291).abs() < f64::EPSILON); + } + #[test] fn test_factorial_and_ln_factorial() { let mut fac = 1.0; diff --git a/src/lib.rs b/src/lib.rs index 939400fb..ad234627 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -55,9 +55,6 @@ #[macro_use] extern crate approx; -#[macro_use] -extern crate lazy_static; - #[macro_export] macro_rules! assert_almost_eq { ($a:expr, $b:expr, $prec:expr) => {