1 #ifndef STAN_MATH_REV_FUN_LOG_DETERMINANT_LDLT_HPP 2 #define STAN_MATH_REV_FUN_LOG_DETERMINANT_LDLT_HPP 3 4 #include <stan/math/rev/meta.hpp> 5 #include <stan/math/rev/core.hpp> 6 #include <stan/math/rev/fun/LDLT_factor.hpp> 7 #include <stan/math/rev/core/typedefs.hpp> 8 #include <stan/math/prim/fun/Eigen.hpp> 9 10 namespace stan { 11 namespace math { 12 13 /** 14 * Returns the log det of the matrix whose LDLT factorization is given 15 * 16 * @tparam T Type of matrix for LDLT factor 17 * @param A an LDLT_factor 18 * @return ln(det(A)) 19 */ 20 template <typename T, require_rev_matrix_t<T>* = nullptr> log_determinant_ldlt(LDLT_factor<T> & A)21var log_determinant_ldlt(LDLT_factor<T>& A) { 22 if (A.matrix().size() == 0) { 23 return 0; 24 } 25 26 var log_det = sum(log(A.ldlt().vectorD().array())); 27 28 arena_t<T> arena_A = A.matrix(); 29 arena_t<Eigen::MatrixXd> arena_A_inv 30 = Eigen::MatrixXd::Identity(A.matrix().rows(), A.matrix().cols()); 31 32 A.ldlt().solveInPlace(arena_A_inv); 33 34 reverse_pass_callback([arena_A, log_det, arena_A_inv]() mutable { 35 arena_A.adj() += log_det.adj() * arena_A_inv; 36 }); 37 38 return log_det; 39 } 40 41 } // namespace math 42 } // namespace stan 43 #endif 44