Dune Core Modules (2.8.0)

matrixinfo.hh
1// -*- tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
2// vi: set et ts=4 sw=2 sts=2:
3#ifndef DUNE_ISTL_EIGENVALUE_TEST_MATRIXINFO_HH
4#define DUNE_ISTL_EIGENVALUE_TEST_MATRIXINFO_HH
5
6#include <cmath> // provides std::abs and std::sqrt
7#include <cassert> // provides assert
8#include <limits>
9#include <iostream> // provides std::cout, std::endl
10
11#include <dune/common/exceptions.hh> // provides DUNE_THROW(...), Dune::Exception
12#include <dune/common/fvector.hh> // provides Dune::FieldVector
13
14#include <dune/istl/blocklevel.hh> // provides Dune::blockLevel
15#include <dune/istl/bvector.hh> // provides Dune::BlockVector
16#include <dune/istl/superlu.hh> // provides Dune::SuperLU
17#include <dune/istl/preconditioners.hh> // provides Dune::SeqGS
18#include <dune/istl/solvers.hh> // provides Dune::BiCGSTABSolver
19#include <dune/istl/matrixmatrix.hh> // provides Dune::transposeMatMultMat(...)
20
21#include "../arpackpp.hh" // provides Dune::ArPackPlusPlus_Algorithms
22#include "../poweriteration.hh" // provides Dune::PowerIteration_Algorithms
23
24
39template <typename BCRSMatrix>
41{
42public:
44 typedef typename BCRSMatrix::field_type Real;
45
46public:
61 MatrixInfo (const BCRSMatrix& m,
62 const bool verbose = false,
63 const unsigned int arppp_a_verbosity_level = 0,
64 const unsigned int pia_verbosity_level = 0)
65 : m_(m),
66 verbose_(verbose),
67 arppp_a_verbosity_level_(arppp_a_verbosity_level*verbose),
68 pia_verbosity_level_(pia_verbosity_level*verbose),
69 cond_2_(-1.0), symmetricity_assumed_(false)
70 {
71 // assert that BCRSMatrix type has blocklevel 2
72 static_assert
73 (Dune::blockLevel<BCRSMatrix>() == 2,
74 "Only BCRSMatrices with blocklevel 2 are supported.");
75
76 // assert that BCRSMatrix type has square blocks
77 static_assert
78 (BCRSMatrix::block_type::rows == BCRSMatrix::block_type::cols,
79 "Only BCRSMatrices with square blocks are supported.");
80
81 // assert that m_ is square
82 const int nrows = m_.M() * BCRSMatrix::block_type::rows;
83 const int ncols = m_.N() * BCRSMatrix::block_type::cols;
84 if (nrows != ncols)
85 DUNE_THROW(Dune::Exception,"Matrix is not square ("
86 << nrows << "x" << ncols << ").");
87 }
88
90 inline Real getCond2 (const bool assume_symmetric = true) const
91 {
92 if (cond_2_ == -1.0 || symmetricity_assumed_ != assume_symmetric)
93 {
94 if (verbose_)
95 std::cout << " MatrixInfo: Computing 2-norm condition number"
96 << (assume_symmetric ? " (assuming that matrix is symmetric)." : ".")
97 << std::endl;
98
99 if (assume_symmetric)
100 cond_2_ = computeSymCond2(); // assume that m_ is symmetric
101 else
102 cond_2_ = computeNonSymCond2(); // don't assume that m_ is symmetric
103
104 symmetricity_assumed_ = assume_symmetric;
105 }
106 return cond_2_;
107 }
108
109protected:
112 static const int bvBlockSize = BCRSMatrix::block_type::rows;
115
116protected:
121 inline Real computeSymCond2 () const
122 {
123 // 1) allocate memory for largest and smallest magnitude eigenvalue
124 // as well as the spectral (i.e. 2-norm) condition number
125 Real lambda_max{}, lambda_min{}, cond_2{};
126
127 // 2) allocate memory for starting vectors and approximated
128 // eigenvectors
129 BlockVector x(m_.M());
130
131#if HAVE_ARPACKPP
132 // 3) setup ARPACK++ eigenvalue algorithms
134 const ARPPP_A arppp_a(m_,100000,arppp_a_verbosity_level_);
135#endif // HAVE_ARPACKPP
136
137 // 4) setup power iteration based iterative eigenvalue algorithms
139 PIA pia(m_,20000,pia_verbosity_level_);
140 static const bool avoidLinSolverCrime = true;
141
142#if HAVE_SUPERLU
143 // 5) select a linear solver for power iteration based iterative
144 // eigenvalue algorithms
145 typedef Dune::SuperLU<BCRSMatrix> PIALS;
146 const unsigned int piaLS_verbosity = 0;
147 PIALS piaLS(pia.getIterationMatrix(),piaLS_verbosity);
148#else
149 // 5) select a linear solver for power iteration based iterative
150 // eigenvalue algorithms
151 typedef Dune::SeqGS<BCRSMatrix,
152 typename PIA::IterationOperator::domain_type,
153 typename PIA::IterationOperator::range_type> PIAPC;
154 PIAPC piaPC(pia.getIterationMatrix(),2,1.0);
155 const double piaLS_reduction = 1e-02;
156 const unsigned int piaLS_max_iter = 1000;
157 const unsigned int piaLS_verbosity = 0;
159 PIALS piaLS(pia.getIterationOperator(),piaPC,
160 piaLS_reduction,piaLS_max_iter,piaLS_verbosity);
161#endif // HAVE_SUPERLU
162
163#if HAVE_ARPACKPP
164 // 6) get largest magnitude eigenvalue via ARPACK++
165 // (assume that m_ is symmetric)
166 {
167 const Real epsilon = 0.0;
168 // x = 1.0; (not supported yet)
169 arppp_a.computeSymMaxMagnitude(epsilon,x,lambda_max);
170 }
171#else
172 // 6) get largest magnitude eigenvalue via a combination of
173 // power and TLIME iteration (assume that m_ is symmetric)
174 {
175 const Real epsilonPI = 1e-02;
176 const Real epsilonTLIME = 1e-08;
177 x = 1.0;
178 // 6.1) perform power iteration for largest magnitude
179 // eigenvalue (predictor)
180 pia.applyPowerIteration(epsilonPI,x,lambda_max);
181 // 6.2) perform TLIME iteration to improve result (corrector)
182 const Real gamma = m_.infinity_norm();
183 const Real eta = 0.0;
184 const Real delta = 1e-03;
185 bool external;
186 pia.template applyTLIMEIteration<PIALS,avoidLinSolverCrime>
187 (gamma,eta,epsilonTLIME,piaLS,delta,2,external,x,lambda_max);
188 assert(external);
189 }
190#endif // HAVE_ARPACKPP
191
192 // 7) get smallest magnitude eigenvalue via TLIME iteration
193 // (assume that m_ is symmetric)
194 {
195 const Real epsilon = std::sqrt(std::numeric_limits<Real>::epsilon());
196 x = 1.0;
197 // 7.1) perform TLIME iteration for smallest magnitude
198 // eigenvalue
199 const Real gamma = 0.0;
200 const Real eta = 0.0;
201 const Real delta = 1e-03;
202 bool external;
203 pia.template applyTLIMEIteration<PIALS,avoidLinSolverCrime>
204 (gamma,eta,epsilon,piaLS,delta,2,external,x,lambda_min);
205 assert(external);
206 }
207
208 // 8) check largest magnitude eigenvalue (we have
209 // ||m|| >= |lambda| for each eigenvalue lambda
210 // of a matrix m and each matrix norm ||.||)
211 if (std::abs(lambda_max) > m_.infinity_norm())
212 DUNE_THROW(Dune::Exception,"Absolute value of approximated "
213 << "largest magnitude eigenvalue is greater than "
214 << "infinity norm of the matrix!");
215
216 // 9) output largest magnitude eigenvalue
217 if (verbose_)
218 std::cout << " Largest magnitude eigenvalue λ_max = "
219 << lambda_max << std::endl;
220
221 // 10) output smallest magnitude eigenvalue
222 if (verbose_)
223 std::cout << " Smallest magnitude eigenvalue λ_min = "
224 << lambda_min << std::endl;
225
226 // 11) compute spectral (i.e. 2-norm) condition number
227 // (assume that m_ is symmetric)
228 cond_2 = std::abs(lambda_max / lambda_min);
229
230 // 12) output spectral (i.e. 2-norm) condition number
231 if (verbose_)
232 std::cout << " 2-norm condition number cond_2 = "
233 << cond_2 << std::endl;
234
235 // 13) return spectral (i.e. 2-norm) condition number
236 return cond_2;
237 }
238
241 inline Real computeNonSymCond2 () const
242 {
243 // 1) allocate memory for largest and smallest singular value
244 // as well as the spectral (i.e. 2-norm) condition number
245 Real sigma_max, sigma_min, cond_2;
246
247 // 2) allocate memory for starting vectors and approximated
248 // eigenvectors respectively singular vectors
249 BlockVector x(m_.M());
250
251#if HAVE_ARPACKPP
252 // 3) setup ARPACK++ eigenvalue algorithms
254 const ARPPP_A arppp_a(m_,100000,arppp_a_verbosity_level_);
255#endif // HAVE_ARPACKPP
256
257 // 4) compute m^t*m
258 BCRSMatrix mtm;
259 Dune::transposeMatMultMat(mtm,m_,m_);
260
261 // 5) allocate memory for largest and smallest magnitude
262 // eigenvalue of m^t*m
263 Real lambda_max{}, lambda_min{};
264
265 // 6) setup power iteration based iterative eigenvalue algorithms
266 // for m^t*m
268 PIA pia(mtm,20000,pia_verbosity_level_);
269 static const bool avoidLinSolverCrime = true;
270
271#if HAVE_SUPERLU
272 // 7) select a linear solver for power iteration based iterative
273 // eigenvalue algorithms for m^t*m
274 typedef Dune::SuperLU<BCRSMatrix> PIALS;
275 const unsigned int piaLS_verbosity = 0;
276 PIALS piaLS(pia.getIterationMatrix(),piaLS_verbosity);
277#else
278 // 7) select a linear solver for power iteration based iterative
279 // eigenvalue algorithms for m^t*m
280 typedef Dune::SeqGS<BCRSMatrix,
281 typename PIA::IterationOperator::domain_type,
282 typename PIA::IterationOperator::range_type> PIAPC;
283 PIAPC piaPC(pia.getIterationMatrix(),2,1.0);
284 const double piaLS_reduction = 1e-02;
285 const unsigned int piaLS_max_iter = 1000;
286 const unsigned int piaLS_verbosity = 0;
288 PIALS piaLS(pia.getIterationOperator(),piaPC,
289 piaLS_reduction,piaLS_max_iter,piaLS_verbosity);
290#endif // HAVE_SUPERLU
291
292#if HAVE_ARPACKPP
293 // 8) get largest singular value via ARPACK++
294 {
295 const Real epsilon = 0.0;
296 // x = 1.0; (not supported yet)
297 arppp_a.computeNonSymMax(epsilon,x,sigma_max);
298 }
299#else
300 // 8) get largest singular value as square root of the largest
301 // magnitude eigenvalue of m^t*m via a combination of power
302 // and TLIME iteration
303 {
304 const Real epsilonPI = 1e-02;
305 const Real epsilonTLIME = 1e-08;
306 x = 1.0;
307 // 8.1) perform power iteration for largest magnitude
308 // eigenvalue of m^t*m (predictor)
309 pia.applyPowerIteration(epsilonPI,x,lambda_max);
310 // 8.2) perform TLIME iteration to improve result (corrector)
311 const Real gamma = mtm.infinity_norm();
312 const Real eta = 0.0;
313 const Real delta = 1e-03;
314 bool external;
315 pia.template applyTLIMEIteration<PIALS,avoidLinSolverCrime>
316 (gamma,eta,epsilonTLIME,piaLS,delta,2,external,x,lambda_max);
317 assert(external);
318 // 8.3) get largest singular value
319 sigma_max = std::sqrt(lambda_max);
320 }
321#endif // HAVE_ARPACKPP
322
323 // 9) get smallest singular value as square root of the smallest
324 // magnitude eigenvalue of m^t*m via TLIME iteration
325 {
326 const Real epsilon = std::sqrt(std::numeric_limits<Real>::epsilon());
327 x = 1.0;
328 // 9.1) perform TLIME iteration for smallest magnitude
329 // eigenvalue of m^t*m
330 const Real gamma = 0.0;
331 const Real eta = 0.0;
332 const Real delta = 1e-03;
333 bool external;
334 pia.template applyTLIMEIteration<PIALS,avoidLinSolverCrime>
335 (gamma,eta,epsilon,piaLS,delta,2,external,x,lambda_min);
336 assert(external);
337 // 9.2) get smallest singular value
338 sigma_min = std::sqrt(lambda_min);
339 }
340
341 // 10) check largest magnitude eigenvalue (we have
342 // ||m|| >= |lambda| for each eigenvalue lambda
343 // of a matrix m and each matrix norm ||.||)
344 if (std::abs(lambda_max) > mtm.infinity_norm())
345 DUNE_THROW(Dune::Exception,"Absolute value of approximated "
346 << "largest magnitude eigenvalue is greater than "
347 << "infinity norm of the matrix!");
348
349 // 11) output largest singular value
350 if (verbose_)
351 std::cout << " Largest singular value σ_max = "
352 << sigma_max << std::endl;
353
354 // 12) output smallest singular value
355 if (verbose_)
356 std::cout << " Smallest singular value σ_min = "
357 << sigma_min << std::endl;
358
359 // 13) compute spectral (i.e. 2-norm) condition number
360 cond_2 = sigma_max / sigma_min;
361
362 // 14) output spectral (i.e. 2-norm) condition number
363 if (verbose_)
364 std::cout << " 2-norm condition number cond_2 = "
365 << cond_2 << std::endl;
366
367 // 15) return spectral (i.e. 2-norm) condition number
368 return cond_2;
369 }
370
371protected:
372 // parameters related to computation of matrix information
373 const BCRSMatrix& m_;
374
375 // verbosity setting
376 const bool verbose_;
377 const unsigned int arppp_a_verbosity_level_;
378 const unsigned int pia_verbosity_level_;
379
380 // memory for storing matrix information
381 // (mutable as matrix information is computed on demand)
382 mutable Real cond_2_;
383 mutable bool symmetricity_assumed_;
384};
385
386
387#endif // DUNE_ISTL_EIGENVALUE_TEST_MATRIXINFO_HH
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...
Wrapper to use a range of ARPACK++ eigenvalue solvers.
Definition: arpackpp.hh:243
Bi-conjugate Gradient Stabilized (BiCG-STAB)
Definition: solvers.hh:416
A vector of blocks with memory management.
Definition: bvector.hh:393
Base class for Dune-Exceptions.
Definition: exceptions.hh:94
vector space out of a tensor product of fields.
Definition: fvector.hh:95
Iterative eigenvalue algorithms based on power iteration.
Definition: poweriteration.hh:174
Sequential SOR preconditioner.
Definition: preconditioners.hh:259
SuperLu Solver.
Definition: superlu.hh:269
Class template which yields information related to a square matrix like its spectral (i....
Definition: matrixinfo.hh:41
MatrixInfo(const BCRSMatrix &m, const bool verbose=false, const unsigned int arppp_a_verbosity_level=0, const unsigned int pia_verbosity_level=0)
Construct from required parameters.
Definition: matrixinfo.hh:61
Real computeSymCond2() const
Definition: matrixinfo.hh:121
Real getCond2(const bool assume_symmetric=true) const
return spectral (i.e. 2-norm) condition number of the matrix
Definition: matrixinfo.hh:90
BCRSMatrix::field_type Real
Type of the underlying field of the matrix.
Definition: matrixinfo.hh:44
static const int bvBlockSize
Definition: matrixinfo.hh:112
Real computeNonSymCond2() const
Definition: matrixinfo.hh:241
A few common exception classes.
Implements a vector constructed from a given type representing a field and a compile-time given size.
#define DUNE_THROW(E, m)
Definition: exceptions.hh:216
void transposeMatMultMat(BCRSMatrix< FieldMatrix< T, n, m >, A > &res, const BCRSMatrix< FieldMatrix< T, k, n >, A1 > &mat, const BCRSMatrix< FieldMatrix< T, k, m >, A2 > &matt, bool tryHard=false)
Calculate product of a transposed sparse matrix with another sparse matrices ( ).
Definition: matrixmatrix.hh:588
provides functions for sparse matrix matrix multiplication.
Define general preconditioner interface.
Implementations of the inverse operator interface.
Classes for using SuperLU with ISTL matrices.
Creative Commons License   |  Legal Statements / Impressum  |  Hosted by TU Dresden  |  generated with Hugo v0.111.3 (Dec 22, 23:30, 2024)