7 #ifndef SPECTRA_JD_SYM_EIGS_BASE_H
8 #define SPECTRA_JD_SYM_EIGS_BASE_H
17 #include "Util/SelectionRule.h"
18 #include "Util/CompInfo.h"
19 #include "LinAlg/SearchSpace.h"
20 #include "LinAlg/RitzPairs.h"
33 template <
typename Derived,
typename OpType>
37 using Index = Eigen::Index;
38 using Scalar =
typename OpType::Scalar;
39 using Matrix = Eigen::Matrix<Scalar, Eigen::Dynamic, Eigen::Dynamic>;
40 using Vector = Eigen::Matrix<Scalar, Eigen::Dynamic, 1>;
42 const OpType& m_matrix_operator;
45 const Index m_number_eigenvalues;
46 Index m_max_search_space_size;
47 Index m_initial_search_space_size;
48 Index m_correction_size;
49 RitzPairs<Scalar> m_ritz_pairs;
50 SearchSpace<Scalar> m_search_space;
55 void check_argument()
const
57 if (m_number_eigenvalues < 1 || m_number_eigenvalues > m_matrix_operator.cols() - 1)
58 throw std::invalid_argument(
"nev must satisfy 1 <= nev <= n - 1, n is the size of matrix");
64 if (m_matrix_operator.cols() < m_max_search_space_size)
66 m_max_search_space_size = m_matrix_operator.cols();
68 if (m_matrix_operator.cols() < m_initial_search_space_size + m_correction_size)
70 m_initial_search_space_size = m_matrix_operator.cols() / 3;
71 m_correction_size = m_matrix_operator.cols() / 3;
76 JDSymEigsBase(OpType& op, Index nev, Index nvec_init, Index nvec_max) :
77 m_matrix_operator(op),
78 m_number_eigenvalues(nev),
79 m_max_search_space_size(nvec_max < op.rows() ? nvec_max : 10 * m_number_eigenvalues),
80 m_initial_search_space_size(nvec_init < op.rows() ? nvec_init : 2 * m_number_eigenvalues),
81 m_correction_size(m_number_eigenvalues)
95 m_max_search_space_size = max_search_space_size;
102 m_correction_size = correction_size;
110 m_initial_search_space_size = initial_search_space_size;
129 Vector eigenvalues()
const {
return m_ritz_pairs.ritz_values().head(m_number_eigenvalues); }
131 Matrix eigenvectors()
const {
return m_ritz_pairs.ritz_vectors().leftCols(m_number_eigenvalues); }
134 Scalar tol = 100 * Eigen::NumTraits<Scalar>::dummy_precision())
136 Derived& derived =
static_cast<Derived&
>(*this);
137 Matrix intial_space = derived.setup_initial_search_space(selection);
138 return compute_with_guess(intial_space, selection, maxit, tol);
141 Index compute_with_guess(
const Eigen::Ref<const Matrix>& initial_space,
144 Scalar tol = 100 * Eigen::NumTraits<Scalar>::dummy_precision())
147 m_search_space.initialize_search_space(initial_space);
149 for (niter_ = 0; niter_ < maxit; niter_++)
151 bool do_restart = (m_search_space.size() > m_max_search_space_size);
155 m_search_space.restart(m_ritz_pairs, m_initial_search_space_size);
158 m_search_space.update_operator_basis_product(m_matrix_operator);
160 Eigen::ComputationInfo small_problem_info = m_ritz_pairs.compute_eigen_pairs(m_search_space);
161 if (small_problem_info != Eigen::ComputationInfo::Success)
166 m_ritz_pairs.sort(selection);
168 bool converged = m_ritz_pairs.check_convergence(tol, m_number_eigenvalues);
174 else if (niter_ == maxit - 1)
179 Derived& derived =
static_cast<Derived&
>(*this);
180 Matrix corr_vect = derived.calculate_correction_vector();
182 m_search_space.extend_basis(corr_vect);
184 return (m_ritz_pairs.converged_eigenvalues()).
template cast<Index>().head(m_number_eigenvalues).sum();
void set_correction_size(Index correction_size)
Index num_iterations() const
void set_initial_search_space_size(Index initial_search_space_size)
void set_max_search_space_size(Index max_search_space_size)
@ Successful
Computation was successful.