MyraMath
lu2_partialsolve


Source: tests/multifrontal/lu/lu2_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 Number> void test(int I, int J, typename ReflectPrecision<Number>::type tolerance)
38  {
39  myra::out() << typestring<Number>() << std::endl;
40  typedef typename ReflectPrecision<Number>::type Precision;
41  // Generate A.
42  int N = I*J;
43  SparseMatrix<Number> A = laplacian2<Number>(I,J);
44  // Options related to reordering. Test input is small, so need to use small
45  // blocks/no globbing to make sure the symbolic factorization is nontrivial
46  typedef multifrontal::Options Options;
47  Options options = Options::create().set_blocksize(4).set_globsize(4).set_nthreads(1);
48  // Reorder A using bisection and factor it.
49  Permutation perm = bisect2(I,J);
50  SparseLUSolver<Number> solver(A,perm,options);
51  // Make random restriction Ri.
52  std::vector<int> Ri(20,0);
53  for (int i = 0; i < Ri.size(); ++i)
54  Ri[i] = random_int(N);
55  sortunique(Ri);
56  // Make random restriction Rj.
57  std::vector<int> Rj(30,0);
58  for (int j = 0; j < Rj.size(); ++j)
59  Rj[j] = random_int(N);
60  sortunique(Rj);
61  // Form restricted inverse Z = Ri'inv(A)*Rj
62  Matrix<Number> Z = solver.inverse(Ri,Rj);
63  int K = 15;
64  // Test from the left.
65  {
66  auto B1 = Matrix<Number>::random(ssize(Rj),K);
67  auto B2 = Matrix<Number>::random(ssize(Ri),K);
68  Precision error_N = frobenius( gemm(Z,'N',B1) - solver.partialsolve(Ri,Rj,B1,'L','N') );
69  Precision error_T = frobenius( gemm(Z,'T',B2) - solver.partialsolve(Ri,Rj,B2,'L','T') );
70  Precision error_H = frobenius( gemm(Z,'H',B2) - solver.partialsolve(Ri,Rj,B2,'L','H') );
71  Precision error_C = frobenius( gemm(Z,'C',B1) - solver.partialsolve(Ri,Rj,B1,'L','C') );
72  myra::out() << " error in Z^N * B = " << error_N << std::endl;
73  myra::out() << " error in Z^T * B = " << error_T << std::endl;
74  myra::out() << " error in Z^H * B = " << error_H << std::endl;
75  myra::out() << " error in Z^C * B = " << error_C << std::endl;
76  REQUIRE(error_N < tolerance);
77  REQUIRE(error_T < tolerance);
78  REQUIRE(error_H < tolerance);
79  REQUIRE(error_C < tolerance);
80  }
81  // Test from the right.
82  {
83  auto B1 = Matrix<Number>::random(K,ssize(Ri));
84  auto B2 = Matrix<Number>::random(K,ssize(Rj));
85  Precision error_N = frobenius( gemm(B1,Z,'N') - solver.partialsolve(Ri,Rj,B1,'R','N') );
86  Precision error_T = frobenius( gemm(B2,Z,'T') - solver.partialsolve(Ri,Rj,B2,'R','T') );
87  Precision error_H = frobenius( gemm(B2,Z,'H') - solver.partialsolve(Ri,Rj,B2,'R','H') );
88  Precision error_C = frobenius( gemm(B1,Z,'C') - solver.partialsolve(Ri,Rj,B1,'R','C') );
89  myra::out() << " error in B * Z^N = " << error_N << std::endl;
90  myra::out() << " error in B * Z^T = " << error_T << std::endl;
91  myra::out() << " error in B * Z^H = " << error_H << std::endl;
92  myra::out() << " error in B * Z^C = " << error_C << std::endl;
93  REQUIRE(error_N < tolerance);
94  REQUIRE(error_T < tolerance);
95  REQUIRE(error_H < tolerance);
96  REQUIRE(error_C < tolerance);
97  }
98  }
99 
100 } // namespace
101 
102 ADD_TEST("lu2_partialsolve","[multifrontal][parallel]")
103  {
104  test<NumberD>(20,20,1.0e-10);
105  test<NumberZ>(20,20,1.0e-10);
106  }
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.
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.
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.
Sparse direct solver suitable for symmetric-pattern nonsymmetric-value A.
General purpose dense matrix container, O(i*j) storage.
Sparse direct solver suitable for symmetric-pattern nonsymmetric-valued A.
Definition: SparseLUSolver.h:57
Reflects Precision trait for a Number, scalar Number types should specialize it.
Definition: Number.h:33
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.
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.73396e-16
error in Z^T * B = 2.25136e-16
error in Z^H * B = 2.25136e-16
error in Z^C * B = 2.73396e-16
error in B * Z^N = 2.42228e-16
error in B * Z^T = 2.79062e-16
error in B * Z^H = 2.79062e-16
error in B * Z^C = 2.42228e-16
std::complex<double>
error in Z^N * B = 2.99762e-16
error in Z^T * B = 2.81363e-16
error in Z^H * B = 2.81363e-16
error in Z^C * B = 3.56507e-16
error in B * Z^N = 2.58783e-16
error in B * Z^T = 2.62462e-16
error in B * Z^H = 2.62462e-16
error in B * Z^C = 3.31214e-16


Go back to Summary of /test programs.