Main MRPT website > C++ reference for MRPT 1.5.7
matrix_ops1_unittest.cpp
Go to the documentation of this file.
1 /* +---------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | http://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2017, Individual contributors, see AUTHORS file |
6  | See: http://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See details in http://www.mrpt.org/License |
8  +---------------------------------------------------------------------------+ */
9 
10 // Note: Matrices unit tests have been split in different files since
11 // building them with eigen3 eats a lot of RAM and may be a problem while
12 // compiling in small systems.
13 
15 #include <mrpt/math/CMatrixD.h>
16 #include <mrpt/math/matrix_serialization.h> // serialization of matrices
17 #include <mrpt/math/ops_matrices.h>
20 #include <mrpt/random.h>
21 #include <gtest/gtest.h>
22 
23 using namespace mrpt;
24 using namespace mrpt::utils;
25 using namespace mrpt::math;
26 using namespace mrpt::random;
27 using namespace mrpt::utils::metaprogramming;
28 using namespace std;
29 
30 
31 const double dat_A[] = { 4, 5, 8, -2, 1, 3 };
32 const double dat_B[] = { 2, 6, 9, 8 };
33 const double dat_Cok[] = {53,64, -2,32, 29,30 };
34 
35 
36 #define CHECK_AND_RET_ERROR(_COND_,_MSG_) EXPECT_FALSE(_COND_) << _MSG_;
37 
38 TEST(Matrices, A_times_B_dyn)
39 {
40  // Dyn. size, double.
41  CMatrixDouble A(3,2, dat_A);
42  CMatrixDouble B(2,2, dat_B);
43  CMatrixDouble C = A*B;
44  CMatrixDouble C_ok(3,2, dat_Cok);
45  CMatrixDouble err = C - C_ok;
46  EXPECT_NEAR(0,fabs(err.sum()), 1e-5) <<
47  "A: " << A <<
48  "B: " << B <<
49  "A*B: " << C << endl;
50 }
51 
52 TEST(Matrices,A_times_B_fix)
53 {
54  // Fix. size, double.
58 
59  C = A * B;
60  Err = C - CMatrixFixedNumeric<double,3,2>(C_ok);
61 
62  EXPECT_NEAR(0,fabs(Err.sum()), 1e-5) <<
63  "A: " << A <<
64  "B: " << B <<
65  "A*B: " << C << endl;
66 }
67 
68 TEST(Matrices,SerializeCMatrixD)
69 {
70  CMatrixDouble A(3,2, dat_A);
72 
73  CMatrixD As = A;
74 
75  CMemoryStream membuf;
76  membuf << As;
77  membuf.Seek(0);
78  membuf >> fA;
79 
80  EXPECT_NEAR(0,fabs((CMatrixDouble(fA) - A).sum()), 1e-9);
81 
82  try
83  {
84  // Now, if we try to de-serialize into the wrong type, we should get an exception:
85  membuf.Seek(0);
87  membuf >> fB; // Wrong size!
88 
89  GTEST_FAIL() << "Exception not launched when it was expected!";
90  }
91  catch(...)
92  { // OK, exception occurred, as expected
93  }
94 }
95 
96 
97 TEST(Matrices,EigenVal2x2dyn)
98 {
99  const double dat_C1[] = { 14.6271, 5.8133, 5.8133, 16.8805 };
100  CMatrixDouble C1(2,2, dat_C1);
101 
102  Eigen::MatrixXd C1_V,C1_D;
103  C1.eigenVectors(C1_V,C1_D);
104 
105  CMatrixDouble C1_RR = C1_V * C1_D * C1_V.transpose();
106  EXPECT_NEAR( (C1_RR-C1).array().abs().sum(),0,1e-4);
107 }
108 
109 TEST(Matrices,EigenVal3x3dyn)
110 {
111  const double dat_C1[] = { 8,6,1, 6,9,4, 1,4,10 };
112  CMatrixDouble C1(3,3, dat_C1);
113 
114  Eigen::MatrixXd C1_V,C1_D;
115  C1.eigenVectors(C1_V,C1_D);
116 
117  CMatrixDouble C1_RR = C1_V*C1_D*C1_V.transpose();
118  EXPECT_NEAR( (C1_RR-C1).array().abs().sum(),0,1e-4);
119 }
120 
121 TEST(Matrices,EigenVal2x2fix)
122 {
123  const double dat_C1[] = { 14.6271, 5.8133, 5.8133, 16.8805 };
124  CMatrixDouble22 C1(dat_C1);
125 
126  Eigen::Matrix2d C1_V,C1_D;
127  C1.eigenVectors(C1_V,C1_D);
128 
129  CMatrixDouble22 C1_RR = C1_V*C1_D*(~C1_V);
130  EXPECT_NEAR( (C1_RR-C1).array().abs().sum(),0,1e-4);
131 }
132 
133 TEST(Matrices,EigenVal3x3fix)
134 {
135  const double dat_C1[] = { 8,6,1, 6,9,4, 1,4,10 };
136  CMatrixDouble33 C1(dat_C1);
137 
138  CMatrixDouble33 C1_V, C1_D;
139  C1.eigenVectors(C1_V,C1_D);
140 
141  CMatrixDouble33 C1_RR = C1_V*C1_D*(~C1_V);
142  EXPECT_NEAR( (C1_RR-C1).array().abs().sum(),0,1e-4);
143 }
144 
145 #if 0 // JL: Disabled since it fails in some PPA build servers. Reported to Eigen list for possible fixes...
146 
147 // Compare the two ways of computing matrix eigenvectors: generic & for symmetric matrices:
148 TEST(Matrices,EigenVal4x4_sym_vs_generic)
149 {
150  const double dat_C1[] = {
151  13.737245,10.248641,-5.839599,11.108320,
152  10.248641,14.966139,-5.259922,11.662222,
153  -5.839599,-5.259922,9.608822,-4.342505,
154  11.108320,11.662222,-4.342505,12.121940 };
155  const CMatrixDouble44 C1(dat_C1);
156 
157  CMatrixDouble44 eigvecs_sym, eigvecs_gen, eigvals_symM, eigvals_genM;
158  CVectorDouble eigvals_sym, eigvals_gen;
159 
160  C1.eigenVectorsVec(eigvecs_gen,eigvals_gen);
161  C1.eigenVectorsSymmetricVec(eigvecs_sym,eigvals_sym);
162 
163  eigvals_symM.setZero();eigvals_symM.diagonal() = eigvals_sym;
164  eigvals_genM.setZero();eigvals_genM.diagonal() = eigvals_gen;
165 
166  EXPECT_NEAR( (C1-eigvecs_gen*eigvals_genM*(~eigvecs_gen)).array().abs().sum(),0,1e-5)
167  << endl << endl
168  << "eigvecs_gen*eigvals_gen*(~eigvecs_gen):\n" << eigvecs_gen*eigvals_genM*(~eigvecs_gen) << endl
169  << "C1:\n" << C1 << endl
170  << "eigvals_sym:\n" << eigvals_sym << endl
171  << "eigvals_gen:\n" << eigvals_gen << endl
172  << "eigvals_symM:\n" << eigvals_symM << endl
173  << "eigvals_genM:\n" << eigvals_genM << endl
174  << "eigvecs_gen:\n" << eigvecs_gen << endl
175  << "eigvecs_sym:\n" << eigvecs_sym << endl<< endl;
176 
177  EXPECT_NEAR( (C1-eigvecs_sym*eigvals_symM*(~eigvecs_sym)).array().abs().sum(),0,1e-5)
178  << endl << endl
179  << "eigvecs_sym*eigvals_sym*(~eigvecs_sym):\n" << eigvecs_sym*eigvals_symM*(~eigvecs_sym) << endl
180  << "C1:\n" << C1 << endl;
181 
182  EXPECT_NEAR( (eigvals_gen-eigvals_sym).array().abs().sum(),0,1e-5)
183  << endl << endl
184  << "eigvals_gen:\n" << eigvals_gen<< endl
185  << "eigvals_sym:\n" << eigvals_sym << endl;
186 }
187 #endif
188 
A namespace of pseudo-random numbers genrators of diferent distributions.
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
Definition: zip.h:16
This class is a "CSerializable" wrapper for "CMatrixTemplateNumeric<double>".
Definition: CMatrixD.h:30
const double dat_A[]
Column vector, like Eigen::MatrixX*, but automatically initialized to zeros since construction...
Definition: eigen_frwds.h:35
This file implements miscelaneous matrix and matrix/vector operations, and internal functions in mrpt...
STL namespace.
A numeric matrix of compile-time fixed size.
This base provides a set of functions for maths stuff.
Definition: CArrayNumeric.h:19
This CStream derived class allow using a memory buffer as a CStream.
Definition: CMemoryStream.h:26
CMatrixTemplateNumeric< double > CMatrixDouble
Declares a matrix of double numbers (non serializable).
CONTAINER::Scalar sum(const CONTAINER &v)
Computes the sum of all the elements.
TEST(Matrices, A_times_B_dyn)
A set of utility objects for metaprogramming with STL algorithms.
const double dat_Cok[]
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
This file implements matrix/vector text and binary serialization.
uint64_t Seek(int64_t Offset, CStream::TSeekOrigin Origin=sFromBeginning) MRPT_OVERRIDE
Introduces a pure virtual method for moving to a specified position in the streamed resource...
const double dat_B[]



Page generated by Doxygen 1.8.14 for MRPT 1.5.7 Git: 5902e14cc Wed Apr 24 15:04:01 2019 +0200 at lun oct 28 01:39:17 CET 2019