FILTLAN  1.0a
laneig.h
Go to the documentation of this file.
1 #ifndef LANEIG_H
2 #define LANEIG_H
3 
7 #include <math.h> // for sqrt, pow, etc.
8 #include <iostream> // for ostream, cout, cerr, endl, etc. (under namespace std)
9 
10 #ifdef USE_NAMESPACE
11 using namespace MATKIT;
12 namespace MATKIT {
13 #endif
14 
15 class Vector;
16 class Matrix;
17 class SymmetricMatrix;
18 class SparseMatrix;
19 
20 #ifdef USE_NAMESPACE
21 } // end of namespace MATKIT
22 #endif
23 
24 
25 
31 // an instance of this class, taken by LanczosEigenSolver(), is a collection of options for the Lanczos procedure to solve symmetric eigenvalue problems
35 
38  // this parameter tells whether eigenvectors are wanted or not (default true)
39  // note that the standard Lanczos procedure computes the eigenvalues first
40  // the computation of eigenvectors is unnecessary if only the eigenvalues are required
41  bool wantEigVec;
43 
47  // minimum number of Lanczos iterations
48  // this is the number of iterations performed before checking convergence
49  // the default value is 0, which means that it will be determined by LanczosOptions::defaultMinIterFactor
50  mkIndex minIter;
52 
56  // maximum number of Lanczos iterations
57  // this is the maximum number of iterations performed even if some desired eigenvalues do not yet converge
58  // the default value is 0, which means that it will be determined by LanczosOptions::defaultMaxIterFactor
59  mkIndex maxIter;
61 
76  // extraIter is the extra number of Lanczos iterations (default 100)
77  // this is the number of Lanczos iterations performed after the Ritz values are `deemed' converged to the desired eigenvalues
78  // there are two reasons to perform more Lanczos iterations
79  // first, to improve the accuracy of the computed eigenvalues / eigenvectors
80  // second, it is possible that there are missing eigenvalues
81  // for instance, when the 10 largest Ritz values are converged to 10 eigenvalues,
82  // it is possible that the 10 eigenvalues are not the largest,
83  // because one or more of the 10 largest eigenvalues do not yet show up as Ritz values
84  // nevertheless, these missing eigenvalues, if any, may come out by applying more iterations
85  // this issue can be serious in a filtered Lanczos procedure with a high degree polynomial
86  // finally, the phase of such extra iterations may be repeated for a few times until all desired eigenvalues are found
87  mkIndex extraIter;
89  // the convergence is checked every `stride' iterations (default 10)
90  mkIndex stride;
92 
94  // The default LanczosOptions::minIter, if not set, is LanczosOptions::defaultMinIterFactor times the number of (largest or smallest) eigenvalues requested
95  // the default value of LanczosOptions::defaultMinIterFactor is 5
98 
100  // The default LanczosOptions::maxIter, if not set, is 500 plus LanczosOptions::defaultMaxIterFactor times the number of (largest or smallest) eigenvalues requested
101  // the default value of LanczosOptions::defaultMaxIterFactor is 50
104  // tolerance of eigenvalues, defined in the relative and average sense, for convergence check (default eps^{0.8}, with eps the machine epsilon)
105  Real tol;
107 
110  // the initial Lanczos vector
111  // if v0.Length() is not the number of rows/columns of the matrix, then
112  // a random vector is generated for the initial Lanczos vector as the default case
113  Vector v0;
114 
115  // variables for reorthogonalization
117 
123  // a flag to tell which reorthogonalization scheme is used (default 1):
124  // 0 for no reorthogonalization (reserved option);
125  // 1 for partial reorthogonalization (default and recommended);
126  // 2 for full reorthogonalization
127  int reorth;
129 
137  // reorthogonalization is doubled in the iterations with nrm < doubleReorthGamma*nrm_old
138  // the default value of doubleReorthGamma is sqrt(0.5)
139  // nrm_old and nrm are the norms of the latest Lanczos vector before and after reorthogonalization
140  // doubleReorthGamma==0.0 (or smaller) means that reorthogonalization is never doubled
141  // doubleReorthGamma==1.0 (or larger) means that reorthogonalization, whenever it is performed, is always doubled
142  // this parameter is effective only if LanczosOptions::reorh==1 or LanczosOptions::reorth==2 (i.e. partial or full reorthogonalization)
145 
150  // local reorthogonalization is performed if beta[j-1] < localReorthGamma*beta[j] or localReorthGamma >= 1.0,
151  // the default value of localReorthGamma is sqrt(0.5)
152  // where beta[j] is the latest beta and beta[j-1] is the previous beta at j-th Lanczos iteration
153  // localReorthGamma=0.0 (or smaller) means that local reorthogonalization is never performed
154  // this parameter is effective only if LanczosOptions::reorth==1 (i.e. partial reorthogonalization) as input of LanczosEigenSolver().
157 
173  // a flag to tell which partial reorthogonalization strategy is used:
174  // 0 for reorthogonalization against previous Lanczos vectors in groups; each group consists of
175  // v(i),v(i+1),...,v(j) with omega(i),omega(i+1),...,omega(j) all greater than eta, and
176  // there is v(k) with omega(k) > delta, i<=k<=j
177  // 1 for reorthogonalization against previous Lanczos vectors v(i) with omega(i) > eta
178  // 2 for reorthogonalization against previous Lanczos vectors in one group v(i),v(i+1),...,v(j) such that
179  // i is the smallest index for omega(i) > eta, and j is the largest index for omega(j) > eta
180  // 3 for reorthogonalization against all previous Lanczos vectors
181  // omega(i) is the estimated orthogonal error of v(i) against the previous Lanczos vectors v(1),...,v(i-1)
182  // by default, the value of eta is eps^(0.75) and the value of delta is eps^(0.5),
183  // where eps is the machine epsilon
184  // this parameter is effective only if reorth==1 (i.e. partial reorthogonalization)
187 
194  // set checkReorth=true for checking whether semi-orthogonality is preserved with partial reorthogonalization
195  // this is for verification purposes, and is expensive, comparable to full reorthogonalization
196  // therefore, checkReorth=true is not recommended for large problems
197  // by default, checkReorth==false
198  // this parameter is effective only with partial reorthogonalization (LanczosOptions::reorth==1 as input of LanczosEigenSolver())
201  // memoryExpansionFactor determines how much the memory should be expanded
202  // when the allocated memory is not sufficient to store the Lanczos vectors
203  // and the elements alpha's and beta's which form the symmetric tridiagonal matrix
205 
206  // cut points of eigenvalues
208 
210  // eigenvalues larger than eigLowCut in the lower end will not be computed
211  // this parameter is effective when eigPart is "SA" for smallest algebraic or when eigPart is "BE" for both ends
212  Real eigLowCut;
214 
216  // eigenvalues smaller than eigHighCut in the upper end will not be computed
217  // this parameter is effective when eigPart is "LA" for largest algebraic or when eigPart is "BE" for both ends
220 
241  // a flag which indicates how to sort eigenvalues (default -1):
242  // -2 for `don't sort'
243  // -1 for the default setting (2 for decreasing if eigPart[] is "LA"; 0 for increasing if eigPart[] is "SA"; 0 for increasing if eigPart[] is "BE")
244  // otherwise eigSort should be >= 0, in which case
245  // the first digit is 0 (or 1) for to sort the eigenvalues in the lower end in increasing (or decreasing) order
246  // the second digit is 0 (or 1) for to sort the eigenvalues in the higher end in increasing (or decreasing) order
247  // the third digit is 0 (or 1) for to list the eigenvalues in the lower end before (or after) those in the higher end
248  // Here eigPart[] is the input string of LanczosEigenSolver()
249  // note: when eigPart is "LA", the first and the third digits do not matter
250  // when eigPart is "SA", the second and the third digits do not matter
251  // when eigPart is "BE", set eigSort=0 (or 7) for eigenvalues sorted in increasing (or decreasing) order
252  int eigSort;
253 
255 
261  // diagnostic information display level 0, 1 or 2 (default 1)
262  // 0 means that no information will be displayed
263  // 1 means that basic information will be displayed
264  // 2 means that more information will be displayed
265  int disp;
267  // a pointer to an output stream for diagnostic information; by default, it points to std::cout
268  std::ostream *out;
270  // a pointer to an output stream for error messages; by default, it points to std::cerr
271  std::ostream *err;
272 
274  // a default constructor to set default options
276  // default options
277  wantEigVec = true;
278  minIter = 0; // 0 means that the default value will be set and used in LanczosEigenSolver
279  maxIter = 0; // 0 means that the default value will be set and used in LanczosEigenSolver
280  extraIter = 100; // extra number of iterations after convergence, to make sure no more eigenvalue to show up
281  stride = 10; // check convergence every `stride' iterations; if stride==0, it will be set as 10 in the routine LanczosEigenSolver
282 
283  defaultMinIterFactor = 5;
284  defaultMaxIterFactor = 50;
285 
286  // reorthogonalization parameters
287  reorth = 1; // 1 for partial reorthogonalization; 2 for full reorthogonalization
288  doubleReorthGamma = 1.0 / sqrt(2.0);
289  localReorthGamma = 1.0 / sqrt(2.0);
290  partialReorthStrategy = 2;
291  checkReorth = false;
292 
293  // memory expansion factor
294  memoryExpansionFactor = 1.2;
295 
296  // tolerance for convergence check
297  tol = pow(Basics::machineEpsilon, 4.0/5.0);
298 
299  // flag indicating how to sort the eigenvalues; see the description above
300  eigSort = -1;
301 
302  // diagnostic information display parameters
303  disp = 1;
304  #ifdef USE_MEX
305  out = &mexcout;
306  err = &mexcout;
307  #else
308  out = &std::cout;
309  err = &std::cerr;
310  #endif
311 
312  // cut points of eigenvalues
313  eigLowCut = Basics::infinity; // the default means no cut
314  eigHighCut = -Basics::infinity; // the default means no cut
315  }
316 };
317 
319 // LanczosEigenSolver() returns an instance of this class which gives the information of the Lanczos procedure
320 struct LanczosInfo {
322  // number of iterations performed in the Lanczos procedure
323  mkIndex numIter;
325  // CPU time (in total) for obtaining the next Krylov vector in each iteration, e.g. matrix-vector products
328  // CPU time (in total) for partial or full reorthogonalization
331  // CPU time (in total) for convergence check
334  // CPU time for obtaining eigenvectors, after the eigenvalues are obtained
337 
340  // CPU time for the whole Lanczos procedure,
341  // including convergence check and getting eigenvectors (if requested);
342  // this is the total CPU time for computing the eigenvalues / eigenvectors,
343  // excluding reading the data matrix and reporting the result
345 
347 
349  // maximum eigenvalue error
350  // the computation requires the eigenvectors, so this parameter is computed only if LanczosOptions::wantEigVec==true as the input of LanczosEigenSolver()
353 
355  // maximum relative eigenvalue error
356  // the computation requires the eigenvectors, so this parameter is computed only if LanczosOptions::wantEigVec==true as the input of LanczosEigenSolver()
358 
360  // memory (in bytes) required for the Lanczos iterations
362 
364 
366  // allEigenvaluesCheckedConverged is true if all eigenvalues are checked converged;
367  // otherwise, allEigenvaluesCheckedConverged is false, which means that the maximum number of Lanczos iterations is reached
369 
370  // reorthogonalization cost information
372  // number of iterations where reorthogonalization is performed
375  // total number of vectors against which the reorthogonalization is performed
378 
384  // the value is reorthVectorCount divided by the number of vectors reorthogonalized by full reorthogonalization without double reorthogonalization
385  // if no reorthogonalization (i.e. LanczosOptions::reorth==0 as input of LanczosEigenSolver()) is performed, then reorthVectorRate = 0.0
386  // if full reorthogonalization (i.e. LanczosOptions::reorth==2 as input of LanczosEigenSolver()) is performed without double reorthogonalization is performed, then reorthVectorRate = 1.0
387  // if partial reorthogonalization (i.e. LanczosOptions::reorth==1 as input of LanczosEigenSolver()) is performed, usually 0.0 < reorthVectorRate < 1.0
390  // number of iterations where reorthogonalization is doubled
393  // number of iterations where local reorthogonalization is performed
395 
397 
403  // maximum ratio of orthogonality level
406 
412  // minimum ratio of orthogonality level
414  // the above two parameters are computed only if the partial reorthogonalization is applied (i.e. LanczosOptions::reorth==1 as input of LanczosEigenSolver())
415  // let w0(i,j) be the inner product of the i-th and j-th Lanczos vectors and w0(j) = max{w0(i,j)|i<j}
416  // also let w(j) be the estimated upper bound of w0(j)
417  // then minOrthLevelRatio = min{ w0(j)/w(j) | 1<=j<=numIter }, and
418  // maxOrthLevelRatio = max{ w0(j)/w(j) | 1<=j<=numIter }
419 };
420 
423 
429 // the definition of a function /operator with input a vector and output a vector
430 // the operator should be self-adjoint in the Lanczos methods
431 // in a standard Lanczos or conjugate gradient procedure, the input is v and output is A*v;
432 // in a filtered Lanczos or conjugate gradient procedure, the input is v and output is p(A)*v, with p(z) a polynomial,
433 // where A is a symmetric matrix; it can be dense or sparse
434 typedef Vector (*NEXT_VECTOR)(const Vector&);
435 
437 
452 // Lanczos eigensolver, the most general form
453 // input:
454 // NextKrylovVector is the function which defines a self-adjoint operator, e.g. A*v with A a symmetric matrix
455 // n is the length of the input/output vectors of NextKrylovVector()
456 // neigWanted is the number of eigenvalues sought
457 // eigPart is a string "SA", "LA", or "BE"
458 // "LA" - largest algebraic, for largest eigenvalues
459 // "SA" - smallest algebraic, for smallest eigenvalues
460 // "BE" - both ends, one more from high end if nev is odd
461 // opts is a collection of Lanczos options
462 // output:
463 // eigVal is a vector of length neigWanted containing the computed eigenvalues
464 // eigVec is a matrix whose columns are eigenvectors, if opts.wantEigVec==true
465 // return:
466 // this routine returns an instance of LanczosInfo which gives the information of the Lanczos procedure
467 LanczosInfo LanczosEigenSolver(Vector &eigVal, Matrix &eigVec, NEXT_VECTOR NextKrylovVector, mkIndex n, mkIndex neigWanted, const char eigPart[], LanczosOptions &opts);
469 // the same as LanczosEigenSolver(), but with the default LanczosOptions
470 LanczosInfo LanczosEigenSolver(Vector &eigVal, Matrix &eigVec, NEXT_VECTOR NextKrylovVector, mkIndex n, mkIndex neigWanted, const char eigPart[]);
472 // the same as LanczosEigenSolver(), but with the NextKrylovVector() defined as A*v
473 LanczosInfo LanczosEigenSolver(Vector &eigVal, Matrix &eigVec, const SymmetricMatrix &A, mkIndex neigWanted, const char eigPart[], LanczosOptions &opts);
475 // the same as LanczosEigenSolver(), but with the NextKrylovVector() defined as A*v and with the default LanczosOptions
476 LanczosInfo LanczosEigenSolver(Vector &eigVal, Matrix &eigVec, const SymmetricMatrix &A, mkIndex neigWanted, const char eigPart[]);
478 // the same as LanczosEigenSolver(), but with the NextKrylovVector() defined as A*v
479 LanczosInfo LanczosEigenSolver(Vector &eigVal, Matrix &eigVec, const SparseMatrix &A, mkIndex neigWanted, const char eigPart[], LanczosOptions &opts);
481 // the same as LanczosEigenSolver(), but with the NextKrylovVector() defined as A*v and with the default LanczosOptions
482 LanczosInfo LanczosEigenSolver(Vector &eigVal, Matrix &eigVec, const SparseMatrix &A, mkIndex neigWanted, const char eigPart[]);
483  // end of group_laneig
485 
486 
487 #endif // end of #ifdef LANEIG_H
bool wantEigVec
This parameter tells whether eigenvectors are wanted or not (default true).
Definition: laneig.h:41
Real LanczosCpuTime
CPU time for the whole Lanczos procedure, including convergence check and getting eigenvectors (if re...
Definition: laneig.h:344
mkIndex numIter
Number of iterations performed in the Lanczos procedure.
Definition: laneig.h:323
int partialReorthStrategy
A flag to tell which partial reorthogonalization strategy is used. The value can be 0...
Definition: laneig.h:185
int eigSort
A flag which indicates how to sort eigenvalues (default -1). The value should be no less than -2...
Definition: laneig.h:252
Real convergenceCheckCpuTime
CPU time (in total) for convergence check.
Definition: laneig.h:332
Real localReorthGamma
Local reorthogonalization is performed if beta[j-1]<localReorthGamma*beta[j] or localReorthGamma>=1.0, where beta[j] is the latest beta and beta[j-1] is the previous beta at jth Lanczos iteration.
Definition: laneig.h:155
Real eigLowCut
Eigenvalues larger than eigLowCut in the lower end will not be computed.
Definition: laneig.h:212
Real maxRelativeEigenvalueError
Maximum relative eigenvalue error.
Definition: laneig.h:357
LanczosEigenSolver() returns an instance of this class which gives the information of the Lanczos pro...
Definition: laneig.h:320
Vector(* NEXT_VECTOR)(const Vector &)
Definition: laneig.h:434
mkIndex localReorthIterCount
Number of iterations where reorthogonalization is doubled.
Definition: laneig.h:391
Real forNextKrylovVectorCpuTime
CPU time (in total) for obtaining the next Krylov vector in each iteration, e.g. matrix-vector produc...
Definition: laneig.h:326
Real maxOrthLevelRatio
Maximum ratio of orthogonality level.
Definition: laneig.h:404
Real tol
Tolerance of eigenvalues, defined in the relative and average sense, for convergence check (default ...
Definition: laneig.h:105
An instance of this class, taken by LanczosEigenSolver(), is a collection of options for the Lanczos ...
Definition: laneig.h:33
Vector v0
The initial Lanczos vector.
Definition: laneig.h:113
Real forEigenVectorsCpuTime
CPU time for obtaining eigenvectors, after the eigenvalues are obtained.
Definition: laneig.h:335
int disp
Diagnostic information display level (default 1). The value can be 0,1,2.
Definition: laneig.h:265
Real eigHighCut
Eigenvalues smaller than eigHighCut in the upper end will not be computed.
Definition: laneig.h:218
std::ostream * out
A pointer to an output stream for diagnostic information. By default, it points to std::cout...
Definition: laneig.h:268
mkIndex defaultMaxIterFactor
The default LanczosOptions::maxIter, if not set, is 500 plus LanczosOptions::defaultMaxIterFactor tim...
Definition: laneig.h:102
mkIndex doubleReorthIterCount
Number of iterations where local reorthogonalization is performed.
Definition: laneig.h:394
LanczosInfo LanczosEigenSolver(Vector &eigVal, Matrix &eigVec, NEXT_VECTOR NextKrylovVector, mkIndex n, mkIndex neigWanted, const char eigPart[], LanczosOptions &opts)
Lanczos eigensolver, the most general form.
bool allEigenvaluesCheckedConverged
allEigenvaluesCheckedConverged is true if all eigenvalues are checked converged.
Definition: laneig.h:368
std::ostream * err
A pointer to an output stream for error messages. By default, it points to std::cerr.
Definition: laneig.h:271
mkIndex reorthIterCount
Number of iterations where reorthogonalization is performed.
Definition: laneig.h:373
mkIndex stride
The convergence is checked every ‘stride’ iterations (default 10).
Definition: laneig.h:90
mkIndex minIter
Minimum number of Lanczos iterations.
Definition: laneig.h:50
Real reorthogonalizationCpuTime
CPU time (in total) for partial or full reorthogonalization.
Definition: laneig.h:329
mkIndex extraIter
Extra number of Lanczos iterations (default 100).
Definition: laneig.h:87
Real memoryExpansionFactor
This parameter determines how much the memory should be expanded when the allocated memory is not suf...
Definition: laneig.h:204
mkIndex defaultMinIterFactor
The default LanczosOptions::minIter, if not set, is LanczosOptions::defaultMinIterFactor times the nu...
Definition: laneig.h:96
LanczosOptions()
A default constructor to set default options.
Definition: laneig.h:275
Real reorthVectorRate
The value is reorthVectorCount divided by the number of vectors reorthogonalized by full reorthogonal...
Definition: laneig.h:388
Real minOrthLevelRatio
Minimum ratio of orthogonality level.
Definition: laneig.h:413
mkIndex maxIter
Maximum number of Lanczos iterations.
Definition: laneig.h:59
Real maxEigenvalueError
Maximum eigenvalue error.
Definition: laneig.h:351
int reorth
A flag to tell which reorthogonalization scheme is used (default 1). The value can be 0...
Definition: laneig.h:127
mkIndex reorthVectorCount
Total number of vectors against which the reorthogonalization is performed.
Definition: laneig.h:376
bool checkReorth
Set checkReorth=true for checking whether semi-orthogonality is preserved with partial reorthogonaliz...
Definition: laneig.h:199
Real doubleReorthGamma
Reorthogonalization is doubled in the iterations with nrm < doubleReorthGamma*nrm_old, where nrm_old and nrm are the norms of the latest Lanczos vector before and after reorthogonalization.
Definition: laneig.h:143
mkIndex memoryForLanczosInBytes
Memory (in bytes) required for the Lanczos iterations.
Definition: laneig.h:361