1#ifndef STAN_MATH_REV_FUN_TRACE_DOT_HPP
2#define STAN_MATH_REV_FUN_TRACE_DOT_HPP
33template <
typename Mat1,
typename Mat2,
34 require_all_matrix_t<Mat1, Mat2>* =
nullptr,
35 require_any_rev_matrix_t<Mat1, Mat2>* =
nullptr>
39 if constexpr (is_autodiff_v<Mat1> && is_autodiff_v<Mat2>) {
42 auto res_val = arena_A.val().cwiseProduct(arena_B.val().transpose()).sum();
45 arena_A.adj().noalias() += res.adj() * arena_B.val().transpose();
47 arena_A.adj() += res.adj() * arena_B.val().transpose();
50 arena_B.adj().noalias() += res.adj() * arena_A.val().transpose();
52 arena_B.adj() += res.adj() * arena_A.val().transpose();
55 }
else if constexpr (is_autodiff_v<Mat2>) {
58 auto res_val = arena_A.cwiseProduct(arena_B.val().transpose()).sum();
61 arena_B.adj().noalias() += res.adj() * arena_A.transpose();
63 arena_B.adj() += res.adj() * arena_A.transpose();
69 auto res_val = arena_A.val().cwiseProduct(arena_B.transpose()).sum();
72 arena_A.adj().noalias() += res.adj() * arena_B.transpose();
74 arena_A.adj() += res.adj() * arena_B.transpose();
return_type_t< EigMat1, EigMat2 > trace_dot(EigMat1 &&A, EigMat2 &&B)
Compute the trace of the product of two matrices with forward-mode autodiff support.
var_value< plain_type_t< T > > make_callback_var(T &&value, F &&functor)
Creates a new var initialized with a callback_vari with a given value and reverse-pass callback funct...
void check_size_match(const char *function, const char *name_i, T_size1 i, const char *name_j, T_size2 j)
Check if the provided sizes match.
typename internal::arena_type_impl< std::decay_t< T > >::type arena_t
Determines a type that can be used in place of T that does any dynamic allocations on the AD stack.
The lgamma implementation in stan-math is based on either the reentrant safe lgamma_r implementation ...
Check if a type is a var_value whose value_type is derived from Eigen::EigenBase