bool pdsolve(const SQMATTP& M,const VCTTP& b,VCTTP& res,double* logDet) { /* static */ LDLT<SQMATTP> MSr; MSr = M.ldlt(); // Maybe replace this by a better rank-reaveling criteron if (MSr.info()!=Success) return false; res = MSr.solve(b); if (logDet) { Diagonal<const SQMATTP> MSrdiag(MSr.vectorD()); *logDet = log(MSrdiag(0)); for (int i=1;i<M.rows();i++) *logDet += log(MSrdiag(i)); } return true; }
bool pdsolve(const SQMATTP& M,SQMATTP& MInv,double* logDet) { /* static */ LDLT<SQMATTP> MSr; /* static */ SQMATTP Ip; /* static */ int Ipdim(0); int p(M.rows()); if (Ipdim!=p) SetIdentity(Ip,p,&Ipdim); MSr = M.ldlt(); // Maybe replace this by a better rank-reaveling criteron if (MSr.info()!=Success) return false; MInv = MSr.solve(Ip); if (logDet) { Diagonal<const SQMATTP> MSrdiag(MSr.vectorD()); *logDet = log(MSrdiag(0)); for (int i=1;i<M.rows();i++) *logDet += log(MSrdiag(i)); } return true; }
inline bool check_pos_definite(const char* function, const char* name, const Eigen::Matrix<T_y, Dynamic, Dynamic>& y) { check_symmetric(function, name, y); check_positive_size(function, name, "rows", y.rows()); if (y.rows() == 1 && !(y(0, 0) > CONSTRAINT_TOLERANCE)) domain_error(function, name, y, "is not positive definite: "); using Eigen::LDLT; using Eigen::Matrix; using Eigen::Dynamic; LDLT< Matrix<double, Dynamic, Dynamic> > cholesky = value_of_rec(y).ldlt(); if (cholesky.info() != Eigen::Success || !cholesky.isPositive() || (cholesky.vectorD().array() <= CONSTRAINT_TOLERANCE).any()) domain_error(function, name, y, "is not positive definite:\n"); check_not_nan(function, name, y); return true; }