1 #ifndef __STAN__AGRAD__REV__MATRIX__MULTIPLY_HPP__
2 #define __STAN__AGRAD__REV__MATRIX__MULTIPLY_HPP__
5 #include <boost/math/tools/promotion.hpp>
26 template <
typename T1,
typename T2>
28 typename boost::math::tools::promote_args<T1,T2>::type
39 template<
typename T1,
typename T2,
int R2,
int C2>
40 inline Eigen::Matrix<var,R2,C2>
multiply(
const T1& c,
41 const Eigen::Matrix<T2, R2, C2>& m) {
53 template<
typename T1,
int R1,
int C1,
typename T2>
54 inline Eigen::Matrix<var,R1,C1>
multiply(
const Eigen::Matrix<T1, R1, C1>& m,
69 template<
int R1,
int C1,
int R2,
int C2>
70 inline Eigen::Matrix<var,R1,C2>
multiply(
const Eigen::Matrix<var,R1,C1>& m1,
71 const Eigen::Matrix<var,R2,C2>& m2) {
73 Eigen::Matrix<var,R1,C2> result(m1.rows(),m2.cols());
74 for (
int i = 0; i < m1.rows(); i++) {
75 typename Eigen::Matrix<var,R1,C1>::ConstRowXpr crow(m1.row(i));
76 for (
int j = 0; j < m2.cols(); j++) {
77 typename Eigen::Matrix<var,R2,C2>::ConstColXpr ccol(m2.col(j));
80 result(i,j) =
var(
new dot_product_vv_vari(crow,ccol));
83 dot_product_vv_vari *v2 =
static_cast<dot_product_vv_vari*
>(result(0,j).vi_);
84 result(i,j) =
var(
new dot_product_vv_vari(crow,ccol,NULL,v2));
89 dot_product_vv_vari *v1 =
static_cast<dot_product_vv_vari*
>(result(i,0).vi_);
90 result(i,j) =
var(
new dot_product_vv_vari(crow,ccol,v1));
93 dot_product_vv_vari *v1 =
static_cast<dot_product_vv_vari*
>(result(i,0).vi_);
94 dot_product_vv_vari *v2 =
static_cast<dot_product_vv_vari*
>(result(0,j).vi_);
95 result(i,j) =
var(
new dot_product_vv_vari(crow,ccol,v1,v2));
113 template<
int R1,
int C1,
int R2,
int C2>
114 inline Eigen::Matrix<var,R1,C2>
multiply(
const Eigen::Matrix<double,R1,C1>& m1,
115 const Eigen::Matrix<var,R2,C2>& m2) {
117 Eigen::Matrix<var,R1,C2> result(m1.rows(),m2.cols());
118 for (
int i = 0; i < m1.rows(); i++) {
119 typename Eigen::Matrix<double,R1,C1>::ConstRowXpr crow(m1.row(i));
120 for (
int j = 0; j < m2.cols(); j++) {
121 typename Eigen::Matrix<var,R2,C2>::ConstColXpr ccol(m2.col(j));
125 result(i,j) =
var(
new dot_product_vd_vari(ccol,crow));
128 dot_product_vd_vari *v2 =
static_cast<dot_product_vd_vari*
>(result(0,j).vi_);
129 result(i,j) =
var(
new dot_product_vd_vari(ccol,crow,v2,NULL));
134 dot_product_vd_vari *v1 =
static_cast<dot_product_vd_vari*
>(result(i,0).vi_);
135 result(i,j) =
var(
new dot_product_vd_vari(ccol,crow,NULL,v1));
138 dot_product_vd_vari *v1 =
static_cast<dot_product_vd_vari*
>(result(i,0).vi_);
139 dot_product_vd_vari *v2 =
static_cast<dot_product_vd_vari*
>(result(0,j).vi_);
140 result(i,j) =
var(
new dot_product_vd_vari(ccol,crow,v2,v1));
158 template<
int R1,
int C1,
int R2,
int C2>
159 inline Eigen::Matrix<var,R1,C2>
multiply(
const Eigen::Matrix<var,R1,C1>& m1,
160 const Eigen::Matrix<double,R2,C2>& m2) {
162 Eigen::Matrix<var,R1,C2> result(m1.rows(),m2.cols());
163 for (
int i = 0; i < m1.rows(); i++) {
164 typename Eigen::Matrix<var,R1,C1>::ConstRowXpr crow(m1.row(i));
165 for (
int j = 0; j < m2.cols(); j++) {
166 typename Eigen::Matrix<double,R2,C2>::ConstColXpr ccol(m2.col(j));
170 result(i,j) =
var(
new dot_product_vd_vari(crow,ccol));
173 dot_product_vd_vari *v2 =
static_cast<dot_product_vd_vari*
>(result(0,j).vi_);
174 result(i,j) =
var(
new dot_product_vd_vari(crow,ccol,NULL,v2));
179 dot_product_vd_vari *v1 =
static_cast<dot_product_vd_vari*
>(result(i,0).vi_);
180 result(i,j) =
var(
new dot_product_vd_vari(crow,ccol,v1,NULL));
183 dot_product_vd_vari *v1 =
static_cast<dot_product_vd_vari*
>(result(i,0).vi_);
184 dot_product_vd_vari *v2 =
static_cast<dot_product_vd_vari*
>(result(0,j).vi_);
185 result(i,j) =
var(
new dot_product_vd_vari(crow,ccol,v1,v2));
202 template <
int C1,
int R2>
204 const Eigen::Matrix<var, R2, 1>& v) {
205 if (rv.size() != v.size())
206 throw std::domain_error(
"row vector and vector must be same length in multiply");
218 template <
int C1,
int R2>
220 const Eigen::Matrix<var, R2, 1>& v) {
233 template <
int C1,
int R2>
235 const Eigen::Matrix<double, R2, 1>& v) {