MyraMath
slqt


Source: tests/dense/lqt.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.
17 #include <myramath/dense/lqt.h>
18 #include <myramath/dense/gemm.h>
19 #include <myramath/dense/trmm.h>
20 #include <myramath/dense/gelqf.h>
21 #include <myramath/dense/ormlq.h>
24 
25 // Reporting.
26 #include <tests/myratest.h>
27 
28 using namespace myra;
29 
30 namespace {
31 
32 // Tests lqt() on a tall/skinny A.
33 template<class Number> void test(int I, int J, typename ReflectPrecision<Number>::type tolerance)
34  {
35  // Useful typedefs/constants.
36  typedef typename ReflectPrecision<Number>::type Precision;
37  Number one(1);
38  int K = I < J ? I : J;
39  myra::out() << typestring<Number>() << std::endl;
40  // Form random A/B, factor A=LQ, form T in tril(A)
41  auto A = Matrix<Number>::random(I,J);
42  auto B1 = Matrix<Number>::random(I,J);
43  auto B2 = B1;
44  auto tau = gelqf_inplace(A);
45  lqt_inplace(A,tau);
46  // Apply scalar, B1 = B1*(I-tau*v*v'), using ormlq_inplace() ..
47  ormlq_inplace(A,tau,B1,'R','N');
48  // Apply block reflections, B2 = B2*(I-V'*T*V), using lqt() ..
49  // .. partition V and B.
50  auto VlVr = A.split_left(K);
51  auto Vl = VlVr.first;
52  auto Vr = VlVr.second;
53  auto BlBr = B2.split_left(K);
54  auto Bl = BlBr.first;
55  auto Br = BlBr.second;
56  // .. form W = B2*V'
57  Matrix<Number> W(Bl);
58  trmm_inplace('R','U','H',Vl,W,'U');
59  gemm_inplace(W,Br,'N',Vr,'H',one,one);
60  // .. update W = W*T
61  trmm_inplace('R','L','N',Vl,W,'N',one);
62  // .. update B -= W*V
63  gemm_inplace(Br,W,'N',Vr,'N',-one,one);
64  trmm_inplace('R','U','N',Vl,W,'U');
65  Bl -= W;
66  // Check answers.
67  Precision error = frobenius(B1-B2) / frobenius(B1);
68  myra::out() << "|Q*B1(ormlq) - Q*B2(lqt)| = " << error << std::endl;
69  REQUIRE(error < tolerance);
70  }
71 
72 } // namespace
73 
74 ADD_TEST("slqt","[dense][lapack]")
75  { test<NumberS>(159,178,1.0e-4f); }
76 
77 ADD_TEST("dlqt","[dense][lapack]")
78  { test<NumberD>(159,178,1.0e-10); }
79 
80 ADD_TEST("clqt","[dense][lapack]")
81  { test<NumberC>(159,178,1.0e-4f); }
82 
83 ADD_TEST("zlqt","[dense][lapack]")
84  { test<NumberZ>(159,178,1.0e-10); }
Interface class for representing subranges of dense Matrix&#39;s.
Routines to apply a Householder Q, as previously factored via gelqf_inplace()
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 multiplying by a triangular Matrix or LowerMatrix.
Given the scalar reflectors [V,tau] from gelqf(), forms the T of the equivalent block reflector I-V&#39;*...
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.
Variety of routines all for dense Matrix*Matrix multiplies. Delegates to the BLAS.
Routines to compute a Householder LQ decomposition.


Results: [PASS]

float
|Q*B1(ormlq) - Q*B2(lqt)| = 8.18313e-07


Go back to Summary of /test programs.