MyraMath
dsyev


Source: tests/dense/syev.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/syev.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  myra::out() << typestring<Precision>() << std::endl;
35  // Make random real symmetric matrix A.
36  auto A = Matrix<Precision>::random(N,N);
37  A += transpose(A);
38  // Eigendecompose A = X*D*X'
39  auto XD = syev(A);
40  const auto& X = XD.first;
41  const auto& D = XD.second;
42  auto I = Matrix<Precision>::identity(N);
43  // Check residual error |R|, where R = A-X*D*X'
44  Precision R_error = frobenius(A-X*D*transpose(X))/frobenius(D);
45  myra::out() << " |A-X*D*X'| = " << R_error << std::endl;
46  // Check eigenvector orthogonality, X'*X = I
47  Precision X_error = frobenius(gemm(X,'T',X)-I)/N;
48  myra::out() << " |X'*X -I| = " << X_error << std::endl;
49  // Check the layout assumptions of X (orthogonal columns)
50  int K = N/2;
51  auto Xk = X.left(K);
52  auto Ik = Matrix<Precision>::identity(K);
53  Precision Xk_error = frobenius(gemm(Xk,'T',Xk)-Ik)/N;
54  myra::out() << " |Xk'Xk-Ik| = " << Xk_error << std::endl;
55  // Verify eigenvalues are sorted in ascending order.
56  bool sorted = true;
57  for (int n = 0; n < N-1; ++n)
58  sorted &= D(n) <= D(n+1);
59  myra::out() << std::boolalpha;
60  myra::out() << " sorted D(n) <= D(n+1) = " << sorted << std::endl;
61  // Apply tests.
62  REQUIRE(R_error < tolerance);
63  REQUIRE(X_error < tolerance);
64  REQUIRE(Xk_error < tolerance);
65  REQUIRE(sorted);
66  }
67 
68 } // namespace
69 
70 // Single test, float precision.
71 ADD_TEST("ssyev","[dense][lapack]")
72  { test<float>(50,1.0e-4f); }
73 
74 // Stress test, lots of sizes (N) and lots of trials (T).
75 ADD_TEST("ssyev_stress","[dense][lapack][.]")
76  {
77  int N = 100;
78  int T = 10;
79  for (int n = 1; n < N; ++n)
80  for (int t = 0; t < T; ++t)
81  test<float>(n,1.0e-4f);
82  }
83 
84 // Single test, double precision.
85 ADD_TEST("dsyev","[dense][lapack]")
86  { test<double>(50,1.0e-12); }
87 
88 // Stress test, lots of sizes (N) and lots of trials (T).
89 ADD_TEST("dsyev_stress","[dense][lapack][.]")
90  {
91  int N = 100;
92  int T = 10;
93  for (int n = 1; n < N; ++n)
94  for (int t = 0; t < T; ++t)
95  test<double>(n,1.0e-12);
96  }
97 
Interface class for representing subranges of DiagonalMatrix&#39;s.
Computes all eigenpairs of real symmetric Matrix.
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
Returns a transposed copy of a Matrix. The inplace version only works on a square operand...
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.
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]

double
|A-X*D*X'| = 4.49426e-15
|X'*X -I| = 3.05103e-16
|Xk'Xk-Ik| = 1.85485e-16
sorted D(n) <= D(n+1) = true


Go back to Summary of /test programs.