MyraMath
ctrsmL


Source: tests/dense/trsm1.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.
13 #include <myramath/dense/Matrix.h>
15 
16 // Algorithms.
18 #include <myramath/dense/potrf.h>
19 #include <myramath/dense/tril.h>
20 #include <myramath/dense/gemm.h>
21 #include <myramath/dense/trsm.h>
26 
27 // Reporting.
28 #include <tests/myratest.h>
29 
30 using namespace myra;
31 
32 namespace {
33 
34 template<class Number> void test(typename ReflectPrecision<Number>::type tolerance)
35  {
36  typedef typename ReflectPrecision<Number>::type Precision;
37  myra::out() << typestring<Number>() << std::endl;
38  int I = 27;
39  int J = 34;
40  // Compute the cholesky triangle of a random SPD matrix to get a suitably conditioned L.
41  auto G = Matrix<Number>::random(I,I);
42  Matrix<Number> A = G * hermitian(G);
43  potrf_inplace('L','R',A);
44  Matrix<Number> L = tril(A);
45  char diag = 'N';
46  Number alpha = random<Number>();
47  Number one(1);
48  // Case 1: solving L*X=B
49  {
50  auto X = Matrix<Number>::random(I,J);
51  Matrix<Number> B = (one/alpha)*L*X;
52  trsm_inplace('L','L','N',A,B,diag,alpha);
53  Precision error = frobenius(B-X);
54  myra::out() << " |L\\B-X| = " << error << std::endl;
55  REQUIRE(error < tolerance);
56  }
57  // Case 2: solving transpose(L)*X = B
58  {
59  auto X = Matrix<Number>::random(I,J);
60  Matrix<Number> B = (one/alpha)*transpose(L)*X;
61  trsm_inplace('L','L','T',A,B,diag,alpha);
62  Precision error = frobenius(B-X);
63  myra::out() << " |transpose(L)\\B-X| = " << error << std::endl;
64  REQUIRE(error < tolerance);
65  }
66  // Case 3: solving hermitian(L)*X = B
67  {
68  auto X = Matrix<Number>::random(I,J);
69  Matrix<Number> B = (one/alpha)*hermitian(L)*X;
70  trsm_inplace('L','L','H',A,B,diag,alpha);
71  Precision error = frobenius(B-X);
72  myra::out() << " |hermitian(L)\\B-X| = " << error << std::endl;
73  REQUIRE(error < tolerance);
74  }
75  // Case 4: solving conjugate(L)*X = B
76  {
77  auto X = Matrix<Number>::random(I,J);
78  Matrix<Number> B = (one/alpha)*conjugate(L)*X;
79  trsm_inplace('L','L','C',A,B,diag,alpha);
80  Precision error = frobenius(B-X);
81  myra::out() << " |conjugate(L)\\B-X| = " << error << std::endl;
82  REQUIRE(error < tolerance);
83  }
84  // Case 5: solving X*L = B
85  {
86  auto X = Matrix<Number>::random(J,I);
87  Matrix<Number> B = (one/alpha)*X*L;
88  trsm_inplace('R','L','N',A,B,diag,alpha);
89  Precision error = frobenius(B-X);
90  myra::out() << " |B/L-X| = " << error << std::endl;
91  REQUIRE(error < tolerance);
92  }
93  // Case 6: solving X*transpose(L) = B
94  {
95  auto X = Matrix<Number>::random(J,I);
96  Matrix<Number> B = (one/alpha)*X*transpose(L);
97  trsm_inplace('R','L','T',A,B,diag,alpha);
98  Precision error = frobenius(B-X);
99  myra::out() << " |B/transpose(L)-X| = " << error << std::endl;
100  REQUIRE(error < tolerance);
101  }
102  // Case 7: solving X*hermitian(L) = B
103  {
104  auto X = Matrix<Number>::random(J,I);
105  Matrix<Number> B = (one/alpha)*X*hermitian(L);
106  trsm_inplace('R','L','H',A,B,diag,alpha);
107  Precision error = frobenius(B-X);
108  myra::out() << " |B/hermitian(L)-X| = " << error << std::endl;
109  REQUIRE(error < tolerance);
110  }
111  // Case 8: solving X*conjugate(L) = B
112  {
113  auto X = Matrix<Number>::random(J,I);
114  Matrix<Number> B = (one/alpha)*X*conjugate(L);
115  trsm_inplace('R','L','C',A,B,diag,alpha);
116  Precision error = frobenius(B-X);
117  myra::out() << " |B/conjugate(L)-X| = " << error << std::endl;
118  REQUIRE(error < tolerance);
119  }
120  }
121 
122 } // namespace
123 
124 ADD_TEST("strsmL","[dense][lapack]")
125  { test<NumberS>(1.0e-2f); }
126 
127 ADD_TEST("dtrsmL","[dense][lapack]")
128  { test<NumberD>(1.0e-10); }
129 
130 ADD_TEST("ctrsmL","[dense][lapack]")
131  { test<NumberC>(1.0e-2f); }
132 
133 ADD_TEST("ztrsmL","[dense][lapack]")
134  { test<NumberZ>(1.0e-10); }
Returns a conjugated copy of a Matrix or Vector. Or, conjugate one inplace.
Cholesky factorization routines for positive definite matrices.
Interface class for representing subranges of dense Matrix&#39;s.
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
Definition: syntax.dox:1
Routines for backsolving by a triangular Matrix or LowerMatrix.
Returns a transposed copy of a Matrix. The inplace version only works on a square operand...
Returns the lower triangle of a dense Matrix.
Various utility functions/classes related to scalar Number types.
General purpose dense matrix container, O(i*j) storage.
Reflects Precision trait for a Number, scalar Number types should specialize it.
Definition: Number.h:33
Returns a hermitian copy of a Matrix. The inplace version only works on a square operand.
Simplistic random number functions.
Variety of routines all for dense Matrix*Matrix multiplies. Delegates to the BLAS.


Results: [PASS]

std::complex<float>
|L\B-X| = 1.23347e-05
|transpose(L)\B-X| = 5.50482e-06
|hermitian(L)\B-X| = 6.47073e-06
|conjugate(L)\B-X| = 1.32608e-05
|B/L-X| = 6.05496e-06
|B/transpose(L)-X| = 1.1193e-05
|B/hermitian(L)-X| = 1.10228e-05
|B/conjugate(L)-X| = 5.45893e-06


Go back to Summary of /test programs.