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)21 var 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