MyraMath
sparse_gemv


Source: tests/sparse/gemv.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.
12 #include <myramath/dense/Vector.h>
14 #include <myramath/dense/Matrix.h>
18 
19 // Algorithms.
20 #include <myramath/sparse/gemv.h>
21 #include <myramath/dense/gemv.h>
23 
24 // Reporting.
25 #include <tests/myratest.h>
26 
27 using namespace myra;
28 
29 namespace {
30 
31 template<class Number> void test(int I, int J, int N, typename ReflectPrecision<Number>::type tolerance)
32  {
33  myra::out() << typestring<Number>() << std::endl;
34  typedef typename ReflectPrecision<Number>::type Precision;
35  Number one(1);
36  Number zero(0);
37  // Make random sparse A operand.
38  auto A = SparseMatrix<Number>::random(I,J,N);
39  // Walk every possible combination of op.
40  std::vector<char> ops;
41  ops.push_back('N');
42  ops.push_back('T');
43  ops.push_back('H');
44  ops.push_back('C');
45  // Tests with the SparseMatrix appearing on the 'L'eft ..
46  for (int o = 0; o < ops.size(); ++o)
47  {
48  char op = ops[0];
49  // Deduce size of b operand.
50  std::pair<int,int> A_size(I,J);
51  if (op == 'T' || op == 'H')
52  std::swap(A_size.first, A_size.second);
53  int b_size = A_size.second;
54  // Construct random b operand of given size.
55  auto b = Vector<Number>::random(b_size);
56  // Generate c = op(A)*b, sparsely and densely.
57  Vector<Number> c1 = gemv(A,op,b);
58  Vector<Number> c2 = gemv(A.make_Matrix(),op,b);
59  // Check error between the two.
60  Precision error = frobenius(c1-c2);
61  myra::out() << " |A^" << op << "*b [sparse*vector]| = " << error << std::endl;
62  REQUIRE(error < tolerance);
63  }
64  // Tests with the SparseMatrix appearing on the 'R'ight ..
65  for (int o = 0; o < ops.size(); ++o)
66  {
67  char op = ops[0];
68  // Deduce size of b operand.
69  std::pair<int,int> A_size(I,J);
70  if (op == 'T' || op == 'H')
71  std::swap(A_size.first, A_size.second);
72  int b_size = A_size.first;
73  // Construct random b operand of given size.
74  auto b = Vector<Number>::random(b_size);
75  // Generate C = b*op(A), sparsely and densely.
76  Vector<Number> c1 = gemv(b,A,op);
77  Vector<Number> c2 = gemv(b,A.make_Matrix(),op);
78  Precision error = frobenius(c1-c2);
79  myra::out() << " |b*A^" << op << " [vector*sparse]| = " << error << std::endl;
80  REQUIRE(error < tolerance);
81  }
82  }
83 
84 } // namespace
85 
86 ADD_TEST("sparse_gemv","[sparse]")
87  {
88  test< float >(15,10,40,1.0e-4f);
89  test< double >(15,10,40,1.0e-9);
90  test< std::complex<float > >(15,10,40,1.0e-4f);
91  test< std::complex<double> >(15,10,40,1.0e-9);
92  }
Interface class for representing subranges of dense Matrix&#39;s.
Interface class for representing subranges of dense Vector&#39;s.
Routines for computing Frobenius norms of various algebraic containers.
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.
Variety of routines all for dense Matrix*Vector multiplies. All just delegate to gemm() ...
static Vector< Number > random(int N)
Generates a random Vector of specified size.
Definition: Vector.cpp:276
Definition: syntax.dox:1
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) ...
Reflects Precision trait for a Number, scalar Number types should specialize it.
Definition: Number.h:33
Range/Iterator types associated with SparseMatrix.


Results: [PASS]

float
|A^N*b [sparse*vector]| = 6.83872e-08
|A^N*b [sparse*vector]| = 3.72529e-09
|A^N*b [sparse*vector]| = 1.46191e-07
|A^N*b [sparse*vector]| = 1.62058e-07
|b*A^N [vector*sparse]| = 1.8193e-07
|b*A^N [vector*sparse]| = 8.59293e-08
|b*A^N [vector*sparse]| = 1.06354e-07
|b*A^N [vector*sparse]| = 1.35149e-07
double
|A^N*b [sparse*vector]| = 2.75118e-16
|A^N*b [sparse*vector]| = 1.33111e-16
|A^N*b [sparse*vector]| = 7.85046e-17
|A^N*b [sparse*vector]| = 2.77556e-17
|b*A^N [vector*sparse]| = 0
|b*A^N [vector*sparse]| = 2.31909e-16
|b*A^N [vector*sparse]| = 2.22478e-16
|b*A^N [vector*sparse]| = 1.30923e-16
std::complex<float>
|A^N*b [sparse*vector]| = 2.76777e-07
|A^N*b [sparse*vector]| = 2.43943e-07
|A^N*b [sparse*vector]| = 2.60877e-07
|A^N*b [sparse*vector]| = 1.51963e-07
|b*A^N [vector*sparse]| = 2.93897e-07
|b*A^N [vector*sparse]| = 3.14693e-07
|b*A^N [vector*sparse]| = 2.28552e-07
|b*A^N [vector*sparse]| = 2.22022e-07
std::complex<double>
|A^N*b [sparse*vector]| = 5.69254e-16
|A^N*b [sparse*vector]| = 3.67434e-16
|A^N*b [sparse*vector]| = 3.98367e-16
|A^N*b [sparse*vector]| = 4.78331e-16
|b*A^N [vector*sparse]| = 4.91046e-16
|b*A^N [vector*sparse]| = 2.8441e-16
|b*A^N [vector*sparse]| = 3.49503e-16
|b*A^N [vector*sparse]| = 5.2461e-16


Go back to Summary of /test programs.