MOAB: Mesh Oriented datABase  (version 5.5.0)
test_Matrix3.cpp File Reference
#include <vector>
#include <cassert>
#include "moab/Matrix3.hpp"
#include "moab/Core.hpp"
#include "moab/CartVect.hpp"
#include "TestUtil.hpp"
+ Include dependency graph for test_Matrix3.cpp:

Go to the source code of this file.

Macros

#define ACOS(x)   acos( std::min( std::max( x, -1.0 ), 1.0 ) )
 
#define CHECK_EIGVECREAL_EQUAL(EXP, ACT, EPS)    check_equal_eigvect( ( EXP ), ( ACT ), ( EPS ), #EXP, #ACT, __LINE__, __FILE__ )
 

Functions

double find_angle (const moab::CartVect &A, const moab::CartVect &B)
 
void check_equal_eigvect (const moab::CartVect &A, const moab::CartVect &B, double eps, const char *sA, const char *sB, int line, const char *file)
 
void test_EigenDecomp ()
 
int main ()
 

Macro Definition Documentation

◆ ACOS

#define ACOS (   x)    acos( std::min( std::max( x, -1.0 ), 1.0 ) )

Definition at line 10 of file test_Matrix3.cpp.

◆ CHECK_EIGVECREAL_EQUAL

#define CHECK_EIGVECREAL_EQUAL (   EXP,
  ACT,
  EPS 
)     check_equal_eigvect( ( EXP ), ( ACT ), ( EPS ), #EXP, #ACT, __LINE__, __FILE__ )

Definition at line 22 of file test_Matrix3.cpp.

Function Documentation

◆ check_equal_eigvect()

void check_equal_eigvect ( const moab::CartVect A,
const moab::CartVect B,
double  eps,
const char *  sA,
const char *  sB,
int  line,
const char *  file 
)

Definition at line 24 of file test_Matrix3.cpp.

31 {
32  check_equal( A.length(), B.length(), eps, sA, sB, line, file );
33 
34  double angle = find_angle( A, B );
35 
36  if( ( fabs( A[0] - B[0] ) <= eps || fabs( A[0] + B[0] ) <= eps ) &&
37  ( fabs( A[1] - B[1] ) <= eps || fabs( A[1] + B[1] ) <= eps ) &&
38  ( fabs( A[2] - B[2] ) <= eps || fabs( A[2] + B[2] ) <= eps ) &&
39  ( angle <= eps || fabs( angle - 180.0 ) <= eps ) )
40  return;
41 
42  std::cout << "Equality Test Failed: " << sA << " == " << sB << std::endl;
43  std::cout << " at line " << line << " of '" << file << "'" << std::endl;
44 
45  std::cout << " Expected: ";
46  std::cout << A << std::endl;
47 
48  std::cout << " Actual: ";
49  std::cout << B << std::endl;
50 
51  std::cout << "Angle between vectors := " << angle << std::endl;
52 
53  flag_error();
54 }

References moab::angle(), check_equal(), eps, find_angle(), flag_error(), and moab::CartVect::length().

◆ find_angle()

double find_angle ( const moab::CartVect A,
const moab::CartVect B 
)

Definition at line 12 of file test_Matrix3.cpp.

13 {
14  const double lA = A.length(), lB = B.length();
15  assert( lA > 0.0 );
16  assert( lB > 0.0 );
17  const double dPI = 3.14159265;
18  const double dot = ( A[0] * B[0] + A[1] * B[1] + A[2] * B[2] );
19  return ACOS( dot / ( lA * lB ) ) * 180.0 / dPI;
20 }

References ACOS, moab::dot(), and moab::CartVect::length().

Referenced by check_equal_eigvect().

◆ main()

int main ( )

Definition at line 58 of file test_Matrix3.cpp.

59 {
60 
61  int result = 0;
62 
63  result += RUN_TEST( test_EigenDecomp );
64 
65  return result;
66 }

References RUN_TEST, and test_EigenDecomp().

◆ test_EigenDecomp()

void test_EigenDecomp ( )

Definition at line 70 of file test_Matrix3.cpp.

71 {
72  // Create a matrix
73  moab::Matrix3 mat;
74 
75  mat( 0 ) = 2;
76  mat( 1 ) = -1;
77  mat( 2 ) = 0;
78  mat( 3 ) = -1;
79  mat( 4 ) = 2;
80  mat( 5 ) = -1;
81  mat( 6 ) = 0;
82  mat( 7 ) = -1;
83  mat( 8 ) = 2;
84 
85  // now do the Eigen Decomposition of this Matrix
86 
87  CartVect lamda;
88  Matrix3 vectors;
89  moab::ErrorCode rval = mat.eigen_decomposition( lamda, vectors );CHECK_ERR( rval );
90  for( int i = 0; i < 3; ++i )
91  vectors.col( i ).normalize();
92 
93  // Hardcoded check values for the results
94  double lamda_check[3];
95  lamda_check[0] = 0.585786;
96  lamda_check[1] = 2.0;
97  lamda_check[2] = 3.41421;
98 
99  moab::CartVect vec0_check( 0.5, 0.707107, 0.5 );
100  moab::CartVect vec1_check( 0.707107, 3.37748e-17, -0.707107 );
101  moab::CartVect vec2_check( 0.5, -0.707107, 0.5 );
102 
103  // now verfy that the returns Eigenvalues and Eigenvectors are correct (within some tolerance)
104  double tol = 1e-04;
105 
106  // use a deprecated constructor
107  Matrix3 mat3( CartVect( 2, -1, 0 ), CartVect( -1, 2, -1 ), CartVect( 0, -1, 2 ), true );
108  CHECK_REAL_EQUAL( mat( 1 ), mat3( 1 ), tol );
109 
110  vec0_check.normalize();
111  vec1_check.normalize();
112  vec2_check.normalize();
113 
114  // check that the correct Eigenvalues are returned correctly (in order)
115  CHECK_REAL_EQUAL( lamda[0], lamda_check[0], tol );
116  CHECK_REAL_EQUAL( lamda[1], lamda_check[1], tol );
117  CHECK_REAL_EQUAL( lamda[2], lamda_check[2], tol );
118 
119  // check the Eigenvector values (order should correspond to the Eigenvalues)
120  // first vector
121  CHECK_EIGVECREAL_EQUAL( vectors.col( 0 ), vec0_check, tol );
122 
123  // sceond vector
124  CHECK_EIGVECREAL_EQUAL( vectors.col( 1 ), vec1_check, tol );
125 
126  // third vector
127  CHECK_EIGVECREAL_EQUAL( vectors.col( 2 ), vec2_check, tol );
128 
129  // another check to ensure the result is valid (AM-kM = 0)
130  for( unsigned i = 0; i < 3; ++i )
131  {
132  moab::CartVect v = moab::Matrix::matrix_vector( mat, vectors.col( i ) ) - lamda[i] * vectors.col( i );
133  CHECK_REAL_EQUAL( v.length(), 0, tol );
134  }
135 
136  // for a real, symmetric matrix the Eigenvectors should be orthogonal
137  CHECK_REAL_EQUAL( vectors.col( 0 ) % vectors.col( 1 ), 0, tol );
138  CHECK_REAL_EQUAL( vectors.col( 0 ) % vectors.col( 2 ), 0, tol );
139 
140  return;
141 }

References CHECK_EIGVECREAL_EQUAL, CHECK_ERR, CHECK_REAL_EQUAL, moab::Matrix3::col(), moab::Matrix3::eigen_decomposition(), ErrorCode, moab::CartVect::length(), moab::Matrix::matrix_vector(), and moab::CartVect::normalize().

Referenced by main().