MyraMath
gebrd_square


Source: tests/dense/gebrd.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 #include <myramath/dense/Vector.h>
16 
17 // Algorithms.
18 #include <myramath/dense/gemm.h>
19 #include <myramath/dense/ormqr.h>
20 #include <myramath/dense/ormlq.h>
21 #include <myramath/dense/gebrd.h>
24 
25 // Reporting.
26 #include <tests/myratest.h>
27 
28 using namespace myra;
29 
30 namespace {
31 
32 // Tests tall/skinny gebrd(). Also handles the square case (see fine print on gebrd).
33 template<class Number> void test1(int I, int J, typename ReflectPrecision<Number>::type tolerance)
34  {
35  // Useful constants.
36  typedef typename ReflectPrecision<Number>::type Precision;
37  int K = I < J ? I : J;
38  // Make random A, and a few copy.
39  auto A = Matrix<Number>::random(I,J);
40  auto B = A;
41  // Factor A = Q*B*P
42  auto tau = gebrd_inplace(A);
43  auto tauq = tau.first;
44  auto taup = tau.second;
45  // Multiply out (Q'*A)*P', order matters.
46  auto Q = A.range();
47  ormqr_inplace(Q,tauq,B,'L','H');
48  auto P = A.cut_left(1).top(J);
49  ormlq_inplace(P,taup.cut_last(1),B.cut_left(1).top(J),'R','H');
50  // Subtract out D and E from B.
51  for (int k = 0; k < K; ++k)
52  B(k,k) -= A(k,k);
53  for (int k = 0; k < K-1; ++k)
54  B(k,k+1) -= A(k,k+1);
55  // Verify Q'*A*P' = B.
56  Precision error = frobenius(B);
57  myra::out() << "|Q'*A*P' - B| = " << error << std::endl;
58  REQUIRE(error < tolerance);
59  }
60 
61 // Tests short/fat gebrd()
62 template<class Number> void test2(int I, int J, typename ReflectPrecision<Number>::type tolerance)
63  {
64  // Useful constants.
65  typedef typename ReflectPrecision<Number>::type Precision;
66  int K = I < J ? I : J;
67  // Make random A, and a few copy.
68  auto A = Matrix<Number>::random(I,J);
69  auto B = A;
70  // Factor A = Q*B*P
71  auto tau = gebrd_inplace(A);
72  auto tauq = tau.first;
73  auto taup = tau.second;
74  // Multiply out Q'*(A*P'), order matters.
75  auto P = A.range();
76  ormlq_inplace(P,taup,B,'R','H');
77  auto Q = A.cut_top(1).left(I);
78  ormqr_inplace(Q,tauq.cut_last(1),B.cut_top(1).left(I),'L','H');
79  // Subtract out D and E from B.
80  for (int k = 0; k < K; ++k)
81  B(k,k) -= A(k,k);
82  for (int k = 0; k < K-1; ++k)
83  B(k+1,k) -= A(k+1,k);
84  // Verify Q'*A*P' = B.
85  Precision error = frobenius(B);
86  myra::out() << "|Q'*A*P' - B| = " << error << std::endl;
87  REQUIRE(error < tolerance);
88  }
89 
90 } // namespace
91 
92 ADD_TEST("gebrd_tallskinny","[dense][lapack]")
93  {
94  int N1 = 17;
95  int N2 = 13;
96  test1<NumberS>(N1,N2,1.0e-5f);
97  test1<NumberD>(N1,N2,1.0e-10);
98  test1<NumberC>(N1,N2,1.0e-5f);
99  test1<NumberZ>(N1,N2,1.0e-10);
100  }
101 
102 ADD_TEST("gebrd_shortfat","[dense][lapack]")
103  {
104  int N1 = 17;
105  int N2 = 13;
106  test2<NumberS>(N2,N1,1.0e-5f);
107  test2<NumberD>(N2,N1,1.0e-10);
108  test2<NumberC>(N2,N1,1.0e-5f);
109  test2<NumberZ>(N2,N1,1.0e-10);
110  }
111 
112 ADD_TEST("gebrd_square","[dense][lapack]")
113  {
114  int N1 = 17;
115  int N2 = 13;
116  test1<NumberS>(N1,N1,1.0e-5f);
117  test1<NumberD>(N1,N1,1.0e-10);
118  test1<NumberC>(N1,N1,1.0e-5f);
119  test1<NumberZ>(N1,N1,1.0e-10);
120  }
121 
CMatrixRange< Number > range() const
Explicit conversion, returns a MatrixRange over all of *this.
Definition: Matrix.cpp:130
Interface class for representing subranges of dense Matrix&#39;s.
Routines to apply a Householder Q, as previously factored via gelqf_inplace()
CMatrixRange< Number > cut_left(int j) const
Returns a MatrixRange that cuts the j leftmost columns, this(:,j:J)
Definition: Matrix.cpp:269
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
Replaces small values with explicit zeros.
Definition: syntax.dox:1
Various utility functions/classes related to scalar Number types.
General purpose dense matrix container, O(i*j) storage.
CMatrixRange< Number > cut_top(int i) const
Cuts the i topmost rows, returns this(i:I,:)
Definition: MatrixRange.cpp:539
Householder bidiagonalization of a general Matrix.
Container for either a column vector or row vector (depends upon the usage context) ...
CMatrixRange< Number > cut_left(int j) const
Cuts the j leftmost columns, returns this(:,j:J)
Definition: MatrixRange.cpp:588
Reflects Precision trait for a Number, scalar Number types should specialize it.
Definition: Number.h:33
Routines to apply a Householder Q, as previously factored via geqrf_inplace()
CMatrixRange< Number > cut_top(int i) const
Returns a MatrixRange that cuts the i topmost rows, this(i:I,:)
Definition: Matrix.cpp:213
Variety of routines all for dense Matrix*Matrix multiplies. Delegates to the BLAS.


Results: [PASS]

|Q'*A*P' - B| = 5.33681e-06
|Q'*A*P' - B| = 8.38749e-15
|Q'*A*P' - B| = 9.12197e-06
|Q'*A*P' - B| = 1.32992e-14


Go back to Summary of /test programs.