31 #include <Spectra/include/Spectra/SymEigsSolver.h>
32 #include <Spectra/include/Spectra/SymEigsShiftSolver.h>
33 #include <Spectra/include/Spectra/SymGEigsSolver.h>
34 #include <Spectra/include/Spectra/SymGEigsShiftSolver.h>
35 #include <Spectra/include/Spectra/GenEigsSolver.h>
36 #include <Spectra/include/Spectra/MatOp/SparseSymShiftSolve.h>
43 template <
class MatrixType>
class SpectraMatProd
46 typedef typename MatrixType::Scalar Scalar;
47 typedef typename MatrixType::Nested NestedMatrix;
50 SpectraMatProd(
const MatrixType&& ) =
delete;
51 SpectraMatProd(
const MatrixType& mat) : m_mat(mat) {}
52 index_t rows()
const {
return m_mat.rows(); }
53 index_t cols()
const {
return m_mat.cols(); }
54 void perform_op(
const Scalar* x_in, Scalar* y_out)
const
56 GISMO_ASSERT(m_mat.rows()!=0 && m_mat.cols()!=0,
"The matrix has zero rows or columns. Is the matrix a temporary (e.g. A-B)?");
57 gsAsVector<Scalar>(y_out, m_mat.rows()).noalias() =
58 m_mat * gsAsConstVector<Scalar>(x_in, m_mat.cols());
63 template <
class MatrixType>
class SpectraSymMatProd
66 typedef typename MatrixType::Scalar Scalar;
67 typedef typename MatrixType::Nested NestedMatrix;
70 SpectraSymMatProd(
const MatrixType&& ) =
delete;
71 SpectraSymMatProd(
const MatrixType& mat) : m_mat(mat) {}
72 index_t rows()
const {
return m_mat.rows(); }
73 index_t cols()
const {
return m_mat.cols(); }
74 void perform_op(
const Scalar* x_in, Scalar* y_out)
const
76 GISMO_ASSERT(m_mat.rows()!=0 && m_mat.cols()!=0,
"The matrix has zero rows or columns. Is the matrix a temporary (e.g. A-B)?");
77 gsAsVector<Scalar>(y_out, m_mat.rows()).noalias() =
78 m_mat.template selfadjointView<gsEigen::Lower>() * gsAsConstVector<Scalar>(x_in, m_mat.cols());
83 template <
class MatrixType>
84 class SpectraMatShiftSolve
87 typedef typename MatrixType::Scalar Scalar;
88 typedef typename MatrixType::Nested NestedMatrix;
91 #ifdef GISMO_WITH_PARDISO
92 typename gsSparseSolver<Scalar>::PardisoLU m_solver;
93 #elif GISMO_WITH_SUPERLU
94 typename gsSparseSolver<Scalar>::SuperLU m_solver;
96 typename gsSparseSolver<Scalar>::LU m_solver;
99 SpectraMatShiftSolve(
const MatrixType&& ) =
delete;
100 SpectraMatShiftSolve(
const MatrixType& mat)
102 m_mat(mat), m_n(mat.rows())
104 GISMO_ASSERT(m_mat.rows() == m_mat.cols(),
"Matrix must be square!");
106 index_t rows()
const {
return m_n; }
107 index_t cols()
const {
return m_n; }
108 void perform_op(
const Scalar* x_in, Scalar* y_out)
const
110 gsAsVector<Scalar>(y_out, m_n).noalias() = m_solver.solve( gsAsConstVector<Scalar>(x_in, m_n) );
113 void set_shift(
const Scalar& sigma)
115 MatrixType mat(m_mat.template selfadjointView<gsEigen::Lower>());
116 MatrixType identity(m_n,m_n);
117 identity.setIdentity();
119 mat = mat - sigma * identity;
120 #ifndef GISMO_WITH_PARDISO
121 #ifndef GISMO_WITH_SUPERLU
122 m_solver.isSymmetric(
true);
125 m_solver.compute(mat);
133 class SpectraMatShiftSolve<gsMatrix<T>>
136 typedef typename gsMatrix<T>::Nested NestedMatrix;
137 typedef typename gsMatrix<T>::Scalar Scalar;
140 typename Spectra::BKLDLT<Scalar> m_solver;
143 SpectraMatShiftSolve(
const gsMatrix<Scalar>&&) =
delete;
144 SpectraMatShiftSolve(
const gsMatrix<Scalar>& mat)
146 m_mat(mat), m_n(mat.rows())
148 GISMO_ASSERT(m_mat.rows() == m_mat.cols(),
"Matrix must be square!");
150 index_t rows()
const {
return m_n; }
151 index_t cols()
const {
return m_n; }
152 void perform_op(
const Scalar* x_in, Scalar* y_out)
const
154 gsAsVector<Scalar>(y_out, m_n).noalias() = m_solver.solve( gsAsConstVector<Scalar>(x_in, m_n) );
157 void set_shift(
const Scalar& sigma)
159 m_solver.compute(m_mat, gsEigen::Lower, sigma);
160 GISMO_ASSERT(m_solver.info() == Spectra::CompInfo::Successful,
"SpectraMatShiftSolve: factorization failed with the given shift");
165 template <
class MatrixType>
166 class SpectraCholesky
169 typedef typename MatrixType::Scalar Scalar;
170 typedef typename MatrixType::Nested NestedMatrix;
174 gsEigen::SimplicialLLT<gsSparseMatrix<Scalar>, gsEigen::Lower> m_solver;
176 Spectra::CompInfo m_info;
179 SpectraCholesky(
const MatrixType&& ) =
delete;
180 SpectraCholesky(
const MatrixType& mat)
182 m_mat(mat), m_n(mat.rows())
184 GISMO_ASSERT(m_mat.rows() == m_mat.cols(),
"Matrix A must be square!");
186 m_solver.compute(mat);
188 Spectra::CompInfo::Successful :
189 Spectra::CompInfo::NumericalIssue;
191 index_t rows()
const {
return m_n; }
192 index_t cols()
const {
return m_n; }
195 Spectra::CompInfo info()
const {
return m_info; }
198 void lower_triangular_solve(
const Scalar* x_in, Scalar* y_out)
const
200 gsAsConstVector<Scalar> x(x_in, m_n);
201 gsAsVector<Scalar> y(y_out, m_n);
202 y.noalias() = m_solver.permutationP() * x;
203 m_solver.matrixL().solveInPlace(y);
207 void upper_triangular_solve(
const Scalar* x_in, Scalar* y_out)
const
209 gsAsConstVector<Scalar> x(x_in, m_n);
210 gsAsVector<Scalar> y(y_out, m_n);
211 y.noalias() = m_solver.matrixU().solve(x);
212 y = (m_solver.permutationPinv() * y).eval();
217 template <
class MatrixType>
218 class SpectraRegularInverse
221 typedef typename MatrixType::Scalar Scalar;
222 typedef typename MatrixType::Nested NestedMatrix;
225 #ifdef GISMO_WITH_PARDISO
226 typename gsSparseSolver<Scalar>::PardisoLU m_solver;
227 #elif GISMO_WITH_SUPERLU
228 typename gsSparseSolver<Scalar>::SuperLU m_solver;
230 typename gsSparseSolver<Scalar>::CGDiagonal m_solver;
233 Spectra::CompInfo m_info;
236 SpectraRegularInverse(
const MatrixType&& ) =
delete;
237 SpectraRegularInverse(
const MatrixType& mat)
239 m_mat(mat), m_n(mat.rows())
241 GISMO_ASSERT(m_mat.rows() == m_mat.cols(),
"Matrix A must be square!");
243 m_solver.compute(mat);
245 Spectra::CompInfo::Successful :
246 Spectra::CompInfo::NumericalIssue;
248 index_t rows()
const {
return m_n; }
249 index_t cols()
const {
return m_n; }
252 Spectra::CompInfo info()
const {
return m_info; }
255 void solve(
const Scalar* x_in, Scalar* y_out)
const
257 gsAsVector<Scalar>(y_out, m_n).noalias() = m_solver.solve( gsAsConstVector<Scalar>(x_in, m_n) );
261 void perform_op(
const Scalar* x_in, Scalar* y_out)
const
263 gsAsVector<Scalar>(y_out, m_n).noalias() = m_mat.template selfadjointView<gsEigen::Lower>() * gsAsConstVector<Scalar>(x_in, m_n);
268 template <
class MatrixType>
269 class SpectraSymShiftInvert
272 typedef typename MatrixType::Scalar Scalar;
273 typedef typename MatrixType::Nested NestedMatrix;
274 NestedMatrix m_A, m_B;
276 #ifdef GISMO_WITH_PARDISO
277 typename gsSparseSolver<Scalar>::PardisoLU m_solver;
278 #elif GISMO_WITH_SUPERLU
279 typename gsSparseSolver<Scalar>::SuperLU m_solver;
281 typename gsSparseSolver<Scalar>::LU m_solver;
284 SpectraSymShiftInvert(
const MatrixType&& ,
const MatrixType&& ) =
delete;
285 SpectraSymShiftInvert(
const MatrixType& A ,
const MatrixType& B)
287 m_A(A), m_B(B), m_n(A.rows())
289 GISMO_ASSERT(m_A.rows() == m_A.cols(),
"Matrix A must be square!");
290 GISMO_ASSERT(m_B.rows() == m_B.cols(),
"Matrix B must be square!");
291 GISMO_ASSERT(m_B.rows() == m_A.rows(),
"Matrix A and B must be the same size!");
293 index_t rows()
const {
return m_n; }
294 index_t cols()
const {
return m_n; }
295 void perform_op(
const Scalar* x_in, Scalar* y_out)
const
297 gsAsVector<Scalar>(y_out, m_n).noalias() = m_solver.solve( gsAsConstVector<Scalar>(x_in, m_n) );
300 void set_shift(
const Scalar& sigma)
302 MatrixType matA = m_A.template selfadjointView<gsEigen::Lower>();
303 MatrixType matB = m_B.template selfadjointView<gsEigen::Lower>();
304 MatrixType mat = matA - sigma * matB;
306 #ifndef GISMO_WITH_PARDISO
307 #ifndef GISMO_WITH_SUPERLU
308 m_solver.isSymmetric(
true);
311 m_solver.compute(mat);
332 template <
class MatrixType>
334 public Spectra::GenEigsSolver<SpectraMatProd<MatrixType> >
336 typedef SpectraMatProd<MatrixType> MatOp;
337 typedef Spectra::GenEigsSolver<MatOp> Base;
341 MatOp(mat), Base(*
this, nev_, ncv_) { Base::init(); }
345 template <
class MatrixType>
347 public Spectra::SymEigsSolver<SpectraSymMatProd<MatrixType> >
349 typedef SpectraSymMatProd<MatrixType> MatOp;
350 typedef Spectra::SymEigsSolver<MatOp> Base;
354 MatOp(mat), Base(*
this, nev_, ncv_) { Base::init(); }
358 template <
class MatrixType>
360 private SpectraMatShiftSolve<MatrixType>,
361 public Spectra::SymEigsShiftSolver<SpectraMatShiftSolve<MatrixType> >
363 typedef typename MatrixType::Scalar Scalar;
364 typedef SpectraMatShiftSolve<MatrixType> Op;
365 typedef Spectra::SymEigsShiftSolver<Op> Base;
369 Op(mat), Base(*
this, nev_, ncv_,sigma) { Base::init(); }
374 template <
class MatrixType, Spectra::GEigsMode GEigsMode = Spectra::GEigsMode::Cholesky>
378 typedef SpectraSymMatProd<MatrixType> ProdOp;
379 typedef SpectraCholesky<MatrixType> InvOp;
380 SpectraOps(
const MatrixType & A,
const MatrixType & B) : opA(A), opB(B) { }
390 typedef Spectra::DenseCholesky<T> InvOp;
391 typedef SpectraMatProd<MatrixType> ProdOp;
393 SpectraOps(
const MatrixType & A,
const MatrixType & B) : opA(A), opB(B) { }
400 template <
class MatrixType>
401 class SpectraOps<MatrixType,Spectra::GEigsMode::RegularInverse>
404 typedef SpectraRegularInverse<MatrixType> InvOp;
405 typedef SpectraSymMatProd<MatrixType> ProdOp;
406 SpectraOps(
const MatrixType & A,
const MatrixType & B) : opA(A), opB(B) { }
413 template <
class MatrixType, Spectra::GEigsMode GEigsMode = Spectra::GEigsMode::ShiftInvert>
417 typedef typename MatrixType::Scalar Scalar;
418 typedef SpectraSymShiftInvert<MatrixType> InvOp;
419 typedef SpectraSymMatProd<MatrixType> ProdOp;
421 SpectraShiftOps(
const MatrixType & A,
const MatrixType & B) : opA(A,B), opB(B) { }
428 template <
class MatrixType>
432 typedef typename MatrixType::Scalar Scalar;
433 typedef SpectraSymShiftInvert<MatrixType> InvOp;
434 typedef SpectraSymMatProd<MatrixType> ProdOp;
436 SpectraShiftOps(
const MatrixType & A,
const MatrixType & B) : opA(A,B), opB(A) { }
443 template <
class MatrixType, Spectra::GEigsMode GEigsMode = Spectra::GEigsMode::Cholesky>
446 public Spectra::SymGEigsSolver<typename SpectraOps<MatrixType,GEigsMode>::ProdOp, typename SpectraOps<MatrixType,GEigsMode>::InvOp, GEigsMode>
448 typedef typename MatrixType::Scalar Scalar;
450 typedef typename OpType::ProdOp Op;
451 typedef typename OpType::InvOp BOp;
453 typedef Spectra::SymGEigsSolver<Op, BOp,GEigsMode> Base;
457 :
OpType(Amat,Bmat), Base(this->opA, this->opB, nev_, math::min(ncv_,Amat.rows()))
463 template <
class MatrixType, Spectra::GEigsMode GEigsMode = Spectra::GEigsMode::ShiftInvert>
466 public Spectra::SymGEigsShiftSolver<typename SpectraShiftOps<MatrixType,GEigsMode>::InvOp, typename SpectraShiftOps<MatrixType,GEigsMode>::ProdOp, GEigsMode>
468 typedef typename MatrixType::Scalar Scalar;
470 typedef typename OpType::InvOp Op;
471 typedef typename OpType::ProdOp BOp;
473 typedef Spectra::SymGEigsShiftSolver<Op, BOp,GEigsMode> Base;
477 :
OpType(Amat,Bmat), Base(this->opA, this->opB, nev_, math::min(ncv_,Amat.rows()),sigma)
Shifted Eigenvalue solver for real symmetric matrices.
Definition: gsSpectra.h:359
Definition: gsSpectra.h:444
#define index_t
Definition: gsConfig.h:32
A matrix with arbitrary coefficient type and fixed or dynamic size.
Definition: gsMatrix.h:38
#define GISMO_ASSERT(cond, message)
Definition: gsDebug.h:89
Provides preprocessor directives configuration of G+Smo.
Definition: gsSpectra.h:375
Eigenvalue solver for real symmetric matrices.
Definition: gsSpectra.h:346
This is the main header file that collects wrappers of Eigen for linear algebra.
Definition: gsSpectra.h:464
Definition: gsSpectra.h:414
Eigenvalue solver for general real matrices.
Definition: gsSpectra.h:333