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());
307 mdivide_left_tri_vv_vari<TriView,R1,C1,R2,C2> *baseVari =
new mdivide_left_tri_vv_vari<TriView,R1,C1,R2,C2>(A,b);
310 for (
size_type j = 0; j < res.cols(); j++)
311 for (
size_type i = 0; i < res.rows(); i++)
312 res(i,j).vi_ = baseVari->_variRefC[pos++];
316 template <
int TriView,
int R1,
int C1,
int R2,
int C2>
318 Eigen::Matrix<var,R1,C2>
320 const Eigen::Matrix<var,R2,C2> &b) {
321 Eigen::Matrix<var,R1,C2> res(b.rows(),b.cols());
330 mdivide_left_tri_dv_vari<TriView,R1,C1,R2,C2> *baseVari =
new mdivide_left_tri_dv_vari<TriView,R1,C1,R2,C2>(A,b);
333 for (
size_type j = 0; j < res.cols(); j++)
334 for (
size_type i = 0; i < res.rows(); i++)
335 res(i,j).vi_ = baseVari->_variRefC[pos++];
339 template <
int TriView,
int R1,
int C1,
int R2,
int C2>
341 Eigen::Matrix<var,R1,C2>
343 const Eigen::Matrix<double,R2,C2> &b) {
344 Eigen::Matrix<var,R1,C2> res(b.rows(),b.cols());
353 mdivide_left_tri_vd_vari<TriView,R1,C1,R2,C2> *baseVari =
new mdivide_left_tri_vd_vari<TriView,R1,C1,R2,C2>(A,b);
356 for (
size_type j = 0; j < res.cols(); j++)
357 for (
size_type i = 0; i < res.rows(); i++)
358 res(i,j).vi_ = baseVari->_variRefC[pos++];
Eigen::Matrix< var, R1, C2 > mdivide_left_tri(const Eigen::Matrix< var, R1, C1 > &A, const Eigen::Matrix< var, R2, C2 > &b)
memory::stack_alloc memalloc_
bool check_multiplicable(const char *function, const T1 &y1, const char *name1, const T2 &y2, const char *name2, T_result *result)
Eigen::Matrix< T, C, R > transpose(const Eigen::Matrix< T, R, C > &m)
Eigen::Matrix< double, Eigen::Dynamic, Eigen::Dynamic >::Index size_type
size_t rows(const Eigen::Matrix< T, R, C > &m)
size_t cols(const Eigen::Matrix< T, R, C > &m)
bool check_square(const char *function, const Eigen::Matrix< T_y, Eigen::Dynamic, Eigen::Dynamic > &y, const char *name, T_result *result)
Return true if the specified matrix is square.