1 #ifndef __STAN__AGRAD__REV__MATRIX__MDIVIDE_LEFT_TRI_HPP__
2 #define __STAN__AGRAD__REV__MATRIX__MDIVIDE_LEFT_TRI_HPP__
16 template <
int TriView,
int R1,
int C1,
int R2,
int C2>
17 class mdivide_left_tri_vv_vari :
public vari {
27 mdivide_left_tri_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)
38 * (A.
rows() + 1) / 2)),
48 if (TriView == Eigen::Lower) {
52 }
else if (TriView == Eigen::Upper) {
61 _A[pos++] = A(i,j).val();
69 _C[pos++] = B(i,j).val();
73 Matrix<double,R1,C2> C(_M,_N);
74 C = Map<Matrix<double,R1,C2> >(
_C,
_M,
_N);
76 C = Map<Matrix<double,R1,C1> >(
_A,
_M,
_M)
77 .
template triangularView<TriView>().solve(C);
90 virtual void chain() {
93 Matrix<double,R1,C1> adjA(
_M,
_M);
94 Matrix<double,R2,C2> adjB(
_M,
_N);
95 Matrix<double,R1,C2> adjC(
_M,
_N);
98 for (
size_type j = 0; j < adjC.cols(); j++)
99 for (
size_type i = 0; i < adjC.rows(); i++)
102 adjB = Map<Matrix<double,R1,C1> >(
_A,
_M,
_M)
103 .
template triangularView<TriView>().transpose().solve(adjC);
104 adjA.noalias() = -adjB
108 if (TriView == Eigen::Lower) {
109 for (
size_type j = 0; j < adjA.cols(); j++)
110 for (
size_type i = j; i < adjA.rows(); i++)
112 }
else if (TriView == Eigen::Upper) {
113 for (
size_type j = 0; j < adjA.cols(); j++)
119 for (
size_type j = 0; j < adjB.cols(); j++)
120 for (
size_type i = 0; i < adjB.rows(); i++)
125 template <
int TriView,
int R1,
int C1,
int R2,
int C2>
126 class mdivide_left_tri_dv_vari :
public vari {
135 mdivide_left_tri_dv_vari(
const Eigen::Matrix<double,R1,C1> &A,
136 const Eigen::Matrix<var,R2,C2> &B)
140 _A((double*)stan::agrad::
memalloc_.alloc(sizeof(double)
142 _C((double*)stan::agrad::
memalloc_.alloc(sizeof(double)
163 _C[pos++] = B(i,j).val();
167 Matrix<double,R1,C2> C(_M,_N);
168 C = Map<Matrix<double,R1,C2> >(
_C,
_M,
_N);
170 C = Map<Matrix<double,R1,C1> >(
_A,
_M,
_M)
171 .
template triangularView<TriView>().solve(C);
177 _variRefC[pos] =
new vari(_C[pos],
false);
183 virtual void chain() {
186 Matrix<double,R2,C2> adjB(_M,_N);
187 Matrix<double,R1,C2> adjC(_M,_N);
190 for (
size_type j = 0; j < adjC.cols(); j++)
191 for (
size_type i = 0; i < adjC.rows(); i++)
194 adjB = Map<Matrix<double,R1,C1> >(
_A,
_M,
_M)
195 .
template triangularView<TriView>().transpose().solve(adjC);
198 for (
size_type j = 0; j < adjB.cols(); j++)
199 for (
size_type i = 0; i < adjB.rows(); i++)
204 template <
int TriView,
int R1,
int C1,
int R2,
int C2>
205 class mdivide_left_tri_vd_vari :
public vari {
214 mdivide_left_tri_vd_vari(
const Eigen::Matrix<var,R1,C1> &A,
215 const Eigen::Matrix<double,R2,C2> &B)
219 _A((double*)stan::agrad::
memalloc_.alloc(sizeof(double)
221 _C((double*)stan::agrad::
memalloc_.alloc(sizeof(double)
225 * (A.
rows() + 1) / 2)),
233 if (TriView == Eigen::Lower) {
237 }
else if (TriView == Eigen::Upper) {
246 _A[pos++] = A(i,j).val();
250 Matrix<double,R1,C2> C(_M,_N);
251 C = Map<Matrix<double,R1,C1> >(
_A,
_M,
_M)
252 .
template triangularView<TriView>().solve(B);
258 _variRefC[pos] =
new vari(_C[pos],
false);
264 virtual void chain() {
267 Matrix<double,R1,C1> adjA(_M,_M);
268 Matrix<double,R1,C2> adjC(_M,_N);
271 for (
size_type j = 0; j < adjC.cols(); j++)
272 for (
size_type i = 0; i < adjC.rows(); i++)
275 adjA.noalias() = -Map<Matrix<double,R1,C1> >(
_A,
_M,
_M)
276 .
template triangularView<TriView>()
277 .transpose().solve(adjC*Map<Matrix<double,R1,C2> >(_C,_M,_N).
transpose());
280 if (TriView == Eigen::Lower) {
281 for (
size_type j = 0; j < adjA.cols(); j++)
282 for (
size_type i = j; i < adjA.rows(); i++)
284 }
else if (TriView == Eigen::Upper) {
285 for (
size_type j = 0; j < adjA.cols(); j++)
293 template <
int TriView,
int R1,
int C1,
int R2,
int C2>
295 Eigen::Matrix<var,R1,C2>
297 const Eigen::Matrix<var,R2,C2> &b) {
298 Eigen::Matrix<var,R1,C2> res(b.rows(),b.cols());
306 mdivide_left_tri_vv_vari<TriView,R1,C1,R2,C2> *baseVari =
new mdivide_left_tri_vv_vari<TriView,R1,C1,R2,C2>(A,b);
309 for (
size_type j = 0; j < res.cols(); j++)
310 for (
size_type i = 0; i < res.rows(); i++)
311 res(i,j).vi_ = baseVari->_variRefC[pos++];
315 template <
int TriView,
int R1,
int C1,
int R2,
int C2>
317 Eigen::Matrix<var,R1,C2>
319 const Eigen::Matrix<var,R2,C2> &b) {
320 Eigen::Matrix<var,R1,C2> res(b.rows(),b.cols());
328 mdivide_left_tri_dv_vari<TriView,R1,C1,R2,C2> *baseVari =
new mdivide_left_tri_dv_vari<TriView,R1,C1,R2,C2>(A,b);
331 for (
size_type j = 0; j < res.cols(); j++)
332 for (
size_type i = 0; i < res.rows(); i++)
333 res(i,j).vi_ = baseVari->_variRefC[pos++];
337 template <
int TriView,
int R1,
int C1,
int R2,
int C2>
339 Eigen::Matrix<var,R1,C2>
341 const Eigen::Matrix<double,R2,C2> &b) {
342 Eigen::Matrix<var,R1,C2> res(b.rows(),b.cols());
350 mdivide_left_tri_vd_vari<TriView,R1,C1,R2,C2> *baseVari =
new mdivide_left_tri_vd_vari<TriView,R1,C1,R2,C2>(A,b);
353 for (
size_type j = 0; j < res.cols(); j++)
354 for (
size_type i = 0; i < res.rows(); i++)
355 res(i,j).vi_ = baseVari->_variRefC[pos++];