MyraMath
lopcg


Source: tests/iterative/lopcg.cpp

1 // ========================================================================= //
2 // This file is part of MyraMath, copyright (c) 2014-2019 by Ryan A Chilton //
3 // and distributed by MyraCore, LLC. See LICENSE.txt for license terms. //
4 // ========================================================================= //
5 
11 // Containers.
13 #include <myramath/dense/Matrix.h>
14 #include <myramath/dense/Vector.h>
22 
23 // Algorithms.
24 #include <myramath/dense/gemm.h>
25 #include <myramath/dense/dimm.h>
28 #include <myramath/sparse/gemm.h>
29 #include <myramath/sparse/gemv.h>
32 
33 // Iterative solve/action stuff.
39 
40 // Reporting.
42 #include <tests/myratest.h>
43 
44 using namespace myra;
45 using namespace myra_stlprint;
46 
47 namespace {
48 
49 template<class Precision> void test(int X, int Y)
50  {
51  myra::out() << typestring<Precision>() << std::endl;
52  int N = X*Y;
53  // Construct laplacian, shift it by 10^-3 to make it positive.
54  auto A = laplacian2<Precision>(X,Y);
55  Precision one(1);
56  Precision ten(10);
57  Precision sigma = std::pow(ten,-3);
58  for (int n = 0; n < N; ++n)
59  A(n,n) = A(n,n) - one + sigma;
60  A *= one /frobenius(A);
61  // Form action for A.
62  auto A_action = make_GemmAction(A);
63  // Form incomplete cholesky preconditioner, M.
65  auto M_action = make_SolveAction(M);
66  // Form the (unwanted) constant eigenvector, will be deflated out.
67  auto Q = Matrix<Precision>::ones(N,1);
68  normalize(Q.range().vector(0));
69  // Generate one eigenpair.
70  auto v_mu = lopcg1(M_action,A_action,Q);
71  Vector<Precision>& v = v_mu.first;
72  Precision lambda = Precision(1)/v_mu.second;
73  // Check residual, A*v - v*lambda
74  Vector<Precision> r = A*v-v*lambda;
75  Precision r_error = frobenius(r);
76  myra::out() << " |A*v - v*lambda| = " << r_error << std::endl;
77  REQUIRE(r_error < 1.0e-3);
78  // Generate 3 eigenpairs
79  int size = 3;
80  auto V_Mu = lopcgN(M_action,A_action,Q,size);
81  Matrix<Precision>& V = V_Mu.first;
82  DiagonalMatrix<Precision> Lambda = V_Mu.second;
83  for (int ij = 0; ij < size; ++ij)
84  Lambda(ij) = Precision(1) / Lambda(ij);
85  // Check residual, A*V - V*Lambda
86  Matrix<Precision> R = A*V - V*Lambda;
87  Precision R_error = frobenius(R);
88  // Check orthogonality V'V-I
89  auto I = Matrix<Precision>::identity(size);
90  Precision I_error = frobenius(gemm(V,'T',V,'N')-I);
91  myra::out() << " |A*V - V*Lambda| = " << R_error << std::endl;
92  myra::out() << " |V'V - I| = " << R_error << std::endl;
93  myra::out() << " Mu = " << V_Mu.second.range() << std::endl;
94  REQUIRE(R_error < 1.0e-3);
95  REQUIRE(I_error < 1.0e-3);
96  }
97 
98 } // namespace
99 
100 ADD_TEST("lopcg","[iterative]")
101  {
102  // Test on square laplacian (degenerate, then 2:1 gap)
103  test<double>(32,32);
104  test<float >(32,32);
105  // Test on a squarish laplacian (near degenerate, then 2:1 gap)
106  test<double>(32,31);
107  test<double>(32,16);
108  // Test on a 2:1 laplacian (looking for 4:1 gap)
109  test<float >(32,31);
110  test<float >(32,16);
111  }
Routines for computing euclidean norm of a Vector/VectorRange, or normalizing a Vector/VectorRange to...
Interface class for representing subranges of DiagonalMatrix&#39;s.
Interface class for representing subranges of dense Matrix&#39;s.
Interface class for representing subranges of dense Vector&#39;s.
Applies the "Action" of a linear operator, b := A*x, used in iterative solution algorithms.
Finds several small eigenpairs of a real symmetric Action.
Variety of routines for mixed dense*sparse or dense*sparse matrix multiplies. The dense*dense case is...
Routines for computing Frobenius norms of various algebraic containers.
Routines for multiplying by a DiagonalMatrix.
General purpose compressed-sparse-column (CSC) container.
Definition: syntax.dox:1
CVectorRange< Number > first(int n) const
Returns a VectorRange over the first n entries, this(0:n)
Definition: Vector.cpp:192
Definition: stlprint.h:32
Action< typename ReflectNumber< Solver >::type > make_SolveAction(const Solver &solver, char op='N')
Free function for making SolveAction&#39;s.
Definition: SolveAction.h:67
Routines for printing the contents of various std::container&#39;s to a std::ostream using operator <<...
Various utility functions/classes related to scalar Number types.
static Matrix< Number > identity(int IJ)
Generates an identity Matrix of specified size.
Definition: Matrix.cpp:349
Signatures for sparse matrix * dense vector multiplies. All delegate to gemm() under the hood...
General purpose dense matrix container, O(i*j) storage.
Tabulates a vector of length N, allows random access.
Definition: conjugate.h:21
Container for either a column vector or row vector (depends upon the usage context) ...
Finds one small eigenpair of a real symmetric Action.
static Matrix< Number > ones(int I, int J)
Generates a ones Matrix of specified size.
Definition: Matrix.cpp:361
Adapts a class with a .solve() method into an Action.
An Action for multiplying by a dense Matrix or SparseMatrix using gemm().
Returns frobenius norm of a SparseMatrix.
Container for a diagonal matrix, O(n) storage. Used by SVD, row/column scaling, etc.
Incompletely factors A ~= L*L&#39;, presents approximate solve() method.
Definition: ICholeskySolver.h:28
Helper routines for reordering/filling 2D structured grids. Used by many unit tests.
Variety of routines all for dense Matrix*Matrix multiplies. Delegates to the BLAS.
Incomplete Cholesky preconditioner. Presents a solve() function, but it&#39;s only approximate.
Range/Iterator types associated with SparseMatrix.


