MyraMath
lu2_schur


Source: tests/multifrontal/lu/lu2_schur.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>
22 
23 // Algorithms.
26 #include <myramath/dense/dot.h>
27 #include <myramath/dense/gemm.h>
28 #include <myramath/dense/inverse.h>
31 
32 // Solver under test.
34 
35 // Reporting.
36 #include <tests/myratest.h>
37 
38 using namespace myra;
39 
40 namespace {
41 
42 // Generates random row indices.
43 std::vector<int> random_rows(int I, int N)
44  {
45  std::vector<int> answer;
46  for (int n = 0; n < N; ++n)
47  answer.push_back( random_int(0,I) );
48  sortunique(answer);
49  return answer;
50  }
51 
52 // Fills SparseMatrix B from (Bi,Bv) data.
53 template<class Number> SparseMatrix<Number> fill(int I, const std::vector<int>& Bi, const Matrix<Number>& Bv)
54  {
55  int J = Bv.size().second;
56  SparseMatrixBuilder<Number> B_builder(I,J);
57  for (int j = 0; j < J; ++j)
58  for (int i = 0; i < Bi.size(); ++i)
59  B_builder(Bi[i],j) = Bv(i,j);
60  return B_builder.make_SparseMatrix();
61  }
62 
63 template<class Number> void test(typename ReflectPrecision<Number>::type tolerance)
64  {
65  typedef typename ReflectPrecision<Number>::type Precision;
66  // Generate A, structured stencil but random values.
67  int I = 20;
68  int J = 25;
69  int N = I*J;
70  int K = 23;
71  int K1 = K-1;
72  int K2 = K+1;
73 
74  // Generate A.
75  Pattern P = stencil2(I,J);
76  auto A = SparseMatrix<Number>::random(P);
77 
78  // Options related to reordering.
79  typedef multifrontal::Options Options;
80  Options options = Options::create().set_blocksize(4).set_globsize(4).set_nthreads(4);
81 
82  // Reorder A using bisection and factor it.
83  Permutation perm = bisect2(I,J);
84  SparseLUSolver<Number> solver(A,perm,options);
85 
86  {
87  // Generate C/D, compute a schur complement C'*inv(A)*D
88  auto C = SparseMatrix<Number>::random(N,K1,5);
89  auto D = SparseMatrix<Number>::random(N,K2,4);
90  Matrix<Number> S1 = solver.schur(C,D,options);
91  // Compare to reference/dense calculation.
92  Matrix<Number> S2 = gemm(C.make_Matrix(),'T',gemm(inverse(A.make_Matrix()),D.make_Matrix()));
93  Precision S_error = frobenius(S1-S2) / frobenius(S2);
94  myra::out() << "|C'*inv(A)*D [dense] - C'*inv(A)*D [sparse]| = " << S_error << std::endl;
95  REQUIRE(S_error < 1.0e-10);
96  }
97 
98  {
99  // Compute a restricted schur complement Bv'*Bi'*inv(A)*Ci*Cv
100  auto Bi = random_rows(N,10);
101  auto Bv = Matrix<Number>::random(N,K1);
102  auto Ci = random_rows(N,10);
103  auto Cv = Matrix<Number>::random(N,K2);
104  auto S1 = solver.schur(Bi,Bv,Ci,Cv,options);
105  // Compare to reference/dense calculation.
106  auto B = fill(N,Bi,Bv);
107  auto C = fill(N,Ci,Cv);
108  auto S2 = gemm(B.make_Matrix(),'T',gemm(inverse(A.make_Matrix()),C.make_Matrix()));
109  Precision S_error = frobenius(S1-S2)/frobenius(S2);
110  myra::out() << "|schur(B,C)-schur(BiBv,CiCv)| = " << S_error << std::endl;
111  REQUIRE(S_error < tolerance);
112  }
113 
114  }
115 
116 } // namespace
117 
118 ADD_TEST("lu2_schur","[multifrontal][parallel]")
119  {
120  test<NumberD>(1.0e-8);
121  test<NumberZ>(1.0e-8);
122  }
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
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
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
Routines for inner products of Vector&#39;s / VectorRange&#39;s.
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.
Convenience type for building SparseMatrix&#39;s, uses coordinate/triplet format.
Definition: SparseMatrix.h:32
std::pair< int, int > size() const
Size inspector.
Definition: Matrix.cpp:116
Convenience type for building SparseMatrix&#39;s, uses coordinate/triplet format. Note that SparseMatrixB...
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.
Matrix< Number > make_Matrix() const
Accumulates *this onto a Matrix<Number>.
Definition: SparseMatrix.cpp:581
Interface class for representing subranges of contiguous int&#39;s.


Results: [PASS]

|C'*inv(A)*D [dense] - C'*inv(A)*D [sparse]| = 5.03812e-14
|schur(B,C)-schur(BiBv,CiCv)| = 6.22951e-14
|C'*inv(A)*D [dense] - C'*inv(A)*D [sparse]| = 5.61056e-15
|schur(B,C)-schur(BiBv,CiCv)| = 4.53647e-15


Go back to Summary of /test programs.