inline bool check_pos_definite(const char* function, const char* name, const Eigen::LLT<Derived>& cholesky) { if (cholesky.info() != Eigen::Success || !(cholesky.matrixLLT().diagonal().array() > 0.0).all()) domain_error(function, "Cholesky decomposition of", " failed", name); return true; }
/* ************************************************************************* */ bool choleskyPartial(Matrix& ABC, size_t nFrontal) { const bool debug = ISDEBUG("choleskyPartial"); assert(ABC.rows() == ABC.cols()); assert(ABC.rows() >= 0 && nFrontal <= size_t(ABC.rows())); const size_t n = ABC.rows(); // Compute Cholesky factorization of A, overwrites A. tic(1, "lld"); Eigen::LLT<Matrix, Eigen::Upper> llt = ABC.block(0,0,nFrontal,nFrontal).selfadjointView<Eigen::Upper>().llt(); ABC.block(0,0,nFrontal,nFrontal).triangularView<Eigen::Upper>() = llt.matrixU(); toc(1, "lld"); if(debug) cout << "R:\n" << Eigen::MatrixXd(ABC.topLeftCorner(nFrontal,nFrontal).triangularView<Eigen::Upper>()) << endl; // Compute S = inv(R') * B tic(2, "compute S"); if(n - nFrontal > 0) { ABC.topLeftCorner(nFrontal,nFrontal).triangularView<Eigen::Upper>().transpose().solveInPlace( ABC.topRightCorner(nFrontal, n-nFrontal)); } if(debug) cout << "S:\n" << ABC.topRightCorner(nFrontal, n-nFrontal) << endl; toc(2, "compute S"); // Compute L = C - S' * S tic(3, "compute L"); if(debug) cout << "C:\n" << Eigen::MatrixXd(ABC.bottomRightCorner(n-nFrontal,n-nFrontal).selfadjointView<Eigen::Upper>()) << endl; if(n - nFrontal > 0) ABC.bottomRightCorner(n-nFrontal,n-nFrontal).selfadjointView<Eigen::Upper>().rankUpdate( ABC.topRightCorner(nFrontal, n-nFrontal).transpose(), -1.0); if(debug) cout << "L:\n" << Eigen::MatrixXd(ABC.bottomRightCorner(n-nFrontal,n-nFrontal).selfadjointView<Eigen::Upper>()) << endl; toc(3, "compute L"); // Check last diagonal element - Eigen does not check it bool ok; if(llt.info() == Eigen::Success) { if(nFrontal >= 2) { int exp2, exp1; (void)frexp(ABC(nFrontal-2, nFrontal-2), &exp2); (void)frexp(ABC(nFrontal-1, nFrontal-1), &exp1); ok = (exp2 - exp1 < underconstrainedExponentDifference); } else if(nFrontal == 1) { int exp1; (void)frexp(ABC(0,0), &exp1); ok = (exp1 > -underconstrainedExponentDifference); } else { ok = true; } } else { ok = false; } return ok; }
void ctms_decompositions() { const int maxSize = 16; const int size = 12; typedef Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic, 0, maxSize, maxSize> Matrix; typedef Eigen::Matrix<Scalar, Eigen::Dynamic, 1, 0, maxSize, 1> Vector; typedef Eigen::Matrix<std::complex<Scalar>, Eigen::Dynamic, Eigen::Dynamic, 0, maxSize, maxSize> ComplexMatrix; const Matrix A(Matrix::Random(size, size)); const ComplexMatrix complexA(ComplexMatrix::Random(size, size)); const Matrix saA = A.adjoint() * A; // Cholesky module Eigen::LLT<Matrix> LLT; LLT.compute(A); Eigen::LDLT<Matrix> LDLT; LDLT.compute(A); // Eigenvalues module Eigen::HessenbergDecomposition<ComplexMatrix> hessDecomp; hessDecomp.compute(complexA); Eigen::ComplexSchur<ComplexMatrix> cSchur(size); cSchur.compute(complexA); Eigen::ComplexEigenSolver<ComplexMatrix> cEigSolver; cEigSolver.compute(complexA); Eigen::EigenSolver<Matrix> eigSolver; eigSolver.compute(A); Eigen::SelfAdjointEigenSolver<Matrix> saEigSolver(size); saEigSolver.compute(saA); Eigen::Tridiagonalization<Matrix> tridiag; tridiag.compute(saA); // LU module Eigen::PartialPivLU<Matrix> ppLU; ppLU.compute(A); Eigen::FullPivLU<Matrix> fpLU; fpLU.compute(A); // QR module Eigen::HouseholderQR<Matrix> hQR; hQR.compute(A); Eigen::ColPivHouseholderQR<Matrix> cpQR; cpQR.compute(A); Eigen::FullPivHouseholderQR<Matrix> fpQR; fpQR.compute(A); // SVD module Eigen::JacobiSVD<Matrix> jSVD; jSVD.compute(A, ComputeFullU | ComputeFullV); }
pca& pca::compute(mat samples, real eps, mat metric) { mean_ = samples.colwise().mean().transpose(); samples.rowwise() -= mean().transpose(); Eigen::LLT< mat > llt; if( !metric.empty() ) { assert( metric.rows() == samples.cols() ); assert( metric.cols() == metric.rows() ); llt.compute( metric ); samples = samples * llt.matrixL(); } math::svd svd; svd.compute(samples, eps, Eigen::ComputeThinV ); if( !metric.empty() ) { basis_ = llt.matrixU().solve( svd.v() ); } else { basis_ = svd.v(); } // surprisingly, this one works for both cases (coords = samples * // U^{-T}) where U is the eigen basis coords_ = samples * svd.v(); dev_ = svd.singular().cwiseAbs(); rank_ = svd.rank(); // print_vec( cumul() ); return *this; }
inline void check_pos_definite(const char* function, const char* name, const Eigen::LLT<Derived>& cholesky) { if (cholesky.info() != Eigen::Success || !(cholesky.matrixLLT().diagonal().array() > 0.0).all()) domain_error(function, "Matrix", " is not positive definite", name); }