1 #ifndef STAN_MATH_REV_FUN_EIGENVALUES_HPP 2 #define STAN_MATH_REV_FUN_EIGENVALUES_HPP 3 4 #include <stan/math/rev/meta.hpp> 5 #include <stan/math/rev/core.hpp> 6 #include <stan/math/rev/fun/value_of_rec.hpp> 7 #include <stan/math/rev/core/typedefs.hpp> 8 #include <stan/math/prim/fun/Eigen.hpp> 9 #include <stan/math/prim/err/check_symmetric.hpp> 10 #include <stan/math/prim/err/check_nonzero_size.hpp> 11 #include <stan/math/prim/fun/typedefs.hpp> 12 #include <stan/math/prim/fun/value_of_rec.hpp> 13 14 namespace stan { 15 namespace math { 16 17 /** 18 * Return the eigenvalues of the specified symmetric matrix. 19 * <p>See <code>eigen_decompose()</code> for more information. 20 * @tparam T type of input matrix. 21 * @param m Specified matrix. 22 * @return Eigenvalues of matrix. 23 */ 24 template <typename T, require_rev_matrix_t<T>* = nullptr> eigenvalues_sym(const T & m)25inline auto eigenvalues_sym(const T& m) { 26 using return_t = return_var_matrix_t<T>; 27 if (unlikely(m.size() == 0)) { 28 return return_t(m); 29 } 30 check_symmetric("eigenvalues_sym", "m", m); 31 32 auto arena_m = to_arena(m); 33 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> solver(arena_m.val()); 34 arena_t<return_t> eigenvals = solver.eigenvalues(); 35 auto eigenvecs = to_arena(solver.eigenvectors()); 36 37 reverse_pass_callback([eigenvals, arena_m, eigenvecs]() mutable { 38 arena_m.adj() 39 += eigenvecs * eigenvals.adj().asDiagonal() * eigenvecs.transpose(); 40 }); 41 42 return return_t(eigenvals); 43 } 44 45 } // namespace math 46 } // namespace stan 47 #endif 48