MyraMath
SymmAction


Source: tests/iterative/SymmAction.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>
17 
18 // Algorithms.
20 #include <myramath/dense/gemm.h>
23 #include <myramath/sparse/gemm.h>
25 
26 // Iterative solve/action stuff.
29 
30 // Reporting.
31 #include <tests/myratest.h>
32 
33 using namespace myra;
34 
35 namespace {
36 
37 // Test make_SymmAction() for a CMatrixRange
38 template<class Number> void test1(int IJ, int K, typename ReflectPrecision<Number>::type tolerance)
39  {
40  myra::out() << typestring<Number>() << std::endl;
41  typedef typename ReflectPrecision<Number>::type Precision;
42  // Make a random symmetric Matrix A, wrap it up into a SymmAction
43  auto A = Matrix<Number>::random(IJ,IJ);
44  A = A + transpose(A);
45  auto action = make_SymmAction(A);
46  // Check action.make_Matrix()
47  {
48  Precision error = frobenius(action.make_Matrix()-A);
49  myra::out() << " |A(action) - A(dense)| = " << error << std::endl;
50  REQUIRE(error < tolerance);
51  }
52  // Check A_action.multiply(X,B)
53  {
54  auto X = Matrix<Number>::random(IJ,K);
55  auto B = Matrix<Number>::zeros(IJ,K);
56  action.multiply(X,B);
57  Precision error = frobenius(A*X-B);
58  myra::out() << " |A*X - B| = " << error << std::endl;
59  REQUIRE(error < tolerance);
60  }
61  // Check A_action.multiply(X,B,alpha,beta)
62  {
63  auto X = Matrix<Number>::random(IJ,K);
64  auto B = Matrix<Number>::random(IJ,K);
65  auto alpha = random<Number>();
66  auto beta = random<Number>();
67  auto C = alpha*A*X + beta*B;
68  action.multiply(X,B,alpha,beta);
69  Precision error = frobenius(B-C);
70  myra::out() << " | (alpha*A*X+beta*B)[action] - (alpha*A*X+beta*B)[dense] | = " << error << std::endl;
71  REQUIRE(error < tolerance);
72  }
73  }
74 
75 // Test make_SymmAction() for a CSparseMatrixRange
76 template<class Number> void test2(int IJ, int N, int K, typename ReflectPrecision<Number>::type tolerance)
77  {
78  myra::out() << typestring<Number>() << std::endl;
79  typedef typename ReflectPrecision<Number>::type Precision;
80  // Make a random symmetric SparseMatrix A, wrap it up into a SymmAction
81  auto A = SparseMatrix<Number>::random(IJ,IJ,N);
82  A = A + transpose(A);
83  auto action = make_SymmAction(A);
84  // Check action.make_Matrix()
85  {
86  Precision error = frobenius(action.make_Matrix()-A.make_Matrix());
87  myra::out() << " |A(action) - A(dense)| = " << error << std::endl;
88  REQUIRE(error < tolerance);
89  }
90  // Check A_action.multiply(X,B)
91  {
92  auto X = Matrix<Number>::random(IJ,K);
93  auto B = Matrix<Number>::zeros(IJ,K);
94  action.multiply(X,B);
95  Precision error = frobenius(A*X-B);
96  myra::out() << " |A*X - B| = " << error << std::endl;
97  REQUIRE(error < tolerance);
98  }
99  // Check A_action.multiply(X,B,alpha,beta)
100  {
101  auto X = Matrix<Number>::random(IJ,K);
102  auto B = Matrix<Number>::random(IJ,K);
103  auto alpha = random<Number>();
104  auto beta = random<Number>();
105  auto C = alpha*A*X + beta*B;
106  action.multiply(X,B,alpha,beta);
107  Precision error = frobenius(B-C);
108  myra::out() << " | (alpha*A*X+beta*B)[action] - (alpha*A*X+beta*B)[sparse] | = " << error << std::endl;
109  REQUIRE(error < tolerance);
110  }
111  }
112 
113 } // namespace
114 
115 ADD_TEST("SymmAction","[iterative]")
116  {
117  // Test dense make_SymmAction()
118  int IJ = 10;
119  int K = 7;
120  test1<NumberS>(IJ,K,1.0e-4f);
121  test1<NumberD>(IJ,K,1.0e-12);
122  test1<NumberC>(IJ,K,1.0e-4f);
123  test1<NumberZ>(IJ,K,1.0e-12);
124  // Test sparse make_SymmAction()
125  int N = 20;
126  test2<NumberS>(IJ,N,K,1.0e-4f);
127  test2<NumberD>(IJ,N,K,1.0e-12);
128  test2<NumberC>(IJ,N,K,1.0e-4f);
129  test2<NumberZ>(IJ,N,K,1.0e-12);
130  }
Returns a transposed copy of a SparseMatrix.
Interface class for representing subranges of dense Matrix&#39;s.
Applies the "Action" of a linear operator, b := A*x, used in iterative solution algorithms.
Variety of routines for mixed dense*sparse or dense*sparse matrix multiplies. The dense*dense case is...
static Matrix< Number > zeros(int I, int J)
Generates a zeros Matrix of specified size.
Definition: Matrix.cpp:357
Routines for computing Frobenius norms of various algebraic containers.
static Matrix< Number > random(int I, int J)
Generates a random Matrix of specified size.
Definition: Matrix.cpp:353
static SparseMatrix< Number > random(int I, int J, int N)
Generates a random SparseMatrix with size IxJ and (approximately) N nonzeros.
Definition: SparseMatrix.cpp:493
General purpose compressed-sparse-column (CSC) container.
Definition: syntax.dox:1
An Action for multiplying by a symmetric dense Matrix. LowerMatrix or SparseMatrix using symm() ...
Returns a transposed copy of a Matrix. The inplace version only works on a square operand...
Various utility functions/classes related to scalar Number types.
General purpose dense matrix container, O(i*j) storage.
Reflects Precision trait for a Number, scalar Number types should specialize it.
Definition: Number.h:33
Simplistic random number functions.
Variety of routines all for dense Matrix*Matrix multiplies. Delegates to the BLAS.
Range/Iterator types associated with SparseMatrix.


