MyraMath
lu2_inverse


Source: tests/multifrontal/lu/lu2_inverse.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.
14 #include <myramath/dense/Matrix.h>
21 
22 // Algorithms.
24 #include <myramath/dense/gemm.h>
25 #include <myramath/dense/inverse.h>
28 
29 // Solver under test.
31 
32 // Reporting.
33 #include <myramath/utility/Timer.h>
34 #include <tests/myratest.h>
35 
36 using namespace myra;
37 
38 namespace {
39 
40 template<class Number> void test(int I, int J, typename ReflectPrecision<Number>::type tolerance)
41  {
42  typedef typename ReflectPrecision<Number>::type Precision;
43  myra::out() << typestring<Number>() << std::endl;
44  // Generate A.
45  int N = I*J;
46  Pattern P = stencil2(I,J);
47  auto A = SparseMatrix<Number>::random(P);
48  // Options related to reordering. Test input is small, so need to use small
49  // blocks/no globbing to make sure the symbolic factorization is nontrivial
50  typedef multifrontal::Options Options;
51  Options options = Options::create().set_blocksize(4).set_globsize(4).set_nthreads(4);
52  // Reorder A using bisection and factor it.
53  Permutation perm = bisect2(I,J);
54  SparseLUSolver<Number> solver(A,perm,options);
55  // Compute inverse of A explicitly, for reference.
56  Matrix<Number> Z = inverse(A.make_Matrix());
57  // Compare to solver.inverse(i,j) for each nonzero original pattern.
58  {
59  Precision error = 0;
60  for (int j = 0; j < N; ++j)
61  {
62  std::vector<int> Pj = P.pattern(j);
63  for (auto i = Pj.begin(); i != Pj.end(); ++i)
64  {
65  Number Zij = solver.inverse(*i,j);
66  Precision error_ij = scalar_norm1(Z(*i,j)-Zij);
67  if (error_ij > error)
68  error = error_ij;
69  }
70  }
71  myra::out() << " |solver.inverse(i,j)| = " << error << std::endl;
72  REQUIRE(error < tolerance);
73  }
74  // Check the inverse over some arbitrary 20x20 tensor block.
75  {
76  int i0 = 5; int i1 = 25;
77  int j0 = 27; int j1 = 47;
78  std::vector<int> i = ilinspace(i0,i1);
79  std::vector<int> j = ilinspace(j0,j1);
80  Matrix<Number> Z_block = solver.inverse(i,j,options);
81  Precision error = frobenius(Z_block - Z.window(i0,i1,j0,j1)) / frobenius(Z_block);
82  myra::out() << " |solver.inverse(i_indices,j_indices)| = " << error << std::endl;
83  REQUIRE(error < tolerance);
84  }
85  }
86 } // namespace
87 
88 ADD_TEST("lu2_inverse","[multifrontal][parallel]")
89  {
90  int I = 10;
91  int J = 10;
92  test<NumberD>(I,J,1.0e-10);
93  test<NumberZ>(I,J,1.0e-10);
94  }
Interface class for representing subranges of dense Matrix&#39;s.
Options pack for routines in /multifrontal.
Definition: Options.h:24
Represents a Permutation matrix, used to reorder rows/columns/etc of various numeric containers...
Definition: Permutation.h:34
Tabulates an IxJ matrix. Allows random access, has column major layout to be compatible with BLAS/LAP...
Definition: bdsqr.h:20
Routines for computing Frobenius norms of various algebraic containers.
Simplistic timing class, might dispatch to platform specific timers depending upon environment...
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
std::vector< int > pattern(int j) const
Returns the (sorted) nonzero pattern of A(:,j)
Definition: Pattern.cpp:157
General purpose compressed-sparse-column (CSC) container.
Definition: syntax.dox:1
CMatrixRange< Number > window(int i0, int i1, int j0, int j1) const
Returns a MatrixRange over this(i0:i1,j0:j1)
Definition: Matrix.cpp:142
Various utility functions/classes related to scalar Number types.
Sparse direct solver suitable for symmetric-pattern nonsymmetric-value A.
Returns a vector of int&#39;s, over [min,max)
General purpose dense matrix container, O(i*j) storage.
Range/Iterator types associated with Pattern.
Sparse direct solver suitable for symmetric-pattern nonsymmetric-valued A.
Definition: SparseLUSolver.h:57
Holds the nonzero pattern of a sparse matrix.
Definition: Pattern.h:55
Reflects Precision trait for a Number, scalar Number types should specialize it.
Definition: Number.h:33
Container class for a sparse nonzero pattern, used in reordering/symbolic analysis.
Overwrites a LowerMatrix, DiagonalMatrix, or square Matrix with its own inverse. Or, returns it as a copy.
Aggregates a (perm, iperm, swaps) triple into a vocabulary type.
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.
Range/Iterator types associated with SparseMatrix.
Interface class for representing subranges of contiguous int&#39;s.


Results: [PASS]

double
|solver.inverse(i,j)| = 5.86198e-13
|solver.inverse(i_indices,j_indices)| = 3.15979e-14
std::complex<double>
|solver.inverse(i,j)| = 9.56597e-15
|solver.inverse(i_indices,j_indices)| = 2.3699e-15


Go back to Summary of /test programs.