1 #ifndef STAN_MATH_REV_MAT_FUN_MULTIPLY_HPP 2 #define STAN_MATH_REV_MAT_FUN_MULTIPLY_HPP 10 #include <boost/math/tools/promotion.hpp> 11 #include <type_traits> 33 template <
typename Ta,
int Ra,
int Ca,
typename Tb,
int Cb>
64 const Eigen::Matrix<Tb, Ca, Cb>& B)
71 Ad_(
ChainableStack::instance_->memalloc_.alloc_array<double>(A_size_)),
72 Bd_(
ChainableStack::instance_->memalloc_.alloc_array<double>(B_size_)),
80 using Eigen::MatrixXd;
81 for (
size_type i = 0; i < A.size(); ++i) {
82 variRefA_[i] = A.coeffRef(i).vi_;
83 Ad_[i] = A.coeffRef(i).val();
85 for (
size_type i = 0; i < B.size(); ++i) {
86 variRefB_[i] = B.coeffRef(i).vi_;
87 Bd_[i] = B.coeffRef(i).val();
90 * Map<MatrixXd>(Bd_, A_cols_, B_cols_);
92 variRefAB_[i] =
new vari(AB.coeffRef(i),
false);
97 using Eigen::MatrixXd;
98 MatrixXd adjAB(A_rows_, B_cols_);
99 MatrixXd adjA(A_rows_, A_cols_);
100 MatrixXd adjB(A_cols_, B_cols_);
102 for (
size_type i = 0; i < adjAB.size(); ++i)
103 adjAB(i) = variRefAB_[i]->
adj_;
107 variRefA_[i]->
adj_ += adjA(i);
109 variRefB_[i]->
adj_ += adjB(i);
128 template <
typename Ta,
int Ca,
typename Tb>
155 const Eigen::Matrix<Tb, Ca, 1>& B)
158 Ad_(
ChainableStack::instance_->memalloc_.alloc_array<double>(size_)),
159 Bd_(
ChainableStack::instance_->memalloc_.alloc_array<double>(size_)),
165 using Eigen::RowVectorXd;
166 using Eigen::VectorXd;
168 variRefA_[i] = A.coeffRef(i).vi_;
169 Ad_[i] = A.coeffRef(i).val();
172 variRefB_[i] = B.coeffRef(i).vi_;
173 Bd_[i] = B.coeffRef(i).val();
175 double AB = Map<RowVectorXd>(
Ad_, 1, size_) * Map<VectorXd>(Bd_, size_, 1);
176 variRefAB_ =
new vari(AB,
false);
181 using Eigen::RowVectorXd;
182 using Eigen::VectorXd;
185 adjAB = variRefAB_->
adj_;
186 auto adjA = adjAB * Map<VectorXd>(
Bd_, size_, 1).
transpose();
187 auto adjB = Map<RowVectorXd>(
Ad_, 1, size_).
transpose() * adjAB;
189 variRefA_[i]->
adj_ += adjA(i);
191 variRefB_[i]->
adj_ += adjB(i);
211 template <
int Ra,
int Ca,
typename Tb,
int Cb>
241 const Eigen::Matrix<Tb, Ca, Cb>& B)
248 Ad_(
ChainableStack::instance_->memalloc_.alloc_array<double>(A_size_)),
249 Bd_(
ChainableStack::instance_->memalloc_.alloc_array<double>(B_size_)),
253 A_rows_ * B_cols_)) {
255 using Eigen::MatrixXd;
257 Ad_[i] = A.coeffRef(i);
258 for (
size_type i = 0; i < B.size(); ++i) {
259 variRefB_[i] = B.coeffRef(i).vi_;
260 Bd_[i] = B.coeffRef(i).val();
263 * Map<MatrixXd>(Bd_, A_cols_, B_cols_);
264 for (
size_type i = 0; i < AB.size(); ++i)
265 variRefAB_[i] =
new vari(AB.coeffRef(i),
false);
270 using Eigen::MatrixXd;
271 MatrixXd adjAB(A_rows_, B_cols_);
272 MatrixXd adjB(A_cols_, B_cols_);
274 for (
size_type i = 0; i < adjAB.size(); ++i)
275 adjAB(i) = variRefAB_[i]->
adj_;
278 variRefB_[i]->
adj_ += adjB(i);
297 template <
int Ca,
typename Tb>
323 const Eigen::Matrix<Tb, Ca, 1>& B)
326 Ad_(
ChainableStack::instance_->memalloc_.alloc_array<double>(size_)),
327 Bd_(
ChainableStack::instance_->memalloc_.alloc_array<double>(size_)),
331 using Eigen::RowVectorXd;
332 using Eigen::VectorXd;
334 Ad_[i] = A.coeffRef(i);
336 variRefB_[i] = B.coeffRef(i).vi_;
337 Bd_[i] = B.coeffRef(i).val();
339 double AB = Eigen::Map<RowVectorXd>(
Ad_, 1, size_)
340 * Eigen::Map<VectorXd>(Bd_, size_, 1);
341 variRefAB_ =
new vari(AB,
false);
346 using Eigen::RowVectorXd;
347 using Eigen::VectorXd;
350 adjAB = variRefAB_->
adj_;
351 auto adjB = Map<RowVectorXd>(
Ad_, 1, size_).
transpose() * adjAB;
353 variRefB_[i]->
adj_ += adjB(i);
373 template <
typename Ta,
int Ra,
int Ca,
int Cb>
403 const Eigen::Matrix<double, Ca, Cb>& B)
410 Ad_(
ChainableStack::instance_->memalloc_.alloc_array<double>(A_size_)),
411 Bd_(
ChainableStack::instance_->memalloc_.alloc_array<double>(B_size_)),
415 A_rows_ * B_cols_)) {
417 using Eigen::MatrixXd;
419 variRefA_[i] = A.coeffRef(i).vi_;
420 Ad_[i] = A.coeffRef(i).val();
423 Bd_[i] = B.coeffRef(i);
426 * Map<MatrixXd>(Bd_, A_cols_, B_cols_);
427 for (
size_type i = 0; i < AB.size(); ++i)
428 variRefAB_[i] =
new vari(AB.coeffRef(i),
false);
433 using Eigen::MatrixXd;
434 MatrixXd adjAB(A_rows_, B_cols_);
435 MatrixXd adjA(A_rows_, A_cols_);
437 for (
size_type i = 0; i < adjAB.size(); ++i)
438 adjAB(i) = variRefAB_[i]->
adj_;
441 variRefA_[i]->
adj_ += adjA(i);
463 template <
typename Ta,
int Ca>
489 const Eigen::Matrix<double, Ca, 1>& B)
492 Ad_(
ChainableStack::instance_->memalloc_.alloc_array<double>(size_)),
493 Bd_(
ChainableStack::instance_->memalloc_.alloc_array<double>(size_)),
497 using Eigen::RowVectorXd;
498 using Eigen::VectorXd;
500 variRefA_[i] = A.coeffRef(i).vi_;
501 Ad_[i] = A.coeffRef(i).val();
504 Bd_[i] = B.coeffRef(i);
505 double AB = Map<RowVectorXd>(
Ad_, 1, size_) * Map<VectorXd>(Bd_, size_, 1);
506 variRefAB_ =
new vari(AB,
false);
511 using Eigen::RowVectorXd;
512 using Eigen::VectorXd;
515 adjAB = variRefAB_->
adj_;
516 auto adjA = adjAB * Map<VectorXd>(
Bd_, size_, 1).
transpose();
518 variRefA_[i]->
adj_ += adjA(i);
530 template <
typename T1,
typename T2>
531 inline typename std::enable_if<
532 (boost::is_scalar<T1>::value || std::is_same<T1, var>::value)
533 && (boost::is_scalar<T2>::value || std::is_same<T2, var>::value),
534 typename boost::math::tools::promote_args<T1, T2>::type>::type
549 template <
typename T1,
typename T2,
int R2,
int C2>
550 inline Eigen::Matrix<var, R2, C2>
multiply(
const T1& c,
551 const Eigen::Matrix<T2, R2, C2>& m) {
567 template <
typename T1,
int R1,
int C1,
typename T2>
568 inline Eigen::Matrix<var, R1, C1>
multiply(
const Eigen::Matrix<T1, R1, C1>& m,
587 template <
typename Ta,
int Ra,
int Ca,
typename Tb,
int Cb>
588 inline typename std::enable_if<std::is_same<Ta, var>::value
589 || std::is_same<Tb, var>::value,
590 Eigen::Matrix<var, Ra, Cb> >::type
592 const Eigen::Matrix<Tb, Ca, Cb>& B) {
600 Eigen::Matrix<var, Ra, Cb> AB_v(A.rows(), B.cols());
601 for (
size_type i = 0; i < AB_v.size(); ++i) {
602 AB_v.coeffRef(i).vi_ = baseVari->
variRefAB_[i];
617 template <
typename Ta,
int Ca,
typename Tb>
618 inline typename std::enable_if<
619 std::is_same<Ta, var>::value || std::is_same<Tb, var>::value,
var>::type
620 multiply(
const Eigen::Matrix<Ta, 1, Ca>& A,
const Eigen::Matrix<Tb, Ca, 1>& B) {
multiply_mat_vari(const Eigen::Matrix< double, 1, Ca > &A, const Eigen::Matrix< Tb, Ca, 1 > &B)
Constructor for multiply_mat_vari.
int rows(const Eigen::Matrix< T, R, C > &m)
Return the number of rows in the specified matrix, vector, or row vector.
virtual void chain()
Apply the chain rule to this variable based on the variables on which it depends. ...
This is a subclass of the vari class for matrix multiplication A * B where A is N by M and B is M by ...
multiply_mat_vari(const Eigen::Matrix< Ta, 1, Ca > &A, const Eigen::Matrix< double, Ca, 1 > &B)
Constructor for multiply_mat_vari.
The variable implementation base class.
Eigen::Matrix< fvar< T >, R1, C1 > multiply(const Eigen::Matrix< fvar< T >, R1, C1 > &m, const fvar< T > &c)
multiply_mat_vari(const Eigen::Matrix< Ta, 1, Ca > &A, const Eigen::Matrix< Tb, Ca, 1 > &B)
Constructor for multiply_mat_vari.
Independent (input) and dependent (output) variables for gradients.
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic >::Index size_type
Type for sizes and indexes in an Eigen matrix with double e.
virtual void chain()
Apply the chain rule to this variable based on the variables on which it depends. ...
virtual void chain()
Apply the chain rule to this variable based on the variables on which it depends. ...
void check_not_nan(const char *function, const char *name, const T_y &y)
Check if y is not NaN.
multiply_mat_vari(const Eigen::Matrix< double, Ra, Ca > &A, const Eigen::Matrix< Tb, Ca, Cb > &B)
Constructor for multiply_mat_vari.
This is a subclass of the vari class for matrix multiplication A * B where A is 1 by M and B is M by ...
virtual void chain()
Apply the chain rule to this variable based on the variables on which it depends. ...
virtual void chain()
Apply the chain rule to this variable based on the variables on which it depends. ...
int cols(const Eigen::Matrix< T, R, C > &m)
Return the number of columns in the specified matrix, vector, or row vector.
multiply_mat_vari(const Eigen::Matrix< Ta, Ra, Ca > &A, const Eigen::Matrix< Tb, Ca, Cb > &B)
Constructor for multiply_mat_vari.
void check_multiplicable(const char *function, const char *name1, const T1 &y1, const char *name2, const T2 &y2)
Check if the matrices can be multiplied.
multiply_mat_vari(const Eigen::Matrix< Ta, Ra, Ca > &A, const Eigen::Matrix< double, Ca, Cb > &B)
Constructor for multiply_mat_vari.
matrix_cl transpose(const matrix_cl &src)
Takes the transpose of the matrix on the OpenCL device.
vari(double x)
Construct a variable implementation from a value.
int size(const std::vector< T > &x)
Return the size of the specified standard vector.
virtual void chain()
Apply the chain rule to this variable based on the variables on which it depends. ...
double adj_
The adjoint of this variable, which is the partial derivative of this variable with respect to the ro...
This struct always provides access to the autodiff stack using the singleton pattern.
std::vector< var > to_var(const std::vector< double > &v)
Converts argument to an automatic differentiation variable.