1 #ifndef STAN__AGRAD__REV__MATRIX__MDIVIDE_LEFT_LDLT_HPP
2 #define STAN__AGRAD__REV__MATRIX__MDIVIDE_LEFT_LDLT_HPP
13 template <
int R1,
int C1,
int R2,
int C2>
14 class mdivide_left_ldlt_alloc :
public chainable_alloc {
16 virtual ~mdivide_left_ldlt_alloc() {}
23 boost::shared_ptr< Eigen::LDLT< Eigen::Matrix<double,R1,C1> > >
_ldltP;
24 Eigen::Matrix<double,R2,C2>
C_;
37 template <
int R1,
int C1,
int R2,
int C2>
38 class mdivide_left_ldlt_vv_vari :
public vari {
44 mdivide_left_ldlt_alloc<R1,C1,R2,C2> *
_alloc;
48 const Eigen::Matrix<var,R2,C2> &B)
56 _alloc(new mdivide_left_ldlt_alloc<R1,C1,R2,C2>()),
61 for (
int j = 0; j <
N_; j++) {
62 for (
int i = 0; i <
M_; i++) {
64 _alloc->C_(i,j) = B(i,j).val();
72 for (
int j = 0; j <
N_; j++) {
73 for (
int i = 0; i <
M_; i++) {
80 virtual void chain() {
81 Eigen::Matrix<double,R1,C1> adjA(
M_,
M_);
82 Eigen::Matrix<double,R2,C2> adjB(
M_,
N_);
85 for (
int j = 0; j <
N_; j++)
86 for (
int i = 0; i <
M_; i++)
90 adjA.noalias() = -adjB *
_alloc->C_.transpose();
92 for (
int j = 0; j <
M_; j++)
93 for (
int i = 0; i <
M_; i++)
97 for (
int j = 0; j <
N_; j++)
98 for (
int i = 0; i <
M_; i++)
113 template <
int R1,
int C1,
int R2,
int C2>
114 class mdivide_left_ldlt_dv_vari :
public vari {
120 mdivide_left_ldlt_alloc<R1,C1,R2,C2> *
_alloc;
123 const Eigen::Matrix<var,R2,C2> &B)
131 _alloc(new mdivide_left_ldlt_alloc<R1,C1,R2,C2>())
138 for (
int j = 0; j <
N_; j++) {
139 for (
int i = 0; i <
M_; i++) {
141 _alloc->C_(i,j) = B(i,j).val();
146 _alloc->_ldltP = A._ldltP;
150 for (
int j = 0; j <
N_; j++) {
151 for (
int i = 0; i <
M_; i++) {
158 virtual void chain() {
159 Eigen::Matrix<double,R2,C2> adjB(M_,N_);
162 for (
int j = 0; j < adjB.cols(); j++)
163 for (
int i = 0; i < adjB.rows(); i++)
166 _alloc->_ldltP->solveInPlace(adjB);
169 for (
int j = 0; j < adjB.cols(); j++)
170 for (
int i = 0; i < adjB.rows(); i++)
185 template <
int R1,
int C1,
int R2,
int C2>
186 class mdivide_left_ldlt_vd_vari :
public vari {
191 mdivide_left_ldlt_alloc<R1,C1,R2,C2> *
_alloc;
195 const Eigen::Matrix<double,R2,C2> &B)
201 _alloc(new mdivide_left_ldlt_alloc<R1,C1,R2,C2>()),
208 for (
int j = 0; j <
N_; j++) {
209 for (
int i = 0; i <
M_; i++) {
216 virtual void chain() {
217 Eigen::Matrix<double,R1,C1> adjA(M_,M_);
218 Eigen::Matrix<double,R1,C2> adjC(M_,N_);
221 for (
int j = 0; j < adjC.cols(); j++)
222 for (
int i = 0; i < adjC.rows(); i++)
227 for (
int j = 0; j < adjA.cols(); j++)
228 for (
int i = 0; i < adjA.rows(); i++)
241 template <
int R1,
int C1,
int R2,
int C2>
242 inline Eigen::Matrix<var,R1,C2>
244 const Eigen::Matrix<var,R2,C2> &b) {
245 Eigen::Matrix<var,R1,C2> res(b.rows(),b.cols());
250 mdivide_left_ldlt_vv_vari<R1,C1,R2,C2> *baseVari =
new mdivide_left_ldlt_vv_vari<R1,C1,R2,C2>(A,b);
253 for (
int j = 0; j < res.cols(); j++)
254 for (
int i = 0; i < res.rows(); i++)
255 res(i,j).vi_ = baseVari->_variRefC[pos++];
267 template <
int R1,
int C1,
int R2,
int C2>
268 inline Eigen::Matrix<var,R1,C2>
270 const Eigen::Matrix<double,R2,C2> &b) {
271 Eigen::Matrix<var,R1,C2> res(b.rows(),b.cols());
276 mdivide_left_ldlt_vd_vari<R1,C1,R2,C2> *baseVari =
new mdivide_left_ldlt_vd_vari<R1,C1,R2,C2>(A,b);
279 for (
int j = 0; j < res.cols(); j++)
280 for (
int i = 0; i < res.rows(); i++)
281 res(i,j).vi_ = baseVari->_variRefC[pos++];
293 template <
int R1,
int C1,
int R2,
int C2>
294 inline Eigen::Matrix<var,R1,C2>
296 const Eigen::Matrix<var,R2,C2> &b) {
297 Eigen::Matrix<var,R1,C2> res(b.rows(),b.cols());
302 mdivide_left_ldlt_dv_vari<R1,C1,R2,C2> *baseVari =
new mdivide_left_ldlt_dv_vari<R1,C1,R2,C2>(A,b);
305 for (
int j = 0; j < res.cols(); j++)
306 for (
int i = 0; i < res.rows(); i++)
307 res(i,j).vi_ = baseVari->_variRefC[pos++];
Eigen::Matrix< double, R2, C2 > C_
memory::stack_alloc memalloc_
const LDLT_alloc< R1, C1 > * _alloc_ldlt
mdivide_left_ldlt_alloc< R1, C1, R2, C2 > * _alloc
bool check_multiplicable(const char *function, const T1 &y1, const char *name1, const T2 &y2, const char *name2, T_result *result)
Eigen::Matrix< fvar< T2 >, R1, C2 > mdivide_left_ldlt(const stan::math::LDLT_factor< double, R1, C1 > &A, const Eigen::Matrix< fvar< T2 >, R2, C2 > &b)
Returns the solution of the system Ax=b given an LDLT_factor of A.
size_t rows(const Eigen::Matrix< T, R, C > &m)
size_t cols(const Eigen::Matrix< T, R, C > &m)
boost::shared_ptr< Eigen::LDLT< Eigen::Matrix< double, R1, C1 > > > _ldltP
This share_ptr is used to prevent copying the LDLT factorizations for mdivide_left_ldlt(ldltA,b) when ldltA is a LDLT_factor<double>.