5#ifndef DUNE_ISTL_EIGENVALUE_ARPACKPP_HH
6#define DUNE_ISTL_EIGENVALUE_ARPACKPP_HH
8#if HAVE_ARPACKPP || defined DOXYGEN
55 template <
class BCRSMatrix>
56 class ArPackPlusPlus_BCRSMatrixWrapper;
58 template <
class K,
int N,
int M>
70 ArPackPlusPlus_BCRSMatrixWrapper (
const BCRSMatrix& A)
72 m_(A_.
M() * mBlock), n_(A_.
N() * nBlock)
76 (blockLevel<BCRSMatrix>() == 2,
77 "Only BCRSMatrices with blocklevel 2 are supported.");
81 domainBlockVector.resize(A_.N());
82 rangeBlockVector.resize(A_.M());
86 inline void multMv (Real* v, Real* w)
89 arrayToDomainBlockVector(v,domainBlockVector);
92 A_.mv(domainBlockVector,rangeBlockVector);
95 rangeBlockVectorToArray(rangeBlockVector,w);
99 inline void multMtMv (Real* v, Real* w)
102 arrayToDomainBlockVector(v,domainBlockVector);
105 A_.mv(domainBlockVector,rangeBlockVector);
106 A_.mtv(rangeBlockVector,domainBlockVector);
109 domainBlockVectorToArray(domainBlockVector,w);
113 inline void multMMtv (Real* v, Real* w)
116 arrayToRangeBlockVector(v,rangeBlockVector);
119 A_.mtv(rangeBlockVector,domainBlockVector);
120 A_.mv(domainBlockVector,rangeBlockVector);
123 rangeBlockVectorToArray(rangeBlockVector,w);
127 inline int nrows ()
const {
return m_; }
130 inline int ncols ()
const {
return n_; }
134 constexpr static int mBlock = BCRSMatrix::block_type::rows;
135 constexpr static int nBlock = BCRSMatrix::block_type::cols;
139 constexpr static int dbvBlockSize = nBlock;
145 constexpr static int rbvBlockSize = mBlock;
150 typedef typename DomainBlockVector::size_type dbv_size_type;
151 typedef typename RangeBlockVector::size_type rbv_size_type;
152 typedef typename DomainBlockVectorBlock::size_type dbvb_size_type;
153 typedef typename RangeBlockVectorBlock::size_type rbvb_size_type;
158 domainBlockVectorToArray (
const DomainBlockVector& dbv, Real* v)
160 for (dbv_size_type block = 0; block < dbv.N(); ++block)
161 for (dbvb_size_type iBlock = 0; iBlock < dbvBlockSize; ++iBlock)
162 v[block*dbvBlockSize + iBlock] = dbv[block][iBlock];
168 rangeBlockVectorToArray (
const RangeBlockVector& rbv, Real* v)
170 for (rbv_size_type block = 0; block < rbv.N(); ++block)
171 for (rbvb_size_type iBlock = 0; iBlock < rbvBlockSize; ++iBlock)
172 v[block*rbvBlockSize + iBlock] = rbv[block][iBlock];
178 static inline void arrayToDomainBlockVector (
const Real* v,
179 DomainBlockVector& dbv)
181 for (dbv_size_type block = 0; block < dbv.N(); ++block)
182 for (dbvb_size_type iBlock = 0; iBlock < dbvBlockSize; ++iBlock)
183 dbv[block][iBlock] = v[block*dbvBlockSize + iBlock];
188 static inline void arrayToRangeBlockVector (
const Real* v,
189 RangeBlockVector& rbv)
191 for (rbv_size_type block = 0; block < rbv.N(); ++block)
192 for (rbvb_size_type iBlock = 0; iBlock < rbvBlockSize; ++iBlock)
193 rbv[block][iBlock] = v[block*rbvBlockSize + iBlock];
198 const BCRSMatrix& A_;
205 mutable DomainBlockVector domainBlockVector;
206 mutable RangeBlockVector rangeBlockVector;
212 class ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix<K>>
222 ArPackPlusPlus_BCRSMatrixWrapper (
const BCRSMatrix& A)
224 m_(A_.
M()), n_(A_.
N())
228 domainVector.resize(A_.N());
229 rangeVector.resize(A_.M());
233 inline void multMv (Real* v, Real* w)
238 arrayToDomainBlockVector(v,domainVector);
241 A_.mv(domainVector,rangeVector);
244 rangeVectorToArray(rangeVector,w);
248 inline void multMtMv (Real* v, Real* w)
251 arrayToDomainBlockVector(v,domainVector);
254 A_.mv(domainVector,rangeVector);
255 A_.mtv(rangeVector,domainVector);
258 domainVectorToArray(domainVector,w);
262 inline void multMMtv (Real* v, Real* w)
265 arrayToRangeVector(v,rangeVector);
268 A_.mtv(rangeVector,domainVector);
269 A_.mv(domainVector,rangeVector);
272 rangeVectorToArray(rangeVector,w);
276 inline int nrows ()
const {
return m_; }
279 inline int ncols ()
const {
return n_; }
289 typedef typename DomainVector::size_type dbv_size_type;
290 typedef typename RangeVector::size_type rbv_size_type;
295 domainVectorToArray (
const DomainVector& dbv, Real* v)
297 for (dbv_size_type i = 0; i < dbv.N(); ++i)
304 rangeVectorToArray (
const RangeVector& rbv, Real* v)
306 for (rbv_size_type i = 0; i < rbv.N(); ++i)
313 static inline void arrayToDomainBlockVector (
const Real* v,
316 for (dbv_size_type i = 0; i < dbv.N(); ++i)
322 static inline void arrayToRangeBlockVector (
const Real* v,
325 for (rbv_size_type i = 0; i < rbv.N(); ++i)
331 const BCRSMatrix& A_;
338 mutable DomainVector domainVector;
339 mutable RangeVector rangeVector;
383 template <
typename BCRSMatrix,
typename BlockVector>
409 const unsigned int nIterationsMax = 100000,
410 const unsigned int verbosity_level = 0)
414 title_(
" ArPackPlusPlus_Algorithms: "),
435 <<
"the dominant eigenvalue of a matrix which "
436 <<
"is assumed to be symmetric." <<
std::endl;
440 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix> WrappedMatrix;
444 const int nrows = A.nrows();
445 const int ncols = A.ncols();
450 << nrows <<
"x" << ncols <<
").");
455 const Real tol = epsilon;
458 const bool ivec =
true;
463 ARSymStdEig<Real,WrappedMatrix>
464 dprob(nrows, nev, &A, &WrappedMatrix::multMv, which, ncv, tol, maxit);
470 nconv = dprob.Eigenvalues(ev,ivec);
476 Real* x_raw = dprob.RawEigenvector(nev-1);
477 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);
485 A.multMv(x_raw,Ax_raw);
486 WrappedMatrix::arrayToDomainBlockVector(Ax_raw,r);
488 const Real r_norm = r.two_norm();
497 <<
"A*x = λ*x using the ARPACK++ class ARSym"
506 <<
"║residual║_2 = " << r_norm <<
"): "
537 <<
"least dominant eigenvalue of a matrix which "
538 <<
"is assumed to be symmetric." <<
std::endl;
542 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix> WrappedMatrix;
546 const int nrows = A.nrows();
547 const int ncols = A.ncols();
552 << nrows <<
"x" << ncols <<
").");
557 const Real tol = epsilon;
560 const bool ivec =
true;
565 ARSymStdEig<Real,WrappedMatrix>
566 dprob(nrows, nev, &A, &WrappedMatrix::multMv, which, ncv, tol, maxit);
572 nconv = dprob.Eigenvalues(ev,ivec);
578 Real* x_raw = dprob.RawEigenvector(nev-1);
579 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);
587 A.multMv(x_raw,Ax_raw);
588 WrappedMatrix::arrayToDomainBlockVector(Ax_raw,r);
590 const Real r_norm = r.two_norm();
599 <<
"A*x = λ*x using the ARPACK++ class ARSym"
608 <<
"║residual║_2 = " << r_norm <<
"): "
638 <<
"spectral condition number of a matrix which "
639 <<
"is assumed to be symmetric." <<
std::endl;
643 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix> WrappedMatrix;
647 const int nrows = A.nrows();
648 const int ncols = A.ncols();
653 << nrows <<
"x" << ncols <<
").");
658 const Real tol = epsilon;
661 const bool ivec =
true;
666 ARSymStdEig<Real,WrappedMatrix>
667 dprob(nrows, nev, &A, &WrappedMatrix::multMv, which, ncv, tol, maxit);
673 nconv = dprob.Eigenvalues(ev,ivec);
676 const Real& lambda_max = ev[nev-1];
677 const Real& lambda_min = ev[0];
680 Real* x_max_raw = dprob.RawEigenvector(nev-1);
681 Real* x_min_raw = dprob.RawEigenvector(0);
684 cond_2 = std::abs(lambda_max / lambda_min);
692 A.multMv(x_max_raw,Ax_max_raw);
693 A.multMv(x_min_raw,Ax_min_raw);
694 Real r_max_norm = 0.0;
695 Real r_min_norm = 0.0;
696 for (
int i = 0; i < nrows; ++i)
698 r_max_norm +=
std::pow(Ax_max_raw[i] - lambda_max * x_max_raw[i],2);
699 r_min_norm +=
std::pow(Ax_min_raw[i] - lambda_min * x_min_raw[i],2);
711 <<
"A*x = λ*x using the ARPACK++ class ARSym"
724 <<
"║residual║_2 = {" << r_max_norm <<
","
725 << r_min_norm <<
"}, " <<
"λ = {"
726 << lambda_max <<
"," << lambda_min
727 <<
"}): cond_2 = " << cond_2 <<
std::endl;
755 <<
"largest singular value of a matrix which "
756 <<
"is assumed to be nonsymmetric." <<
std::endl;
760 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix> WrappedMatrix;
764 const int nrows = A.nrows();
765 const int ncols = A.ncols();
770 <<
"columns (" << nrows <<
"x" << ncols <<
")."
771 <<
" This case is not implemented, yet.");
776 const Real tol = epsilon;
779 const bool ivec =
true;
784 ARSymStdEig<Real,WrappedMatrix>
785 dprob(ncols, nev, &A, &WrappedMatrix::multMtMv, which, ncv, tol, maxit);
791 nconv = dprob.Eigenvalues(ev,ivec);
794 const Real& lambda = ev[nev-1];
797 Real* x_raw = dprob.RawEigenvector(nev-1);
798 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);
806 A.multMtMv(x_raw,AtAx_raw);
807 WrappedMatrix::arrayToDomainBlockVector(AtAx_raw,r);
809 const Real r_norm = r.two_norm();
822 <<
"ving (A^T*A)*x = σ²*x using the ARPACK++ "
833 <<
"║residual║_2 = " << r_norm <<
"): "
867 <<
"smallest singular value of a matrix which "
868 <<
"is assumed to be nonsymmetric." <<
std::endl;
872 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix> WrappedMatrix;
876 const int nrows = A.nrows();
877 const int ncols = A.ncols();
882 <<
"columns (" << nrows <<
"x" << ncols <<
")."
883 <<
" This case is not implemented, yet.");
888 const Real tol = epsilon;
891 const bool ivec =
true;
896 ARSymStdEig<Real,WrappedMatrix>
897 dprob(ncols, nev, &A, &WrappedMatrix::multMtMv, which, ncv, tol, maxit);
903 nconv = dprob.Eigenvalues(ev,ivec);
906 const Real& lambda = ev[nev-1];
909 Real* x_raw = dprob.RawEigenvector(nev-1);
910 WrappedMatrix::arrayToDomainBlockVector(x_raw,x);
918 A.multMtMv(x_raw,AtAx_raw);
919 WrappedMatrix::arrayToDomainBlockVector(AtAx_raw,r);
921 const Real r_norm = r.two_norm();
934 <<
"ving (A^T*A)*x = σ²*x using the ARPACK++ "
945 <<
"║residual║_2 = " << r_norm <<
"): "
975 <<
"spectral condition number of a matrix which "
976 <<
"is assumed to be nonsymmetric." <<
std::endl;
980 typedef Impl::ArPackPlusPlus_BCRSMatrixWrapper<BCRSMatrix> WrappedMatrix;
984 const int nrows = A.nrows();
985 const int ncols = A.ncols();
990 <<
"columns (" << nrows <<
"x" << ncols <<
")."
991 <<
" This case is not implemented, yet.");
996 const Real tol = epsilon;
999 const bool ivec =
true;
1003 char which[] =
"BE";
1004 ARSymStdEig<Real,WrappedMatrix>
1005 dprob(ncols, nev, &A, &WrappedMatrix::multMtMv, which, ncv, tol, maxit);
1011 nconv = dprob.Eigenvalues(ev,ivec);
1014 const Real& lambda_max = ev[nev-1];
1015 const Real& lambda_min = ev[0];
1018 Real* x_max_raw = dprob.RawEigenvector(nev-1);
1019 Real* x_min_raw = dprob.RawEigenvector(0);
1025 Real* AtAx_max_raw =
new Real[ncols];
1026 Real* AtAx_min_raw =
new Real[ncols];
1027 A.multMtMv(x_max_raw,AtAx_max_raw);
1028 A.multMtMv(x_min_raw,AtAx_min_raw);
1029 Real r_max_norm = 0.0;
1030 Real r_min_norm = 0.0;
1031 for (
int i = 0; i < ncols; ++i)
1033 r_max_norm +=
std::pow(AtAx_max_raw[i] - lambda_max * x_max_raw[i],2);
1034 r_min_norm +=
std::pow(AtAx_min_raw[i] - lambda_min * x_min_raw[i],2);
1044 cond_2 = sigma_max / sigma_min;
1053 <<
"ving (A^T*A)*x = σ²*x using the ARPACK++ "
1068 <<
"║residual║_2 = {" << r_max_norm <<
","
1069 << r_min_norm <<
"}, " <<
"σ = {"
1070 << sigma_max <<
"," << sigma_min
1071 <<
"}): cond_2 = " << cond_2 <<
std::endl;
1075 delete[] AtAx_min_raw;
1076 delete[] AtAx_max_raw;
Some generic functions for pretty printing vectors and matrices.
Helper functions for determining the vector/matrix block level.
This file implements a vector space as a tensor product of a given vector space. The number of compon...
void printvector(std::ostream &s, const V &v, std::string title, std::string rowtext, int columns=1, int width=10, int precision=2)
Print an ISTL vector.
Definition io.hh:89
static constexpr size_type M()
static constexpr size_type N()
#define DUNE_THROW(E,...)
A sparse block matrix with compressed row storage.
Definition bcrsmatrix.hh:468
typename Imp::BlockTraits< B >::field_type field_type
export the type representing the field
Definition bcrsmatrix.hh:490
A vector of blocks with memory management.
Definition bvector.hh:392
typename Imp::BlockTraits< B >::field_type field_type
export the type representing the field
Definition bvector.hh:398
Wrapper to use a range of ARPACK++ eigenvalue solvers.
Definition arpackpp.hh:385
const unsigned int verbosity_level_
Definition arpackpp.hh:1098
unsigned int getIterationCount() const
Return the number of iterations in last application of an algorithm.
Definition arpackpp.hh:1084
const std::string title_
Definition arpackpp.hh:1106
BlockVector::field_type Real
Definition arpackpp.hh:387
void computeSymMaxMagnitude(const Real &epsilon, BlockVector &x, Real &lambda) const
Assume the matrix to be square, symmetric and perform IRLM to compute an approximation lambda of its ...
Definition arpackpp.hh:429
void computeSymMinMagnitude(const Real &epsilon, BlockVector &x, Real &lambda) const
Assume the matrix to be square, symmetric and perform IRLM to compute an approximation lambda of its ...
Definition arpackpp.hh:531
const BCRSMatrix & m_
Definition arpackpp.hh:1094
const unsigned int nIterationsMax_
Definition arpackpp.hh:1095
const std::string blank_
Definition arpackpp.hh:1107
ArPackPlusPlus_Algorithms(const BCRSMatrix &m, const unsigned int nIterationsMax=100000, const unsigned int verbosity_level=0)
Construct from required parameters.
Definition arpackpp.hh:408
void computeSymCond2(const Real &epsilon, Real &cond_2) const
Assume the matrix to be square, symmetric and perform IRLM to compute an approximation of its spectra...
Definition arpackpp.hh:633
unsigned int nIterations_
Definition arpackpp.hh:1103
void computeNonSymMin(const Real &epsilon, BlockVector &x, Real &sigma) const
Assume the matrix to be nonsymmetric and perform IRLM to compute an approximation sigma of its smalle...
Definition arpackpp.hh:861
void computeNonSymCond2(const Real &epsilon, Real &cond_2) const
Assume the matrix to be nonsymmetric and perform IRLM to compute an approximation of its spectral con...
Definition arpackpp.hh:970
void computeNonSymMax(const Real &epsilon, BlockVector &x, Real &sigma) const
Assume the matrix to be nonsymmetric and perform IRLM to compute an approximation sigma of its larges...
Definition arpackpp.hh:749
derive error class from the base class in common
Definition istlexception.hh:19