MyraMath
zheev


Source: tests/dense/heev.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>
17 
18 // Algorithms.
19 #include <myramath/dense/dimm.h>
20 #include <myramath/dense/gemm.h>
21 #include <myramath/dense/heev.h>
24 
25 // Reporting.
26 #include <tests/myratest.h>
27 
28 using namespace myra;
29 
30 namespace {
31 
32 template<class Precision> void test(int N, Precision tolerance)
33  {
34  typedef typename ReflectComplex<Precision>::type Number;
35  myra::out() << typestring<Number>() << std::endl;
36  // Make random hermitian matrix A.
37  auto A = Matrix<Number>::random(N,N);
38  A += hermitian(A);
39  // Eigendecompose A = X*D*X'
40  auto XD = heev(A);
41  const auto& X = XD.first;
42  const auto& D = XD.second;
43  auto I = Matrix<Number>::identity(N);
44  // Check residual error |R|, where R = A-X*D*X'
45  Precision R_error = frobenius(A-X*D*hermitian(X))/frobenius(D);
46  myra::out() << " |A-X*D*X'| = " << R_error << std::endl;
47  // Check eigenvector orthogonality, X'*X = I
48  Precision X_error = frobenius(gemm(X,'H',X)-I)/N;
49  myra::out() << " |X'*X -I| = " << X_error << std::endl;
50  // Check the layout assumptions of X (orthogonal columns)
51  int K = N/2;
52  auto Xk = X.left(K);
53  auto Ik = Matrix<Number>::identity(K);
54  Precision Xk_error = frobenius(gemm(Xk,'H',Xk)-Ik)/N;
55  myra::out() << " |Xk'Xk-Ik| = " << Xk_error << std::endl;
56  // Verify eigenvalues are sorted in ascending order.
57  bool sorted = true;
58  for (int n = 0; n < N-1; ++n)
59  sorted &= D(n) <= D(n+1);
60  myra::out() << std::boolalpha;
61  myra::out() << " sorted D(n) <= D(n+1) = " << sorted << std::endl;
62  // Apply tests.
63  REQUIRE(R_error < tolerance);
64  REQUIRE(X_error < tolerance);
65  REQUIRE(Xk_error < tolerance);
66  REQUIRE(sorted);
67  }
68 
69 } // namespace
70 
71 // Single test, float precision.
72 ADD_TEST("cheev","[dense][lapack]")
73  { test<float>(50,2.0e-5f); }
74 
75 // Stress test, lots of sizes (N) and lots of trials (T).
76 ADD_TEST("cheev_stress","[dense][lapack][.]")
77  {
78  int N = 100;
79  int T = 10;
80  for (int n = 1; n < N; ++n)
81  for (int t = 0; t < T; ++t)
82  test<float>(n,2.0e-5f);
83  }
84 
85 // Single test, double precision.
86 ADD_TEST("zheev","[dense][lapack]")
87  { test<double>(50,1.0e-12); }
88 
89 // Stress test, lots of sizes (N) and lots of trials (T).
90 ADD_TEST("zheev_stress","[dense][lapack][.]")
91  {
92  int N = 100;
93  int T = 10;
94  for (int n = 1; n < N; ++n)
95  for (int t = 0; t < T; ++t)
96  test<double>(n,1.0e-12);
97  }
98 
Interface class for representing subranges of DiagonalMatrix&#39;s.
Interface class for representing subranges of dense Matrix&#39;s.
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
Routines for multiplying by a DiagonalMatrix.
Definition: syntax.dox:1
Reflects a Precision type into a complex type.
Definition: Number.h:46
Various utility functions/classes related to scalar Number types.
static Matrix< Number > identity(int IJ)
Generates an identity Matrix of specified size.
Definition: Matrix.cpp:349
General purpose dense matrix container, O(i*j) storage.
Computes all eigenpairs of complex hermitian Matrix.
Returns a hermitian copy of a Matrix. The inplace version only works on a square operand.
Container for a diagonal matrix, O(n) storage. Used by SVD, row/column scaling, etc.
Variety of routines all for dense Matrix*Matrix multiplies. Delegates to the BLAS.


Results: [PASS]

std::complex<double>
|A-X*D*X'| = 5.67864e-15
|X'*X -I| = 2.8205e-16
|Xk'Xk-Ik| = 1.6696e-16
sorted D(n) <= D(n+1) = true


Go back to Summary of /test programs.