Results: [PASS]

float
|A(action) - A(dense)| = 0
|A*X - B| = 6.97664e-07
| (alpha*A*X+beta*B)[action] - (alpha*A*X+beta*B)[dense] | = 8.91215e-08
double
|A(action) - A(dense)| = 0
|A*X - B| = 1.09628e-15
| (alpha*A*X+beta*B)[action] - (alpha*A*X+beta*B)[dense] | = 1.42849e-15
std::complex<float>
|A(action) - A(dense)| = 0
|A*X - B| = 2.53684e-06
| (alpha*A*X+beta*B)[action] - (alpha*A*X+beta*B)[dense] | = 2.4389e-06
std::complex<double>
|A(action) - A(dense)| = 0
|A*X - B| = 4.98497e-15
| (alpha*A*X+beta*B)[action] - (alpha*A*X+beta*B)[dense] | = 2.66469e-15
float
|A(action) - A(dense)| = 0
|A*X - B| = 0
| (alpha*A*X+beta*B)[action] - (alpha*A*X+beta*B)[sparse] | = 1.23241e-07
double
|A(action) - A(dense)| = 0
|A*X - B| = 0
| (alpha*A*X+beta*B)[action] - (alpha*A*X+beta*B)[sparse] | = 3.97415e-16
std::complex<float>
|A(action) - A(dense)| = 0
|A*X - B| = 0
| (alpha*A*X+beta*B)[action] - (alpha*A*X+beta*B)[sparse] | = 5.69568e-07
std::complex<double>
|A(action) - A(dense)| = 0
|A*X - B| = 0
| (alpha*A*X+beta*B)[action] - (alpha*A*X+beta*B)[sparse] | = 4.30113e-16


Go back to Summary of /test programs.