diff --git a/src/linalg/cholesky.rs b/src/linalg/cholesky.rs index 4d530927..02101748 100644 --- a/src/linalg/cholesky.rs +++ b/src/linalg/cholesky.rs @@ -1,7 +1,7 @@ #[cfg(feature = "serde-serialize-no-std")] use serde::{Deserialize, Serialize}; -use num::One; +use num::{One, Zero}; use simba::scalar::ComplexField; use simba::simd::SimdComplexField; @@ -161,6 +161,27 @@ where } prod_diag.simd_modulus_squared() } + + /// Computes the natural logarithm of determinant of the decomposed matrix. + /// + /// This method is more robust than `.determinant()` to very small or very + /// large determinants since it returns the natural logarithm of the + /// determinant rather than the determinant itself. + #[must_use] + pub fn ln_determinant(&self) -> T::SimdRealField { + let dim = self.chol.nrows(); + let mut sum_diag = T::SimdRealField::zero(); + for i in 0..dim { + sum_diag += unsafe { + self.chol + .get_unchecked((i, i)) + .clone() + .simd_modulus_squared() + .simd_ln() + }; + } + sum_diag + } } impl Cholesky