12#include <Spectra/MatOp/SparseCholesky.h>
13#include <Spectra/MatOp/SparseGenMatProd.h>
14#include <Spectra/SymEigsSolver.h>
15#include <Spectra/SymGEigsSolver.h>
19#include <Eigen/SparseCore>
31template <EigenValueSolverType SolverType, Concepts::DenseOrSparseEigenMatrix MT>
47template <Concepts::DenseOrSparseEigenMatrix MT>
55 std::conditional_t<isDense, Spectra::DenseSymMatProd<ScalarType>, Spectra::SparseSymMatProd<ScalarType>>;
57 std::conditional_t<isDense, Spectra::DenseCholesky<ScalarType>, Spectra::SparseCholesky<ScalarType>>;
59 using SolverType = Spectra::SymGEigsSolver<ProductType, CholeskyType, Spectra::GEigsMode::Cholesky>;
69 template <
typename MATA,
typename MATB>
73 nevsPartition_(
static_cast<Eigen::Index
>(std::ceil(
static_cast<double>(nev_) / 2)),
74 static_cast<Eigen::Index
>(nev_ - std::ceil(
static_cast<double>(nev_) / 2))),
75 aOP_(std::forward<MATA>(A)),
76 bOP_(std::forward<MATB>(B)),
77 solverSmallest_(aOP_, bOP_, nevsPartition_.first, std::min(nevsPartition_.second * 2, nev_)),
78 solverGreatest_(aOP_, bOP_, nevsPartition_.second, nevsPartition_.second * 2) {
79 if ((A.cols() != B.cols()) or (A.rows() != B.rows()) or (A.cols() != A.rows()))
80 DUNE_THROW(Dune::InvalidStateException,
81 "GeneralizedSymEigenSolver: The passed matrices should have the same size");
82 eigenvalues_.resize(nev_);
83 eigenvectors_.resize(A.rows(), nev_);
84 assert(nevsPartition_.first + nevsPartition_.second == nev_);
95 template <Concepts::FlatAssembler AssemblerA, Concepts::FlatAssembler AssemblerB>
108 solverSmallest_.init();
109 solverSmallest_.compute(Spectra::SortRule::SmallestAlge, maxit, tolerance, Spectra::SortRule::SmallestAlge);
111 solverGreatest_.init();
112 solverGreatest_.compute(Spectra::SortRule::LargestAlge, maxit, tolerance, Spectra::SortRule::SmallestAlge);
114 computed_ = solverSmallest_.info() == Spectra::CompInfo::Successful and
115 solverGreatest_.info() == Spectra::CompInfo::Successful;
119 eigenvalues_.head(nevsPartition_.first) = solverSmallest_.eigenvalues();
120 eigenvectors_.leftCols(nevsPartition_.first) = solverSmallest_.eigenvectors();
122 eigenvalues_.tail(nevsPartition_.second) = solverGreatest_.eigenvalues();
123 eigenvectors_.rightCols(nevsPartition_.second) = solverGreatest_.eigenvectors();
145 return eigenvectors_;
149 Eigen::Index
nev()
const {
return nev_; }
153 std::pair<Eigen::Index, Eigen::Index> nevsPartition_;
156 SolverType solverSmallest_;
157 SolverType solverGreatest_;
159 Eigen::VectorXd eigenvalues_;
160 Eigen::MatrixXd eigenvectors_;
164 void assertCompute()
const {
166 DUNE_THROW(Dune::InvalidStateException,
"Eigenvalues and -vectors not yet computed, please call compute() first");
177template <Concepts::EigenMatrix MT>
182 using SolverType = Eigen::GeneralizedSelfAdjointEigenSolver<MatrixType>;
192 template <
typename MATA,
typename MATB>
195 : matA_(std::forward<MATA>(A)),
196 matB_(std::forward<MATB>(B)),
198 if ((A.cols() != B.cols()) or (A.rows() != B.rows()) or (A.cols() != A.rows()))
199 DUNE_THROW(Dune::InvalidStateException,
200 "GeneralizedSymEigenSolver: The passed matrices should have the same size");
211 template <Concepts::FlatAssembler AssemblerA, Concepts::FlatAssembler AssemblerB>
223 bool compute(
int options = Eigen::ComputeEigenvectors) {
224 solver_.compute(matA_, matB_, options);
236 return solver_.eigenvalues();
246 return solver_.eigenvectors();
250 Eigen::Index
nev()
const {
return matA_.rows(); }
258 void assertCompute()
const {
260 DUNE_THROW(Dune::InvalidStateException,
"Eigenvalues and -vectors not yet computed, please call compute() first");
265 void assertNev(std::optional<Eigen::Index> nev, Eigen::Index nevMax) {
266 if (nev.has_value() and nev.value() > nevMax)
267 DUNE_THROW(Dune::InvalidStateException,
"You can not ask for more eigenvalues or eigenvectors than calculated.");
279template <Concepts::DenseOrSparseEigenMatrix MT>
287 std::conditional_t<isDense, Spectra::DenseSymMatProd<ScalarType>, Spectra::SparseSymMatProd<ScalarType>>;
289 std::conditional_t<isDense, Spectra::DenseCholesky<ScalarType>, Spectra::SparseCholesky<ScalarType>>;
291 using SolverType = Spectra::SymGEigsSolver<ProductType, CholeskyType, Spectra::GEigsMode::Cholesky>;
301 template <
typename MATA,
typename MATB>
305 aOP_(std::forward<MATA>(A)),
306 bOP_(std::forward<MATB>(B)),
307 solver_(aOP_, bOP_,
nev, 2 *
nev <= A.cols() ? 2 *
nev : A.cols()) {
308 if ((A.cols() != B.cols()) or (A.rows() != B.rows()) or (A.cols() != A.rows()))
309 DUNE_THROW(Dune::InvalidStateException,
310 "PartialGeneralizedSymEigenSolver: The passed matrices should have the same size");
321 template <Concepts::FlatAssembler AssemblerA, Concepts::FlatAssembler AssemblerB>
336 bool compute(Spectra::SortRule selection = Spectra::SortRule::SmallestAlge,
337 Spectra::SortRule sortRule = Spectra::SortRule::SmallestAlge, Eigen::Index maxit = 1000,
340 solver_.compute(selection, maxit, tolerance, sortRule);
342 computed_ = solver_.info() == Spectra::CompInfo::Successful;
353 return solver_.eigenvalues();
362 auto eigenvectors(std::optional<Eigen::Index> _nev = std::nullopt)
const {
363 Impl::assertNev(_nev, nev_);
365 return solver_.eigenvectors(_nev.value_or(nev_));
368 Eigen::Index
nev()
const {
return nev_; }
378 void assertCompute()
const {
380 DUNE_THROW(Dune::InvalidStateException,
"Eigenvalues and -vectors not yet computed, please call compute() first");
385template <Concepts::FlatAssembler AssemblerA, Concepts::FlatAssembler AssemblerB>
386requires(std::same_as<typename AssemblerA::MatrixType, typename AssemblerB::MatrixType>)
387PartialGeneralizedSymEigenSolver(std::shared_ptr<AssemblerA> as1, std::shared_ptr<AssemblerB> as2,
388 Eigen::Index nev) -> PartialGeneralizedSymEigenSolver<typename AssemblerA::MatrixType>;
390template <
typename MATA,
typename MATB>
391requires(Concepts::DenseOrSparseEigenMatrix<std::remove_cvref_t<MATA>> &&
392 std::same_as<std::remove_cvref_t<MATA>, std::remove_cvref_t<MATB>>)
393PartialGeneralizedSymEigenSolver(MATA&&, MATB&&,
394 Eigen::Index) -> PartialGeneralizedSymEigenSolver<std::remove_cvref_t<MATA>>;
Implementation of the make enum macro.
#define MAKE_ENUM(type,...)
Macro to create an enumeration with a string conversion function.The macro creates an enum class with...
Definition: makeenum.hh:40
Definition: assemblermanipulatorbuildingblocks.hh:22
EigenValueSolverType
A strongly typed enum class representing the type of solver to use for the eigenvalue problem.
Definition: generalizedeigensolver.hh:29
Definition: truncatedconjugategradient.hh:24
Definition: generalizedeigensolver.hh:33
auto & eigenvectors() const
Returns the eigenvectors of the generalized eigenvalue problem.
Definition: generalizedeigensolver.hh:143
std::conditional_t< isDense, Spectra::DenseSymMatProd< ScalarType >, Spectra::SparseSymMatProd< ScalarType > > ProductType
Definition: generalizedeigensolver.hh:55
MT MatrixType
Definition: generalizedeigensolver.hh:53
Eigen::Index nev() const
Returns the number of eigenvalues of the problem.
Definition: generalizedeigensolver.hh:149
std::conditional_t< isDense, Spectra::DenseCholesky< ScalarType >, Spectra::SparseCholesky< ScalarType > > CholeskyType
Definition: generalizedeigensolver.hh:57
typename MT::Scalar ScalarType
Definition: generalizedeigensolver.hh:50
bool compute(Eigen::Index maxit=1000, ScalarType tolerance=1e-10)
Starts the computation of the eigenvalue solver.
Definition: generalizedeigensolver.hh:107
GeneralizedSymEigenSolver(MATA &&A, MATB &&B)
Construct a new GeneralizedSymEigenSolver object.
Definition: generalizedeigensolver.hh:71
Spectra::SymGEigsSolver< ProductType, CholeskyType, Spectra::GEigsMode::Cholesky > SolverType
Definition: generalizedeigensolver.hh:59
GeneralizedSymEigenSolver(std::shared_ptr< AssemblerA > assemblerA, const std::shared_ptr< AssemblerB > &assemblerB)
Construct a new GeneralSymEigenSolver object.
Definition: generalizedeigensolver.hh:96
auto & eigenvalues() const
Returns the eigenvalues of the generalized eigenvalue problem.
Definition: generalizedeigensolver.hh:133
GeneralizedSymEigenSolver(MATA &&A, MATB &&B)
Construct a new GeneralizedSymEigenSolver object.
Definition: generalizedeigensolver.hh:194
Eigen::Index nev() const
Returns the number of eigenvalues of the problem.
Definition: generalizedeigensolver.hh:250
MT MatrixType
Definition: generalizedeigensolver.hh:181
bool compute(int options=Eigen::ComputeEigenvectors)
Starts the computation of the eigenvalue solver.
Definition: generalizedeigensolver.hh:223
GeneralizedSymEigenSolver(std::shared_ptr< AssemblerA > assemblerA, std::shared_ptr< AssemblerB > assemblerB)
Construct a new GeneralSymEigenSolver object.
Definition: generalizedeigensolver.hh:212
auto & eigenvectors() const
Returns the eigenvectors of the generalized eigenvalue problem.
Definition: generalizedeigensolver.hh:244
auto & eigenvalues() const
Returns the eigenvalues of the generalized eigenvalue problem.
Definition: generalizedeigensolver.hh:234
Eigen::GeneralizedSelfAdjointEigenSolver< MatrixType > SolverType
Definition: generalizedeigensolver.hh:182
typename MT::Scalar ScalarType
Definition: generalizedeigensolver.hh:180
This class implements a wrapper to the Spectra generalized eigen solver for square real symmetric mat...
Definition: generalizedeigensolver.hh:281
Spectra::SymGEigsSolver< ProductType, CholeskyType, Spectra::GEigsMode::Cholesky > SolverType
Definition: generalizedeigensolver.hh:291
bool compute(Spectra::SortRule selection=Spectra::SortRule::SmallestAlge, Spectra::SortRule sortRule=Spectra::SortRule::SmallestAlge, Eigen::Index maxit=1000, ScalarType tolerance=1e-10)
Starts the computation of the eigenvalue solver.
Definition: generalizedeigensolver.hh:336
Eigen::Index nev() const
Definition: generalizedeigensolver.hh:368
PartialGeneralizedSymEigenSolver(std::shared_ptr< AssemblerA > assemblerA, std::shared_ptr< AssemblerB > assemblerB, Eigen::Index nev)
Construct a new PartialGeneralizedSymEigenSolver object.
Definition: generalizedeigensolver.hh:322
static constexpr bool isDense
Definition: generalizedeigensolver.hh:283
std::conditional_t< isDense, Spectra::DenseCholesky< ScalarType >, Spectra::SparseCholesky< ScalarType > > CholeskyType
Definition: generalizedeigensolver.hh:289
typename MT::Scalar ScalarType
Definition: generalizedeigensolver.hh:282
MT MatrixType
Definition: generalizedeigensolver.hh:285
Eigen::VectorXd eigenvalues() const
Returns the eigenvalues of the generalized eigenvalue problem.
Definition: generalizedeigensolver.hh:351
std::conditional_t< isDense, Spectra::DenseSymMatProd< ScalarType >, Spectra::SparseSymMatProd< ScalarType > > ProductType
Definition: generalizedeigensolver.hh:287
auto eigenvectors(std::optional< Eigen::Index > _nev=std::nullopt) const
Returns the eigenvectors of the generalized eigenvalue problem.
Definition: generalizedeigensolver.hh:362
PartialGeneralizedSymEigenSolver(MATA &&A, MATB &&B, Eigen::Index nev)
Construct a new PartialGeneralizedSymEigenSolver object.
Definition: generalizedeigensolver.hh:303
Concept defining the requirements for Eigen matrices. This also includes Eigen vectors.
Definition: utils/concepts.hh:373
Concept defining the requirements for sparse or dense Eigen matrices.
Definition: utils/concepts.hh:389