MyraMath
SolveAction


Source: tests/iterative/SolveAction.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>
16 
17 // Algorithms.
19 #include <myramath/dense/gemm.h>
20 #include <myramath/dense/inverse.h>
22 
23 // Iterative solve/action stuff.
26 
27 // Reporting.
28 #include <tests/myratest.h>
29 
30 using namespace myra;
31 
32 namespace {
33 
34 template<class Number> void test(int I, int J, typename ReflectPrecision<Number>::type tolerance)
35  {
36  myra::out() << typestring<Number>() << std::endl;
37  typedef typename ReflectPrecision<Number>::type Precision;
38  // Make a random Matrix A..
39  auto A = Matrix<Number>::random(I,I);
40  // .. generate an LUSolver for it
41  typedef LUSolver<Number> Solver;
42  Solver solver(A.add_const());
43  // .. wrap that up into a make_SolveAction()
44  auto action = make_SolveAction(solver);
45  // Check action.make_Matrix() - should be same as inverse(A)
46  {
47  Precision error = frobenius(action.make_Matrix()-inverse(A));
48  myra::out() << " |action.make_Matrix() - inv(A)| = " << error << std::endl;
49  REQUIRE(error < tolerance);
50  }
51  // Check action.multiply(X,B)
52  {
53  auto X = Matrix<Number>::random(I,J);
54  auto B = Matrix<Number>::zeros(I,J);
55  action.multiply(X,B);
56  Precision error = frobenius(inverse(A)*X-B);
57  myra::out() << " |inv(A)*X - B| = " << error << std::endl;
58  REQUIRE(error < tolerance);
59  }
60  // Check action.multiply(X,B,alpha,beta)
61  {
62  auto X = Matrix<Number>::random(I,J);
63  auto B = Matrix<Number>::random(I,J);
64  auto alpha = random<Number>();
65  auto beta = random<Number>();
66  auto C = alpha*inverse(A)*X + beta*B;
67  action.multiply(X,B,alpha,beta);
68  Precision error = frobenius(B-C);
69  myra::out() << " | (alpha*inv(A)*X+beta*B)[action] - (alpha*inv(A)*X+beta*B)[matrix] | = " << error << std::endl;
70  REQUIRE(error < tolerance);
71  }
72  }
73 
74 } // namespace
75 
76 ADD_TEST("SolveAction","[iterative]")
77  {
78  int I = 10;
79  int J = 5;
80  test<NumberS>(I,J,1.0e-4f);
81  test<NumberD>(I,J,1.0e-12);
82  test<NumberC>(I,J,1.0e-4f);
83  test<NumberZ>(I,J,1.0e-12);
84  }
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.
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
Definition: syntax.dox:1
Action< typename ReflectNumber< Solver >::type > make_SolveAction(const Solver &solver, char op='N')
Free function for making SolveAction&#39;s.
Definition: SolveAction.h:67
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
General purpose linear solver, no symmetry/definiteness assumptions upon A (just square) ...
Overwrites a LowerMatrix, DiagonalMatrix, or square Matrix with its own inverse. Or, returns it as a copy.
Adapts a class with a .solve() method into an Action.
Factors a square matrix A into L*U, presents solve methods.
Definition: LUSolver.h:30
Simplistic random number functions.
Variety of routines all for dense Matrix*Matrix multiplies. Delegates to the BLAS.


Results: [PASS]

float
|action.make_Matrix() - inv(A)| = 0
|inv(A)*X - B| = 2.22223e-06
| (alpha*inv(A)*X+beta*B)[action] - (alpha*inv(A)*X+beta*B)[matrix] | = 1.48848e-06
double
|action.make_Matrix() - inv(A)| = 0
|inv(A)*X - B| = 2.5947e-15
| (alpha*inv(A)*X+beta*B)[action] - (alpha*inv(A)*X+beta*B)[matrix] | = 2.38859e-15
std::complex<float>
|action.make_Matrix() - inv(A)| = 1.71119e-06
|inv(A)*X - B| = 3.2866e-06
| (alpha*inv(A)*X+beta*B)[action] - (alpha*inv(A)*X+beta*B)[matrix] | = 9.03918e-07
std::complex<double>
|action.make_Matrix() - inv(A)| = 4.64566e-15
|inv(A)*X - B| = 8.59021e-15
| (alpha*inv(A)*X+beta*B)[action] - (alpha*inv(A)*X+beta*B)[matrix] | = 2.89178e-15


Go back to Summary of /test programs.