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; }
int run(const log4cxx::LoggerPtr &logger, KernelEVD<Scalar> &builder) const { KQP_SCALAR_TYPEDEFS(Scalar); KQP_LOG_INFO_F(logger, "Kernel EVD with dense vectors and builder \"%s\" (pre-images = %d, linear combination = %d)", %KQP_DEMANGLE(builder) %max_preimages %max_lc); ScalarMatrix matrix(n,n); matrix.setConstant(0); // Construction for(int i = 0; i < nb_add; i++) { Scalar alpha = Eigen::internal::abs(Eigen::internal::random_impl<Scalar>::run()) + 1e-3; int k = (int)std::abs(Eigen::internal::random_impl<double>::run() * (double)(max_preimages-min_preimages)) + min_preimages; int p = (int)std::abs(Eigen::internal::random_impl<double>::run() * (double)(max_lc-min_lc)) + min_lc; KQP_LOG_INFO(logger, boost::format("Pre-images (%dx%d) and linear combination (%dx%d)") % n % k % k % p); // Generate a number of pre-images ScalarMatrix m = ScalarMatrix::Random(n, k); // Generate the linear combination matrix ScalarMatrix mA = ScalarMatrix::Random(k, p); matrix.template selfadjointView<Eigen::Lower>().rankUpdate(m * mA, alpha); builder.add(alpha, FMatrixPtr(new Dense<Scalar>(m)), mA); } // Computing via EVD KQP_LOG_INFO(logger, "Computing an LDLT decomposition"); typedef Eigen::LDLT<ScalarMatrix> LDLT; LDLT ldlt = matrix.template selfadjointView<Eigen::Lower>().ldlt(); ScalarMatrix mL = ldlt.matrixL(); mL = ldlt.transpositionsP().transpose() * mL; FMatrixPtr mU(Dense<Scalar>::create(mL)); Eigen::Matrix<Scalar,Dynamic,1> mU_d = ldlt.vectorD(); // Comparing the results KQP_LOG_INFO(logger, "Retrieving the decomposition"); auto kevd = builder.getDecomposition(); ScalarAltMatrix mUY = Eigen::Identity<Scalar>(mL.rows(), mL.rows()); KQP_LOG_DEBUG(logger, "=== Decomposition ==="); // KQP_LOG_DEBUG(logger, "X = " << kevd.mX); KQP_LOG_DEBUG(logger, "Y = " << kevd.mY); KQP_LOG_DEBUG(logger, "D = " << kevd.mD); // Computing the difference between operators || U1 - U2 ||^2 KQP_LOG_INFO(logger, "Comparing the decompositions"); double error = KernelOperators<Scalar>::difference(kevd.fs, kevd.mX, kevd.mY, kevd.mD, mU, mUY, mU_d); KQP_LOG_INFO_F(logger, "Squared error is %e", %error); return error < tolerance ? 0 : 1; }