// This file is part of libigl, a simple c++ geometry processing library. // // Copyright (C) 2016 Alec Jacobson // // This Source Code Form is subject to the terms of the Mozilla Public License // v. 2.0. If a copy of the MPL was not distributed with this file, You can // obtain one at http://mozilla.org/MPL/2.0/. #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; //std::cout<<"start"<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.leftCols(i).transpose()*B*x).array().abs()<=1e-7).all() ) { //cout<<"Found "<, Eigen::Matrix >(Eigen::SparseMatrix const&, Eigen::SparseMatrix const&, const size_t, igl::EigsType, Eigen::PlainObjectBase >&, Eigen::PlainObjectBase >&); #ifdef WIN32 template bool igl::eigs, Eigen::Matrix >(Eigen::SparseMatrix const &,Eigen::SparseMatrix const &, const size_t, igl::EigsType, Eigen::PlainObjectBase< Eigen::Matrix > &, Eigen::PlainObjectBase > &); #endif #endif