1 #ifndef STAN_MATH_REV_FUN_TCROSSPROD_HPP 2 #define STAN_MATH_REV_FUN_TCROSSPROD_HPP 3 4 #include <stan/math/rev/meta.hpp> 5 #include <stan/math/rev/core.hpp> 6 #include <stan/math/rev/core/typedefs.hpp> 7 #include <stan/math/rev/fun/dot_product.hpp> 8 #include <stan/math/rev/fun/dot_self.hpp> 9 #include <stan/math/prim/meta.hpp> 10 #include <stan/math/prim/fun/Eigen.hpp> 11 12 namespace stan { 13 namespace math { 14 15 /** 16 * Returns the result of post-multiplying a matrix by its 17 * own transpose. 18 * 19 * @tparam T Type of the matrix 20 * @param M Matrix to multiply. 21 * @return M times its transpose. 22 */ 23 template <typename T, require_rev_matrix_t<T>* = nullptr> tcrossprod(const T & M)24inline auto tcrossprod(const T& M) { 25 using ret_type = return_var_matrix_t< 26 Eigen::Matrix<double, T::RowsAtCompileTime, T::RowsAtCompileTime>, T>; 27 arena_t<T> arena_M = M; 28 arena_t<ret_type> res = arena_M.val_op() * arena_M.val_op().transpose(); 29 30 if (likely(M.size() > 0)) { 31 reverse_pass_callback([res, arena_M]() mutable { 32 arena_M.adj() 33 += (res.adj_op() + res.adj_op().transpose()) * arena_M.val_op(); 34 }); 35 } 36 37 return ret_type(res); 38 } 39 40 } // namespace math 41 } // namespace stan 42 #endif 43