4 #include <boost/property_tree/ptree.hpp>
15 int verbosityIn) : numEigs(numEigsIn),
16 eigRelTol(eigRelTolIn),
17 eigAbsTol(eigAbsTolIn),
18 expectedRank((expectedRankIn<0)?numEigsIn:expectedRankIn),
19 samplingFactor((samplingFactorIn<0)?(0.1*numEigsIn):samplingFactorIn),
20 blockSize(blockSizeIn),
21 verbosity(verbosityIn)
27 opts.
get(
"RelativeTolerance",0.0),
28 opts.
get(
"AbsoluteTolerance",0.0),
29 opts.
get(
"ExpectedRank", -1),
30 opts.
get(
"OversamplingFactor", -1),
31 opts.
get(
"BlockSize",10),
32 opts.
get(
"Verbosity",0))
37 std::shared_ptr<LinearOperator> B,
38 std::shared_ptr<LinearOperator> Binv)
48 assert((
B!=
nullptr)==(Binv!=
nullptr));
50 const int dim =
A->cols();
52 Eigen::MatrixXd randMat;
54 bool hasConverged =
false;
59 Y = Binv->Apply(
A->Apply(randMat));
61 Y =
A->Apply(randMat);
70 Eigen::MatrixXd T = Q.transpose()*
A->Apply(Q);
72 Eigen::SelfAdjointEigenSolver<Eigen::MatrixXd> eigSolver(T);
73 eigVals = eigSolver.eigenvalues();
85 std::cout <<
"Converged: Minimum eigenvalue (" << smallestVal <<
") satisfies absolute tolerance (" <<
eigAbsTol <<
")." << std::endl;
93 std::cout <<
"Converged: Minimum eigenvalue (" << smallestVal <<
") satisfies relative tolerance (" <<
eigRelTol*largestVal <<
")." << std::endl;
99 if(Q.cols()<Y.cols()){
101 std::cout <<
"Converged: All nonzero eigenvalues have been found (likely) or samples are degenerate (unlikely)." << std::endl;
109 std::cout <<
"Converged: Reached maximum number of eigenvalues." << std::endl;
115 std::cout <<
"After iteration " << it <<
", " <<
eigVals.size() <<
" eigenvalues in [" << smallestVal <<
"," << largestVal <<
"]" << std::endl;
116 std::cout <<
" Y.shape = " << Y.rows() <<
" x " << Y.cols() << std::endl;
122 randMat.conservativeResize(Eigen::NoChange, randMat.cols()+
blockSize);
123 Y.conservativeResize(Eigen::NoChange, Y.cols()+
blockSize);
136 eigVecs = Q*eigSolver.eigenvectors();
143 double largestVal =
eigVals(0);
144 unsigned int numKeep = 0;
161 std::shared_ptr<LinearOperator>
const& B)
const
164 auto qr = Y.colPivHouseholderQr();
165 unsigned int rank = qr.rank();
167 Eigen::MatrixXd Z = qr.householderQ().setLength(qr.nonzeroPivots()) * Eigen::MatrixXd::Identity(Y.rows(),rank);
168 Eigen::MatrixXd Ry = qr.matrixR().topLeftCorner(rank, rank).template triangularView<Eigen::Upper>();
171 return std::make_pair(Z,Ry);
174 auto chol = (Z.transpose()*
B->Apply(Z)).llt();
176 Eigen::MatrixXd Q = chol.matrixL().solve(Z.transpose()).transpose();
177 Eigen::MatrixXd R = chol.matrixL()*Ry;
179 return std::make_pair(Q,R);
static std::vector< std::pair< int, int > > GetSortSwaps(Eigen::Ref< const Eigen::VectorXd > const &residNorms, std::vector< bool > const &isActive)
std::shared_ptr< LinearOperator > A
static void SortVec(std::vector< std::pair< int, int >> const &swapInds, Eigen::Ref< Eigen::VectorXd > matrix)
static void SortCols(std::vector< std::pair< int, int >> const &swapInds, Eigen::Ref< Eigen::MatrixXd > matrix)
std::shared_ptr< LinearOperator > B
Two-pass stochastic algorithm for computing generalized eigenvalues from matrix products.
StochasticEigenSolver(int numEigsIn, double eigRelTolIn=0.0, double eigAbsTolIn=0.0, int expectedRankIn=-1, int samplingFactorIn=-1, int blockSize=10, int verbosityIn=0)
std::pair< Eigen::MatrixXd, Eigen::MatrixXd > CholeskyQR(Eigen::MatrixXd const &Y, std::shared_ptr< LinearOperator > const &B) const
virtual StochasticEigenSolver & compute(std::shared_ptr< LinearOperator > const &A, std::shared_ptr< LinearOperator > B=nullptr, std::shared_ptr< LinearOperator > Binv=nullptr)
auto get(const nlohmann::detail::iteration_proxy_value< IteratorType > &i) -> decltype(i.key())