1 #ifndef __STAN__AGRAD__REV__MATRIX__COLUMNS_MDIVIDE_LEFT_HPP__
2 #define __STAN__AGRAD__REV__MATRIX__COLUMNS_MDIVIDE_LEFT_HPP__
16 template <
int R1,
int C1,
int R2,
int C2>
17 class mdivide_left_vv_vari :
public vari {
27 mdivide_left_vv_vari(
const Eigen::Matrix<var,R1,C1> &A,
28 const Eigen::Matrix<var,R2,C2> &B)
32 _A((double*)stan::agrad::
memalloc_.alloc(sizeof(double)
34 _C((double*)stan::agrad::
memalloc_.alloc(sizeof(double)
50 _A[pos++] = A(i,j).val();
58 _C[pos++] = B(i,j).val();
62 Matrix<double,R1,C2> C(_M,_N);
63 C = Map<Matrix<double,R1,C2> >(
_C,
_M,
_N);
65 C = Map<Matrix<double,R1,C1> >(
_A,
_M,
_M)
66 .colPivHouseholderQr().solve(C);
78 virtual void chain() {
81 Eigen::Matrix<double,R1,C1> adjA(
_M,
_M);
82 Eigen::Matrix<double,R2,C2> adjB(
_M,
_N);
83 Eigen::Matrix<double,R1,C2> adjC(
_M,
_N);
86 for (
size_type j = 0; j < adjC.cols(); j++)
87 for (
size_type i = 0; i < adjC.rows(); i++)
91 adjB = Map<Matrix<double,R1,C1> >(
_A,
_M,
_M)
92 .
transpose().colPivHouseholderQr().solve(adjC);
93 adjA.noalias() = -adjB
97 for (
size_type j = 0; j < adjA.cols(); j++)
98 for (
size_type i = 0; i < adjA.rows(); i++)
102 for (
size_type j = 0; j < adjB.cols(); j++)
103 for (
size_type i = 0; i < adjB.rows(); i++)
108 template <
int R1,
int C1,
int R2,
int C2>
109 class mdivide_left_dv_vari :
public vari {
118 mdivide_left_dv_vari(
const Eigen::Matrix<double,R1,C1> &A,
119 const Eigen::Matrix<var,R2,C2> &B)
123 _A((double*)stan::agrad::
memalloc_.alloc(sizeof(double)
125 _C((double*)stan::agrad::
memalloc_.alloc(sizeof(double)
146 _C[pos++] = B(i,j).val();
150 Matrix<double,R1,C2> C(_M,_N);
151 C = Map<Matrix<double,R1,C2> >(
_C,
_M,
_N);
153 C = Map<Matrix<double,R1,C1> >(
_A,
_M,
_M)
154 .colPivHouseholderQr().solve(C);
160 _variRefC[pos] =
new vari(_C[pos],
false);
166 virtual void chain() {
169 Eigen::Matrix<double,R2,C2> adjB(_M,_N);
170 Eigen::Matrix<double,R1,C2> adjC(_M,_N);
173 for (
size_type j = 0; j < adjC.cols(); j++)
174 for (
size_type i = 0; i < adjC.rows(); i++)
177 adjB = Map<Matrix<double,R1,C1> >(
_A,
_M,
_M)
178 .
transpose().colPivHouseholderQr().solve(adjC);
181 for (
size_type j = 0; j < adjB.cols(); j++)
182 for (
size_type i = 0; i < adjB.rows(); i++)
187 template <
int R1,
int C1,
int R2,
int C2>
188 class mdivide_left_vd_vari :
public vari {
197 mdivide_left_vd_vari(
const Eigen::Matrix<var,R1,C1> &A,
198 const Eigen::Matrix<double,R2,C2> &B)
202 _A((double*)stan::agrad::
memalloc_.alloc(sizeof(double)
204 _C((double*)stan::agrad::
memalloc_.alloc(sizeof(double)
218 _A[pos++] = A(i,j).val();
222 Matrix<double,R1,C2> C(_M,_N);
223 C = Map<Matrix<double,R1,C1> >(
_A,
_M,
_M)
224 .colPivHouseholderQr().solve(B);
230 _variRefC[pos] =
new vari(_C[pos],
false);
236 virtual void chain() {
239 Eigen::Matrix<double,R1,C1> adjA(_M,_M);
240 Eigen::Matrix<double,R1,C2> adjC(_M,_N);
243 for (
size_type j = 0; j < adjC.cols(); j++)
244 for (
size_type i = 0; i < adjC.rows(); i++)
248 adjA = -Map<Matrix<double,R1,C1> >(
_A,
_M,
_M)
250 .colPivHouseholderQr()
251 .solve(adjC*Map<Matrix<double,R1,C2> >(_C,_M,_N).
transpose());
254 for (
size_type j = 0; j < adjA.cols(); j++)
255 for (
size_type i = 0; i < adjA.rows(); i++)
261 template <
int R1,
int C1,
int R2,
int C2>
263 Eigen::Matrix<var,R1,C2>
265 const Eigen::Matrix<var,R2,C2> &b) {
266 Eigen::Matrix<var,R1,C2> res(b.rows(),b.cols());
274 mdivide_left_vv_vari<R1,C1,R2,C2> *baseVari =
new mdivide_left_vv_vari<R1,C1,R2,C2>(A,b);
277 for (
size_type j = 0; j < res.cols(); j++)
278 for (
size_type i = 0; i < res.rows(); i++)
279 res(i,j).vi_ = baseVari->_variRefC[pos++];
284 template <
int R1,
int C1,
int R2,
int C2>
286 Eigen::Matrix<var,R1,C2>
288 const Eigen::Matrix<double,R2,C2> &b) {
289 Eigen::Matrix<var,R1,C2> res(b.rows(),b.cols());
297 mdivide_left_vd_vari<R1,C1,R2,C2> *baseVari =
new mdivide_left_vd_vari<R1,C1,R2,C2>(A,b);
300 for (
size_type j = 0; j < res.cols(); j++)
301 for (
size_type i = 0; i < res.rows(); i++)
302 res(i,j).vi_ = baseVari->_variRefC[pos++];
307 template <
int R1,
int C1,
int R2,
int C2>
309 Eigen::Matrix<var,R1,C2>
311 const Eigen::Matrix<var,R2,C2> &b) {
312 Eigen::Matrix<var,R1,C2> res(b.rows(),b.cols());
320 mdivide_left_dv_vari<R1,C1,R2,C2> *baseVari =
new mdivide_left_dv_vari<R1,C1,R2,C2>(A,b);
323 for (
size_type j = 0; j < res.cols(); j++)
324 for (
size_type i = 0; i < res.rows(); i++)
325 res(i,j).vi_ = baseVari->_variRefC[pos++];