Add ln_determinant to Cholesky

This commit is contained in:
Hennadii Chernyshchyk 2023-01-11 15:16:16 +02:00
parent 0981f9c660
commit 598cb4fa8d
No known key found for this signature in database
GPG Key ID: 24623302B8395825
1 changed files with 23 additions and 0 deletions

View File

@ -2,6 +2,7 @@
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use num::One; use num::One;
use num::Zero;
use simba::scalar::ComplexField; use simba::scalar::ComplexField;
use simba::simd::SimdComplexField; use simba::simd::SimdComplexField;
@ -41,6 +42,7 @@ where
impl<T: SimdComplexField, D: Dim> Cholesky<T, D> impl<T: SimdComplexField, D: Dim> Cholesky<T, D>
where where
DefaultAllocator: Allocator<T, D, D>, DefaultAllocator: Allocator<T, D, D>,
T::SimdRealField: Zero,
{ {
/// Computes the Cholesky decomposition of `matrix` without checking that the matrix is definite-positive. /// Computes the Cholesky decomposition of `matrix` without checking that the matrix is definite-positive.
/// ///
@ -161,6 +163,27 @@ where
} }
prod_diag.simd_modulus_squared() 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<T: ComplexField, D: Dim> Cholesky<T, D> impl<T: ComplexField, D: Dim> Cholesky<T, D>