#include "eigs.h" #include "cotmatrix.h" #include "sort.h" #include "slice.h" #include "massmatrix.h" #include template < typename Atype, typename Btype, typename DerivedU, typename DerivedS> IGL_INLINE bool igl::eigs( const Eigen::SparseMatrix & A, const Eigen::SparseMatrix & iB, const size_t k, const EigsType type, Eigen::PlainObjectBase & sU, Eigen::PlainObjectBase & sS) { using namespace Eigen; using namespace std; const size_t n = A.rows(); assert(A.cols() == n && "A should be square."); assert(iB.rows() == n && "B should be match A's dims."); assert(iB.cols() == n && "B should be square."); assert(type == EIGS_TYPE_SM && "Only low frequencies are supported"); DerivedU U(n,k); DerivedS S(k,1); typedef Atype Scalar; typedef Eigen::Matrix VectorXS; // Rescale B for better numerics const Scalar rescale = std::abs(iB.diagonal().maxCoeff()); const Eigen::SparseMatrix B = iB/rescale; Scalar tol = 1e-4; Scalar conv = 1e-14; int max_iter = 100; int i = 0; while(true) { // Random initial guess VectorXS y = VectorXS::Random(n,1); Scalar eff_sigma = 0; if(i>0) { eff_sigma = 1e-8+std::abs(S(i-1)); } // whether to use rayleigh quotient method bool ray = false; Scalar err = std::numeric_limits::infinity(); int iter; Scalar sigma = std::numeric_limits::infinity(); VectorXS x; for(iter = 0;iter0 && !ray) { // project-out existing modes for(int j = 0;j0?1.:-1.; Scalar err_prev = err; err = (A*x-sigma*B*x).array().abs().maxCoeff(); if(err > solver; const SparseMatrix C = A-eff_sigma*B+tikhonov*B; //mw.save(C,"C"); //mw.save(eff_sigma,"eff_sigma"); //mw.save(tikhonov,"tikhonov"); solver.compute(C); switch(solver.info()) { case Eigen::Success: break; case Eigen::NumericalIssue: cerr<<"Error: Numerical issue."<1e-14) { U.col(i) = x; S(i) = sigma; i++; if(i == k) { break; } }else { // restart with new random guess. cout<<"RESTART!"<, Eigen::Matrix >(Eigen::SparseMatrix const&, Eigen::SparseMatrix const&, unsigned long, igl::EigsType, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); #ifdef WIN32 template bool igl::eigs, Eigen::Matrix >(Eigen::SparseMatrix const &,Eigen::SparseMatrix const &,unsigned long long, igl::EigsType, Eigen::PlainObjectBase< Eigen::Matrix > &, Eigen::PlainObjectBase > &); #endif #endif