Results: [PASS]

double
|A*v - v*lambda| = 2.82036e-08
|A*V - V*Lambda| = 5.71556e-08
|V'V - I| = 5.71556e-08
Mu = size 3 DiagonalMatrix of double: [ 13126.5 13126.5 6887.18 ]
float
|A*v - v*lambda| = 6.89423e-05
|A*V - V*Lambda| = 0.000183611
|V'V - I| = 0.000183611
Mu = size 3 DiagonalMatrix of float: [ 13124.8 9546.3 6899.35 ]
double
|A*v - v*lambda| = 1.68718e-06
|A*V - V*Lambda| = 6.89533e-08
|V'V - I| = 6.89533e-08
Mu = size 3 DiagonalMatrix of double: [ 12914.4 12191 6571.3 ]
double
|A*v - v*lambda| = 4.84616e-08
|A*V - V*Lambda| = 1.53363e-07
|V'V - I| = 1.53363e-07
Mu = size 3 DiagonalMatrix of double: [ 9160.9 2469.86 2469.86 ]
float
|A*v - v*lambda| = 3.80715e-05
|A*V - V*Lambda| = 0.000146797
|V'V - I| = 0.000146797
Mu = size 3 DiagonalMatrix of float: [ 11584.7 10065.8 7610.83 ]
float
|A*v - v*lambda| = 4.17571e-06
|A*V - V*Lambda| = 1.36859e-05
|V'V - I| = 1.36859e-05
Mu = size 3 DiagonalMatrix of float: [ 9160.15 2469.8 2469.76 ]


Go back to Summary of /test programs.