MyraMath
crank


Source: tests/dense/rank.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>
14 
15 // Algorithms.
16 #include <myramath/dense/gemm.h>
21 
22 // Reporting.
23 #include <tests/myratest.h>
24 
25 using namespace myra;
26 
27 namespace {
28 
29 template<class Number> void test(int I, int J, int K, typename ReflectPrecision<Number>::type tolerance)
30  {
31  myra::out() << typestring<Number>() << std::endl;
32  typedef typename ReflectPrecision<Number>::type Precision;
33  // From IxJ sized matrix with rank K.
34  auto U = Matrix<Number>::random(I,K);
35  auto V = Matrix<Number>::random(K,J);
36  auto A = U*V;
37  auto Ah = hermitian(A);
38  // Extract nullspace/rangespace of A.
39  auto null_A = nullspace(A);
40  auto range_A = rangespace(A);
41  int rank = range_A.size().second;
42  int nullity = null_A.size().second;
43  // Extract nullspace of A'
44  auto null_Ah = nullspace(Ah);
45  auto range_Ah = rangespace(Ah);
46  // Verify nullspaces form orthonormal bases.
47  Precision error1 = frobenius(gemm(null_A,'H',null_A) - Matrix<Number>::identity(nullity));
48  myra::out() << " |null(A)'null(A)-I| = " << error1 << std::endl;
49  Precision error2 = frobenius(gemm(null_Ah,'H',null_Ah) - Matrix<Number>::identity(nullity));
50  myra::out() << " |null(A')'null(A')-I| = " << error2 << std::endl;
51  // Verify A*null(A) and A'*null(A') are vanishingly small.
52  Precision error3 = frobenius(gemm(A,null_A));
53  myra::out() << " |A*null(A)| = " << error3 << std::endl;
54  Precision error4 = frobenius(gemm(Ah,null_Ah));
55  myra::out() << " |A'*null(A')| = " << error4 << std::endl;
56  // Verify rangespaces form orthonormal basis.
57  Precision error5 = frobenius(gemm(range_A,'H',range_A) - Matrix<Number>::identity(rank));
58  myra::out() << " |range(A)'range(A)-I| = " << error5 << std::endl;
59  Precision error6 = frobenius(gemm(range_Ah,'H',range_Ah) - Matrix<Number>::identity(rank));
60  myra::out() << " |range(A')'range(A')-I| = " << error6 << std::endl;
61  // Verify range(A')'*null(A) and range(A)*null(A') are vanishingly small.
62  Precision error7 = frobenius( gemm(range_Ah,'H',null_A) );
63  myra::out() << " |range(A')*null(A)| = " << error7 << std::endl;
64  Precision error8 = frobenius( gemm(range_A,'H',null_Ah) );
65  myra::out() << " |range(A)*null(A')| = " << error8 << std::endl;
66  // Assert everything.
67  REQUIRE(error1 < tolerance);
68  REQUIRE(error2 < tolerance);
69  REQUIRE(error3 < tolerance);
70  REQUIRE(error4 < tolerance);
71  REQUIRE(error5 < tolerance);
72  REQUIRE(error6 < tolerance);
73  REQUIRE(error7 < tolerance);
74  REQUIRE(error8 < tolerance);
75  }
76 
77 } // namespace
78 
79 ADD_TEST("srank","[dense][lapack]")
80  { test<NumberS>(20,17,12,1.0e-4f); }
81 
82 ADD_TEST("drank","[dense][lapack]")
83  { test<NumberD>(20,17,12,1.0e-12); }
84 
85 ADD_TEST("crank","[dense][lapack]")
86  { test<NumberC>(20,17,12,1.0e-4f); }
87 
88 ADD_TEST("zrank","[dense][lapack]")
89  { test<NumberZ>(20,17,12,1.0e-12); }
90 
Returns orthonormal basis for the range of A.
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
Returns orthonormal basis for the nullspace of A, such that A*null(A) = 0.
Definition: syntax.dox:1
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.


Results: [PASS]

std::complex<float>
|null(A)'null(A)-I| = 9.09388e-07
|null(A')'null(A')-I| = 6.88643e-07
|A*null(A)| = 2.85762e-05
|A'*null(A')| = 7.3578e-05
|range(A)'range(A)-I| = 2.00443e-06
|range(A')'range(A')-I| = 1.5302e-06
|range(A')*null(A)| = 1.92874e-06
|range(A)*null(A')| = 3.04422e-05


Go back to Summary of /test programs.