MyraMath
rldlt2_partialsolve


Source: tests/multifrontal/rldlt/rldlt2_partialsolve.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>
19 
20 // Algorithms.
23 #include <myramath/dense/gemm.h>
26 
27 // Solver under test.
29 
30 // Reporting.
31 #include <tests/myratest.h>
32 
33 using namespace myra;
34 
35 namespace {
36 
37 template<class Precision> void test(int I, int J, Precision tolerance)
38  {
39  myra::out() << typestring<Precision>() << std::endl;
40  // Generate A.
41  int N = I*J;
42  SparseMatrix<Precision> A = laplacian2<Precision>(I,J);
43  Precision shift = 5.5;
44  for (int n = 0; n < N; ++n)
45  A(n,n) -= shift;
46  // Options related to reordering. Test input is small, so need to use small
47  // blocks/no globbing to make sure the symbolic factorization is nontrivial
48  typedef multifrontal::Options Options;
49  Options options = Options::create().set_blocksize(8).set_globsize(4).set_nthreads(1);
50  // Reorder A using bisection and factor it.
51  Permutation perm = bisect2(I,J);
52  SparseRLDLTSolver<Precision> solver(A,perm,options);
53  // Make random restriction Ri.
54  std::vector<int> Ri(20,0);
55  for (int i = 0; i < Ri.size(); ++i)
56  Ri[i] = random_int(N);
57  sortunique(Ri);
58  // Make random restriction Rj.
59  std::vector<int> Rj(30,0);
60  for (int j = 0; j < Rj.size(); ++j)
61  Rj[j] = random_int(N);
62  sortunique(Rj);
63  // Form restricted inverse Z = Ri'inv(A)*Rj
64  Matrix<Precision> Z = solver.inverse(Ri,Rj);
65  int K = 15;
66  // Test from the left.
67  {
68  auto B1 = Matrix<Precision>::random(ssize(Rj),K);
69  auto B2 = Matrix<Precision>::random(ssize(Ri),K);
70  Precision error_N = frobenius( gemm(Z,'N',B1) - solver.partialsolve(Ri,Rj,B1,'L','N') );
71  Precision error_T = frobenius( gemm(Z,'T',B2) - solver.partialsolve(Ri,Rj,B2,'L','T') );
72  Precision error_H = frobenius( gemm(Z,'H',B2) - solver.partialsolve(Ri,Rj,B2,'L','H') );
73  Precision error_C = frobenius( gemm(Z,'C',B1) - solver.partialsolve(Ri,Rj,B1,'L','C') );
74  myra::out() << " error in Z^N * B = " << error_N << std::endl;
75  myra::out() << " error in Z^T * B = " << error_T << std::endl;
76  myra::out() << " error in Z^H * B = " << error_H << std::endl;
77  myra::out() << " error in Z^C * B = " << error_C << std::endl;
78  REQUIRE(error_N < tolerance);
79  REQUIRE(error_T < tolerance);
80  REQUIRE(error_H < tolerance);
81  REQUIRE(error_C < tolerance);
82  }
83  // Test from the right.
84  {
85  auto B1 = Matrix<Precision>::random(K,ssize(Ri));
86  auto B2 = Matrix<Precision>::random(K,ssize(Rj));
87  Precision error_N = frobenius( gemm(B1,Z,'N') - solver.partialsolve(Ri,Rj,B1,'R','N') );
88  Precision error_T = frobenius( gemm(B2,Z,'T') - solver.partialsolve(Ri,Rj,B2,'R','T') );
89  Precision error_H = frobenius( gemm(B2,Z,'H') - solver.partialsolve(Ri,Rj,B2,'R','H') );
90  Precision error_C = frobenius( gemm(B1,Z,'C') - solver.partialsolve(Ri,Rj,B1,'R','C') );
91  myra::out() << " error in B * Z^N = " << error_N << std::endl;
92  myra::out() << " error in B * Z^T = " << error_T << std::endl;
93  myra::out() << " error in B * Z^H = " << error_H << std::endl;
94  myra::out() << " error in B * Z^C = " << error_C << std::endl;
95  REQUIRE(error_N < tolerance);
96  REQUIRE(error_T < tolerance);
97  REQUIRE(error_H < tolerance);
98  REQUIRE(error_C < tolerance);
99  }
100  }
101 
102 } // namespace
103 
104 ADD_TEST("rldlt2_partialsolve","[multifrontal][parallel]")
105  { test<double>(20,20,1.0e-8); }
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
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
Sparse direct solver suitable for real symmetric indefinite systems.
Definition: SparseRLDLTSolver.h:61
Reduces a std::vector to its unique entries, and sorts it.
General purpose compressed-sparse-column (CSC) container.
void sortunique(std::vector< T > &v)
Reduces a std::vector to its unique entries, and sorts it.
Definition: sortunique.h:20
Definition: syntax.dox:1
Various utility functions/classes related to scalar Number types.
General purpose dense matrix container, O(i*j) storage.
Aggregates a (perm, iperm, swaps) triple into a vocabulary type.
Simplistic random number functions.
Sparse direct solver suitable for real symmetric indefinite systems.
Stores an IxJ matrix A in compressed sparse column format.
Definition: bothcat.h:23
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
error in Z^N * B = 1.03766e-13
error in Z^T * B = 1.22516e-13
error in Z^H * B = 1.22516e-13
error in Z^C * B = 1.03766e-13
error in B * Z^N = 1.19607e-13
error in B * Z^T = 1.27355e-13
error in B * Z^H = 1.27355e-13
error in B * Z^C = 1.19607e-13


Go back to Summary of /test programs.