Spectra  1.0.1
Header-only C++ Library for Large Scale Eigenvalue Problems
SymEigsShiftSolver.h
1 // Copyright (C) 2016-2022 Yixuan Qiu <yixuan.qiu@cos.name>
2 //
3 // This Source Code Form is subject to the terms of the Mozilla
4 // Public License v. 2.0. If a copy of the MPL was not distributed
5 // with this file, You can obtain one at https://mozilla.org/MPL/2.0/.
6 
7 #ifndef SPECTRA_SYM_EIGS_SHIFT_SOLVER_H
8 #define SPECTRA_SYM_EIGS_SHIFT_SOLVER_H
9 
10 #include <Eigen/Core>
11 
12 #include "SymEigsBase.h"
13 #include "Util/SelectionRule.h"
14 #include "MatOp/DenseSymShiftSolve.h"
15 
16 namespace Spectra {
17 
148 template <typename OpType = DenseSymShiftSolve<double>>
149 class SymEigsShiftSolver : public SymEigsBase<OpType, IdentityBOp>
150 {
151 private:
152  using Scalar = typename OpType::Scalar;
153  using Index = Eigen::Index;
154  using Array = Eigen::Array<Scalar, Eigen::Dynamic, 1>;
155 
157  using Base::m_nev;
158  using Base::m_ritz_val;
159 
160  const Scalar m_sigma;
161 
162  // First transform back the Ritz values, and then sort
163  void sort_ritzpair(SortRule sort_rule) override
164  {
165  // The eigenvalues we get from the iteration is nu = 1 / (lambda - sigma)
166  // So the eigenvalues of the original problem is lambda = 1 / nu + sigma
167  m_ritz_val.head(m_nev).array() = Scalar(1) / m_ritz_val.head(m_nev).array() + m_sigma;
168  Base::sort_ritzpair(sort_rule);
169  }
170 
171 public:
190  SymEigsShiftSolver(OpType& op, Index nev, Index ncv, const Scalar& sigma) :
191  Base(op, IdentityBOp(), nev, ncv),
192  m_sigma(sigma)
193  {
194  op.set_shift(m_sigma);
195  }
196 };
197 
198 } // namespace Spectra
199 
200 #endif // SPECTRA_SYM_EIGS_SHIFT_SOLVER_H
SymEigsShiftSolver(OpType &op, Index nev, Index ncv, const Scalar &sigma)