1 #ifndef STAN_MATH_REV_MAT_FUN_MULTIPLY_HPP
2 #define STAN_MATH_REV_MAT_FUN_MULTIPLY_HPP
13 #include <boost/math/tools/promotion.hpp>
14 #include <boost/utility/enable_if.hpp>
15 #include <boost/type_traits.hpp>
37 template <
typename TA,
int RA,
int CA,
typename TB,
int CB>
64 const Eigen::Matrix<TB, CA, CB>& B)
66 A_rows_(A.
rows()), A_cols_(A.
cols()),
75 using Eigen::MatrixXd;
76 for (
size_type i = 0; i < A.size(); ++i) {
77 variRefA_[i] = A.coeffRef(i).vi_;
78 Ad_[i] = A.coeffRef(i).val();
80 for (
size_type i = 0; i < B.size(); ++i) {
81 variRefB_[i] = B.coeffRef(i).vi_;
82 Bd_[i] = B.coeffRef(i).val();
86 * Map<MatrixXd>(Bd_, A_cols_, B_cols_);
88 variRefAB_[i] =
new vari(AB.coeffRef(i),
false);
92 using Eigen::MatrixXd;
94 MatrixXd adjAB(A_rows_, B_cols_);
95 MatrixXd adjA(A_rows_, A_cols_);
96 MatrixXd adjB(A_cols_, B_cols_);
98 for (
size_type i = 0; i < adjAB.size(); ++i)
99 adjAB(i) = variRefAB_[i]->
adj_;
105 variRefA_[i]->
adj_ += adjA(i);
107 variRefB_[i]->
adj_ += adjB(i);
126 template <
typename TA,
int CA,
typename TB>
153 const Eigen::Matrix<TB, CA, 1>& B)
161 using Eigen::VectorXd;
162 using Eigen::RowVectorXd;
164 variRefA_[i] = A.coeffRef(i).vi_;
165 Ad_[i] = A.coeffRef(i).val();
168 variRefB_[i] = B.coeffRef(i).vi_;
169 Bd_[i] = B.coeffRef(i).val();
171 double AB = Map<RowVectorXd>(
Ad_, 1,
size_)
172 * Map<VectorXd>(Bd_, size_, 1);
173 variRefAB_ =
new vari(AB,
false);
177 using Eigen::VectorXd;
178 using Eigen::RowVectorXd;
181 RowVectorXd adjA(size_);
182 VectorXd adjB(size_);
184 adjAB = variRefAB_->
adj_;
190 variRefA_[i]->
adj_ += adjA(i);
192 variRefB_[i]->
adj_ += adjB(i);
212 template <
int RA,
int CA,
typename TB,
int CB>
238 const Eigen::Matrix<TB, CA, CB>& B)
240 A_rows_(A.
rows()), A_cols_(A.
cols()),
241 B_cols_(B.
cols()), A_size_(A.
size()), B_size_(B.
size()),
247 using Eigen::MatrixXd;
250 Ad_[i] = A.coeffRef(i);
251 for (
size_type i = 0; i < B.size(); ++i) {
252 variRefB_[i] = B.coeffRef(i).vi_;
253 Bd_[i] = B.coeffRef(i).val();
257 * Map<MatrixXd>(Bd_, A_cols_, B_cols_);
258 for (
size_type i = 0; i < AB.size(); ++i)
259 variRefAB_[i] =
new vari(AB.coeffRef(i),
false);
263 using Eigen::MatrixXd;
265 MatrixXd adjAB(A_rows_, B_cols_);
266 MatrixXd adjB(A_cols_, B_cols_);
268 for (
size_type i = 0; i < adjAB.size(); ++i)
269 adjAB(i) = variRefAB_[i]->
adj_;
273 variRefB_[i]->
adj_ += adjB(i);
292 template <
int CA,
typename TB>
318 const Eigen::Matrix<TB, CA, 1>& B)
325 using Eigen::VectorXd;
326 using Eigen::RowVectorXd;
328 Ad_[i] = A.coeffRef(i);
330 variRefB_[i] = B.coeffRef(i).vi_;
331 Bd_[i] = B.coeffRef(i).val();
334 = Eigen::Map<RowVectorXd>(
Ad_, 1,
size_)
335 * Eigen::Map<VectorXd>(Bd_, size_, 1);
336 variRefAB_ =
new vari(AB,
false);
340 using Eigen::RowVectorXd;
341 using Eigen::VectorXd;
344 VectorXd adjB(size_);
346 adjAB = variRefAB_->
adj_;
350 variRefB_[i]->
adj_ += adjB(i);
370 template <
typename TA,
int RA,
int CA,
int CB>
396 const Eigen::Matrix<double, CA, CB>& B)
398 A_rows_(A.
rows()), A_cols_(A.
cols()),
399 B_cols_(B.
cols()), A_size_(A.
size()), B_size_(B.
size()),
406 using Eigen::MatrixXd;
408 variRefA_[i] = A.coeffRef(i).vi_;
409 Ad_[i] = A.coeffRef(i).val();
412 Bd_[i] = B.coeffRef(i);
416 * Map<MatrixXd>(Bd_, A_cols_, B_cols_);
417 for (
size_type i = 0; i < AB.size(); ++i)
418 variRefAB_[i] =
new vari(AB.coeffRef(i),
false);
422 using Eigen::MatrixXd;
424 MatrixXd adjAB(A_rows_, B_cols_);
425 MatrixXd adjA(A_rows_, A_cols_);
427 for (
size_type i = 0; i < adjAB.size(); ++i)
428 adjAB(i) = variRefAB_[i]->
adj_;
431 variRefA_[i]->
adj_ += adjA(i);
453 template <
typename TA,
int CA>
479 const Eigen::Matrix<double, CA, 1>& B)
486 using Eigen::VectorXd;
487 using Eigen::RowVectorXd;
489 variRefA_[i] = A.coeffRef(i).vi_;
490 Ad_[i] = A.coeffRef(i).val();
493 Bd_[i] = B.coeffRef(i);
496 * Map<VectorXd>(Bd_, size_, 1);
497 variRefAB_ =
new vari(AB,
false);
502 using Eigen::VectorXd;
503 using Eigen::RowVectorXd;
505 RowVectorXd adjA(size_);
507 adjAB = variRefAB_->
adj_;
511 variRefA_[i]->
adj_ += adjA(i);
523 template <
typename T1,
typename T2>
526 (boost::is_scalar<T1>::value || boost::is_same<T1, var>::value)
527 && (boost::is_scalar<T2>::value || boost::is_same<T2, var>::value),
528 typename boost::math::tools::promote_args<T1, T2>::type>::type
543 template<
typename T1,
typename T2,
int R2,
int C2>
544 inline Eigen::Matrix<var, R2, C2>
545 multiply(
const T1& c,
const Eigen::Matrix<T2, R2, C2>& m) {
561 template<
typename T1,
int R1,
int C1,
typename T2>
562 inline Eigen::Matrix<var, R1, C1>
563 multiply(
const Eigen::Matrix<T1, R1, C1>& m,
const T2& c) {
581 template <
typename TA,
int RA,
int CA,
typename TB,
int CB>
583 boost::enable_if_c<boost::is_same<TA, var>::value
584 || boost::is_same<TB, var>::value,
585 Eigen::Matrix<var, RA, CB> >::type
587 const Eigen::Matrix<TB, CA, CB> &B) {
595 Eigen::Matrix<var, RA, CB> AB_v(A.rows(), B.cols());
596 for (
size_type i = 0; i < AB_v.size(); ++i) {
597 AB_v.coeffRef(i).vi_ = baseVari->
variRefAB_[i];
612 template <
typename TA,
int CA,
typename TB>
614 boost::enable_if_c<boost::is_same<TA, var>::value
615 || boost::is_same<TB, var>::value, var>::type
617 const Eigen::Matrix<TB, CA, 1> &B) {
vari(const double x)
Construct a variable implementation from a value.
int rows(const Eigen::Matrix< T, R, C > &m)
Return the number of rows in the specified matrix, vector, or row vector.
multiply_mat_vari(const Eigen::Matrix< TA, RA, CA > &A, const Eigen::Matrix< double, CA, CB > &B)
Constructor for multiply_mat_vari.
virtual void chain()
Apply the chain rule to this variable based on the variables on which it depends. ...
bool check_not_nan(const char *function, const char *name, const T_y &y)
Return true if y is not NaN.
multiply_mat_vari(const Eigen::Matrix< double, 1, CA > &A, const Eigen::Matrix< TB, CA, 1 > &B)
Constructor for multiply_mat_vari.
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 ...
The variable implementation base class.
Eigen::Matrix< fvar< T >, R1, C1 > multiply(const Eigen::Matrix< fvar< T >, R1, C1 > &m, const fvar< T > &c)
Independent (input) and dependent (output) variables for gradients.
multiply_mat_vari(const Eigen::Matrix< TA, RA, CA > &A, const Eigen::Matrix< TB, CA, CB > &B)
Constructor for multiply_mat_vari.
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. ...
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. ...
bool check_multiplicable(const char *function, const char *name1, const T1 &y1, const char *name2, const T2 &y2)
Return true if the matrices can be multiplied.
multiply_mat_vari(const Eigen::Matrix< TA, 1, CA > &A, const Eigen::Matrix< TB, CA, 1 > &B)
Constructor for multiply_mat_vari.
virtual void chain()
Apply the chain rule to this variable based on the variables on which it depends. ...
multiply_mat_vari(const Eigen::Matrix< double, RA, CA > &A, const Eigen::Matrix< TB, CA, CB > &B)
Constructor for multiply_mat_vari.
int cols(const Eigen::Matrix< T, R, C > &m)
Return the number of columns in the specified matrix, vector, or row vector.
int size(const std::vector< T > &x)
Return the size of the specified standard vector.
multiply_mat_vari(const Eigen::Matrix< TA, 1, CA > &A, const Eigen::Matrix< double, CA, 1 > &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 ...
double adj_
The adjoint of this variable, which is the partial derivative of this variable with respect to the ro...
Eigen::Matrix< T, C, R > transpose(const Eigen::Matrix< T, R, C > &m)
std::vector< var > to_var(const std::vector< double > &v)
Converts argument to an automatic differentiation variable.