MyraMath
zldlh2_partialsolve


Source: tests/multifrontal/zldlh/zldlh2_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 #include <myramath/sparse/phasor.h>
27 
28 // Solver under test.
30 
31 // Reporting.
32 #include <tests/myratest.h>
33 
34 using namespace myra;
35 
36 namespace {
37 
38 template<class Precision> void test(int I, int J, Precision tolerance)
39  {
40  myra::out() << typestring<Precision>() << std::endl;
41  typedef std::complex<Precision> Number;
42  // Generate A.
43  int N = I*J;
44  SparseMatrix<Number> A = laplacian2<Number>(I,J);
45  Precision shift = 5.5;
46  for (int n = 0; n < N; ++n)
47  A(n,n) -= shift;
48  phasor_hermitian(A);
49  // Options related to reordering. Test input is small, so need to use small
50  // blocks/no globbing to make sure the symbolic factorization is nontrivial
51  typedef multifrontal::Options Options;
52  Options options = Options::create().set_blocksize(8).set_globsize(4).set_nthreads(1);
53  // Reorder A using bisection and factor it.
54  Permutation perm = bisect2(I,J);
55  SparseZLDLHSolver<Precision> solver(A,perm,options);
56  // Make random restriction Ri.
57  std::vector<int> Ri(20,0);
58  for (int i = 0; i < Ri.size(); ++i)
59  Ri[i] = random_int(N);
60  sortunique(Ri);
61  // Make random restriction Rj.
62  std::vector<int> Rj(30,0);
63  for (int j = 0; j < Rj.size(); ++j)
64  Rj[j] = random_int(N);
65  sortunique(Rj);
66  // Form restricted inverse Z = Ri'inv(A)*Rj
67  Matrix<Number> Z = solver.inverse(Ri,Rj);
68  int K = 15;
69  // Test from the left.
70  {
71  auto B1 = Matrix<Number>::random(ssize(Rj),K);
72  auto B2 = Matrix<Number>::random(ssize(Ri),K);
73  Precision error_N = frobenius( gemm(Z,'N',B1) - solver.partialsolve(Ri,Rj,B1,'L','N') );
74  Precision error_T = frobenius( gemm(Z,'T',B2) - solver.partialsolve(Ri,Rj,B2,'L','T') );
75  Precision error_H = frobenius( gemm(Z,'H',B2) - solver.partialsolve(Ri,Rj,B2,'L','H') );
76  Precision error_C = frobenius( gemm(Z,'C',B1) - solver.partialsolve(Ri,Rj,B1,'L','C') );
77  myra::out() << " error in Z^N * B = " << error_N << std::endl;
78  myra::out() << " error in Z^T * B = " << error_T << std::endl;
79  myra::out() << " error in Z^H * B = " << error_H << std::endl;
80  myra::out() << " error in Z^C * B = " << error_C << std::endl;
81  REQUIRE(error_N < tolerance);
82  REQUIRE(error_T < tolerance);
83  REQUIRE(error_H < tolerance);
84  REQUIRE(error_C < tolerance);
85  }
86  // Test from the right.
87  {
88  auto B1 = Matrix<Number>::random(K,ssize(Ri));
89  auto B2 = Matrix<Number>::random(K,ssize(Rj));
90  Precision error_N = frobenius( gemm(B1,Z,'N') - solver.partialsolve(Ri,Rj,B1,'R','N') );
91  Precision error_T = frobenius( gemm(B2,Z,'T') - solver.partialsolve(Ri,Rj,B2,'R','T') );
92  Precision error_H = frobenius( gemm(B2,Z,'H') - solver.partialsolve(Ri,Rj,B2,'R','H') );
93  Precision error_C = frobenius( gemm(B1,Z,'C') - solver.partialsolve(Ri,Rj,B1,'R','C') );
94  myra::out() << " error in B * Z^N = " << error_N << std::endl;
95  myra::out() << " error in B * Z^T = " << error_T << std::endl;
96  myra::out() << " error in B * Z^H = " << error_H << std::endl;
97  myra::out() << " error in B * Z^C = " << error_C << std::endl;
98  REQUIRE(error_N < tolerance);
99  REQUIRE(error_T < tolerance);
100  REQUIRE(error_H < tolerance);
101  REQUIRE(error_C < tolerance);
102  }
103  }
104 
105 } // namespace
106 
107 ADD_TEST("zldlh2_partialsolve","[multifrontal][parallel]")
108  { 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
Sparse direct solver suitable for complex hermitian indefinite systems.
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.
static Matrix< Number > random(int I, int J)
Generates a random Matrix of specified size.
Definition: Matrix.cpp:353
Reduces a std::vector to its unique entries, and sorts it.
Sparse direct solver suitable for complex hermitian indefinite systems.
Definition: SparseZLDLHSolver.h:60
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.
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.
Applies random phase shifts to a complex square SparseMatrix.
Range/Iterator types associated with SparseMatrix.
Interface class for representing subranges of contiguous int&#39;s.


Results: [PASS]

double
error in Z^N * B = 2.12795e-13
error in Z^T * B = 2.27052e-13
error in Z^H * B = 2.06101e-13
error in Z^C * B = 2.16886e-13
error in B * Z^N = 2.01989e-13
error in B * Z^T = 2.30751e-13
error in B * Z^H = 2.0471e-13
error in B * Z^C = 2.30177e-13


Go back to Summary of /test programs.