1 #ifndef STAN__AGRAD__REV__MATRIX__MDIVIDE_LEFT_SPD_HPP
2 #define STAN__AGRAD__REV__MATRIX__MDIVIDE_LEFT_SPD_HPP
16 template <
int R1,
int C1,
int R2,
int C2>
17 class mdivide_left_spd_alloc :
public chainable_alloc {
19 virtual ~mdivide_left_spd_alloc() {}
21 Eigen::LLT< Eigen::Matrix<double,R1,C1> >
_llt;
22 Eigen::Matrix<double,R2,C2>
C_;
25 template <
int R1,
int C1,
int R2,
int C2>
26 class mdivide_left_spd_vv_vari :
public vari {
33 mdivide_left_spd_alloc<R1,C1,R2,C2> *
_alloc;
35 mdivide_left_spd_vv_vari(
const Eigen::Matrix<var,R1,C1> &A,
36 const Eigen::Matrix<var,R2,C2> &B)
46 _alloc(new mdivide_left_spd_alloc<R1,C1,R2,C2>())
51 Matrix<double,R1,C1> Ad(A.rows(),A.cols());
57 Ad(i,j) = A(i,j).val();
67 _alloc->C_(i,j) = B(i,j).val();
84 virtual void chain() {
87 Eigen::Matrix<double,R1,C1> adjA(
M_,
M_);
88 Eigen::Matrix<double,R2,C2> adjB(
M_,
N_);
95 _alloc->_llt.solveInPlace(adjB);
96 adjA.noalias() = -adjB *
_alloc->C_.transpose();
110 template <
int R1,
int C1,
int R2,
int C2>
111 class mdivide_left_spd_dv_vari :
public vari {
117 mdivide_left_spd_alloc<R1,C1,R2,C2> *
_alloc;
119 mdivide_left_spd_dv_vari(
const Eigen::Matrix<double,R1,C1> &A,
120 const Eigen::Matrix<var,R2,C2> &B)
128 _alloc(new mdivide_left_spd_alloc<R1,C1,R2,C2>())
138 _alloc->C_(i,j) = B(i,j).val();
155 virtual void chain() {
158 Eigen::Matrix<double,R2,C2> adjB(M_,N_);
161 for (
size_type j = 0; j < adjB.cols(); j++)
162 for (
size_type i = 0; i < adjB.rows(); i++)
165 _alloc->_llt.solveInPlace(adjB);
168 for (
size_type j = 0; j < adjB.cols(); j++)
169 for (
size_type i = 0; i < adjB.rows(); i++)
174 template <
int R1,
int C1,
int R2,
int C2>
175 class mdivide_left_spd_vd_vari :
public vari {
181 mdivide_left_spd_alloc<R1,C1,R2,C2> *
_alloc;
183 mdivide_left_spd_vd_vari(
const Eigen::Matrix<var,R1,C1> &A,
184 const Eigen::Matrix<double,R2,C2> &B)
192 _alloc(new mdivide_left_spd_alloc<R1,C1,R2,C2>())
197 Matrix<double,R1,C1> Ad(A.rows(),A.cols());
203 Ad(i,j) = A(i,j).val();
220 virtual void chain() {
223 Eigen::Matrix<double,R1,C1> adjA(M_,M_);
224 Eigen::Matrix<double,R1,C2> adjC(M_,N_);
227 for (
size_type j = 0; j < adjC.cols(); j++)
228 for (
size_type i = 0; i < adjC.rows(); i++)
231 adjA = -
_alloc->_llt.solve(adjC*
_alloc->C_.transpose());
234 for (
size_type j = 0; j < adjA.cols(); j++)
235 for (
size_type i = 0; i < adjA.rows(); i++)
241 template <
int R1,
int C1,
int R2,
int C2>
243 Eigen::Matrix<var,R1,C2>
245 const Eigen::Matrix<var,R2,C2> &b) {
246 Eigen::Matrix<var,R1,C2> res(b.rows(),b.cols());
255 mdivide_left_spd_vv_vari<R1,C1,R2,C2> *baseVari =
new mdivide_left_spd_vv_vari<R1,C1,R2,C2>(A,b);
258 for (
size_type j = 0; j < res.cols(); j++)
259 for (
size_type i = 0; i < res.rows(); i++)
260 res(i,j).vi_ = baseVari->_variRefC[pos++];
265 template <
int R1,
int C1,
int R2,
int C2>
267 Eigen::Matrix<var,R1,C2>
269 const Eigen::Matrix<double,R2,C2> &b) {
270 Eigen::Matrix<var,R1,C2> res(b.rows(),b.cols());
279 mdivide_left_spd_vd_vari<R1,C1,R2,C2> *baseVari =
new mdivide_left_spd_vd_vari<R1,C1,R2,C2>(A,b);
282 for (
size_type j = 0; j < res.cols(); j++)
283 for (
size_type i = 0; i < res.rows(); i++)
284 res(i,j).vi_ = baseVari->_variRefC[pos++];
289 template <
int R1,
int C1,
int R2,
int C2>
291 Eigen::Matrix<var,R1,C2>
293 const Eigen::Matrix<var,R2,C2> &b) {
294 Eigen::Matrix<var,R1,C2> res(b.rows(),b.cols());
303 mdivide_left_spd_dv_vari<R1,C1,R2,C2> *baseVari =
new mdivide_left_spd_dv_vari<R1,C1,R2,C2>(A,b);
306 for (
size_type j = 0; j < res.cols(); j++)
307 for (
size_type i = 0; i < res.rows(); i++)
308 res(i,j).vi_ = baseVari->_variRefC[pos++];
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< double, Eigen::Dynamic, Eigen::Dynamic >::Index size_type
size_t rows(const Eigen::Matrix< T, R, C > &m)
Eigen::LLT< Eigen::Matrix< double, R1, C1 > > _llt
size_t cols(const Eigen::Matrix< T, R, C > &m)
mdivide_left_spd_alloc< R1, C1, R2, C2 > * _alloc
Eigen::Matrix< var, R1, C2 > mdivide_left_spd(const Eigen::Matrix< var, R1, C1 > &A, const Eigen::Matrix< var, R2, C2 > &b)
Eigen::Matrix< double, R2, C2 > C_
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.