1 #ifndef STAN_MATH_PRIM_FUN_TCROSSPROD_HPP 2 #define STAN_MATH_PRIM_FUN_TCROSSPROD_HPP 3 4 #include <stan/math/prim/meta.hpp> 5 #include <stan/math/prim/fun/Eigen.hpp> 6 #include <stan/math/prim/fun/to_ref.hpp> 7 #include <stan/math/prim/fun/typedefs.hpp> 8 9 namespace stan { 10 namespace math { 11 12 /** 13 * Returns the result of post-multiplying a matrix by its 14 * own transpose. 15 * 16 * @tparam T type of the matrix (must be derived from \c Eigen::MatrixBase) 17 * @param M Matrix to multiply. 18 * @return M times its transpose. 19 */ 20 template <typename T, require_eigen_vt<std::is_arithmetic, T>* = nullptr> 21 inline Eigen::Matrix<value_type_t<T>, T::RowsAtCompileTime, 22 T::RowsAtCompileTime> tcrossprod(const T & M)23tcrossprod(const T& M) { 24 if (M.rows() == 0) { 25 return {}; 26 } 27 const auto& M_ref = to_ref(M); 28 if (M.rows() == 1) { 29 return M_ref * M_ref.transpose(); 30 } 31 Eigen::Matrix<value_type_t<T>, T::RowsAtCompileTime, T::RowsAtCompileTime> 32 result(M.rows(), M.rows()); 33 return result.setZero().template selfadjointView<Eigen::Upper>().rankUpdate( 34 M_ref); 35 } 36 37 } // namespace math 38 } // namespace stan 39 40 #endif 41