MRPT  2.0.1
matrix_ops1_unittest.cpp
Go to the documentation of this file.
1 /* +------------------------------------------------------------------------+
2  | Mobile Robot Programming Toolkit (MRPT) |
3  | https://www.mrpt.org/ |
4  | |
5  | Copyright (c) 2005-2020, Individual contributors, see AUTHORS file |
6  | See: https://www.mrpt.org/Authors - All rights reserved. |
7  | Released under BSD License. See: https://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 
14 #include <gtest/gtest.h>
15 #include <mrpt/io/CMemoryStream.h>
16 #include <mrpt/math/CMatrixD.h>
17 #include <mrpt/math/CMatrixFixed.h>
18 #include <mrpt/math/matrix_serialization.h> // serialization of matrices
19 #include <mrpt/random.h>
21 #include <Eigen/Dense>
22 
23 using namespace mrpt;
24 using namespace mrpt::math;
25 using namespace mrpt::random;
26 using namespace std;
27 
28 const double dat_A[] = {4, 5, 8, -2, 1, 3};
29 const double dat_B[] = {2, 6, 9, 8};
30 const double dat_Cok[] = {53, 64, -2, 32, 29, 30};
31 
32 #define CHECK_AND_RET_ERROR(_COND_, _MSG_) EXPECT_FALSE(_COND_) << _MSG_;
33 
34 TEST(Matrices, DynMat_size)
35 {
36  CMatrixDouble A(3, 2, dat_A);
37  EXPECT_EQ(A.rows(), 3);
38  EXPECT_EQ(A.cols(), 2);
39  EXPECT_EQ(A.size(), 6U);
40 }
41 
42 TEST(Matrices, A_times_B_dyn)
43 {
44  // Dyn. size, double.
45  CMatrixDouble A(3, 2, dat_A);
46  CMatrixDouble B(2, 2, dat_B);
47  CMatrixDouble C = CMatrixDouble(A * B);
48  CMatrixDouble C_ok(3, 2, dat_Cok);
49  CMatrixDouble err = C - C_ok;
50  EXPECT_NEAR(0, fabs(err.sum()), 1e-5)
51  << "A: " << A << "B: " << B << "A*B: " << C << endl;
52 }
53 
54 TEST(Matrices, A_times_B_fix)
55 {
56  // Fix. size, double.
59  CMatrixFixed<double, 3, 2> C, C_ok(dat_Cok), Err;
60 
61  C = A * B;
62  Err = C.asEigen() - CMatrixFixed<double, 3, 2>(C_ok).asEigen();
63 
64  EXPECT_NEAR(0, fabs(Err.asEigen().array().sum()), 1e-5);
65 }
66 
67 TEST(Matrices, SerializeCMatrixD)
68 {
69  CMatrixDouble A(3, 2, dat_A);
71 
72  CMatrixD As = CMatrixD(A);
73 
75  auto arch = mrpt::serialization::archiveFrom(membuf);
76  arch << As;
77  membuf.Seek(0);
78  arch >> 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
85  // exception:
86  membuf.Seek(0);
88  arch >> fB; // Wrong size!
89 
90  GTEST_FAIL() << "Exception not launched when it was expected!";
91  }
92  catch (...)
93  { // OK, exception occurred, as expected
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  CMatrixDouble C1_V;
103  std::vector<double> C1_Ds;
104  C1.eig(C1_V, C1_Ds);
105 
106  CMatrixDouble C1_D;
107  C1_D.setDiagonal(C1_Ds);
108 
109  CMatrixDouble C1_RR =
110  CMatrixDouble(C1_V.asEigen() * C1_D.asEigen() * C1_V.transpose());
111  EXPECT_NEAR((C1_RR - C1).sum_abs(), 0, 1e-4);
112 }
113 
114 TEST(Matrices, eig_symmetric)
115 {
116  // Test by looking only at the lower triangular-part:
117  {
118  const double dat_C[] = {14.6271, 0, 5.8133, 16.8805};
119  CMatrixDouble22 C(dat_C);
120 
121  CMatrixDouble22 eig_vecs;
122  std::vector<double> eig_vals;
123  C.eig_symmetric(eig_vecs, eig_vals);
124 
125  EXPECT_EQ(eig_vals.size(), 2UL);
126  EXPECT_NEAR(eig_vals[0], 9.83232131811656, 1e-4);
127  EXPECT_NEAR(eig_vals[1], 21.67527868188344, 1e-4);
128  }
129 }
130 
131 TEST(Matrices, EigenVal3x3dyn)
132 {
133  const double dat_C1[] = {8, 6, 1, 6, 9, 4, 1, 4, 10};
134  CMatrixDouble C1(3, 3, dat_C1);
135 
136  CMatrixDouble C1_V;
137  std::vector<double> C1_Ds;
138  C1.eig(C1_V, C1_Ds);
139 
140  CMatrixDouble C1_D;
141  C1_D.setDiagonal(C1_Ds);
142 
143  CMatrixDouble C1_RR =
144  CMatrixDouble(C1_V.asEigen() * C1_D.asEigen() * C1_V.transpose());
145  EXPECT_NEAR((C1_RR - C1).sum_abs(), 0, 1e-4);
146 }
147 
148 TEST(Matrices, EigenVal2x2fix)
149 {
150  const double dat_C1[] = {14.6271, 5.8133, 5.8133, 16.8805};
151  CMatrixDouble22 C1(dat_C1);
152 
153  CMatrixDouble22 C1_V;
154  std::vector<double> C1_Ds;
155  C1.eig(C1_V, C1_Ds);
156 
157  CMatrixDouble22 C1_D;
158  C1_D.setDiagonal(C1_Ds);
159 
160  CMatrixDouble22 C1_RR =
161  CMatrixDouble22(C1_V.asEigen() * C1_D.asEigen() * C1_V.transpose());
162  EXPECT_NEAR((C1_RR - C1).sum_abs(), 0, 1e-4);
163 }
164 
165 TEST(Matrices, EigenVal3x3fix)
166 {
167  const double dat_C1[] = {8, 6, 1, 6, 9, 4, 1, 4, 10};
168  CMatrixDouble33 C1(dat_C1);
169 
170  CMatrixDouble33 C1_V;
171  std::vector<double> C1_Ds;
172  C1.eig(C1_V, C1_Ds);
173 
174  CMatrixDouble33 C1_D;
175  C1_D.setDiagonal(C1_Ds);
176 
177  CMatrixDouble33 C1_RR =
178  CMatrixDouble33(C1_V.asEigen() * C1_D.asEigen() * C1_V.transpose());
179  EXPECT_NEAR((C1_RR - C1).sum_abs(), 0, 1e-4);
180 }
A namespace of pseudo-random numbers generators of diferent distributions.
bool eig(Derived &eVecs, std::vector< Scalar > &eVals, bool sorted=true) const
Computes the eigenvectors and eigenvalues for a square, general matrix.
A compile-time fixed-size numeric matrix container.
Definition: CMatrixFixed.h:33
This class is a "CSerializable" wrapper for "CMatrixDynamic<double>".
Definition: CMatrixD.h:23
const double dat_A[]
STL namespace.
bool eig_symmetric(Derived &eVecs, std::vector< Scalar > &eVals, bool sorted=true) const
Read: eig()
CArchiveStreamBase< STREAM > archiveFrom(STREAM &s)
Helper function to create a templatized wrapper CArchive object for a: MRPT&#39;s CStream, std::istream, std::ostream, std::stringstream.
Definition: CArchive.h:592
CMatrixFixed< double, 3, 3 > CMatrixDouble33
Definition: CMatrixFixed.h:367
This base provides a set of functions for maths stuff.
This CStream derived class allow using a memory buffer as a CStream.
CONTAINER::Scalar sum(const CONTAINER &v)
Computes the sum of all the elements.
uint64_t Seek(int64_t Offset, CStream::TSeekOrigin Origin=sFromBeginning) override
Introduces a pure virtual method for moving to a specified position in the streamed resource...
CMatrixFixed< double, 2, 2 > CMatrixDouble22
Definition: CMatrixFixed.h:364
const double dat_Cok[]
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
Scalar sum() const
Sum of all elements in matrix/vector.
This file implements matrix/vector text and binary serialization.
EXPECT_EQ(out.image_pair_was_used.size(), NUM_IMGS)
EIGEN_MAP asEigen()
Get as an Eigen-compatible Eigen::Map object.
Definition: CMatrixFixed.h:251
EXPECT_NEAR(out.cam_params.rightCameraPose.x, 0.1194, 0.005)
TEST(Matrices, DynMat_size)
EIGEN_MAP asEigen()
Get as an Eigen-compatible Eigen::Map object.
void setDiagonal(const std::size_t N, const Scalar value)
Resize to NxN, set all entries to zero, except the main diagonal which is set to value ...
Definition: MatrixBase.h:34
const double dat_B[]
CMatrixDynamic< double > CMatrixDouble
Declares a matrix of double numbers (non serializable).



Page generated by Doxygen 1.8.14 for MRPT 2.0.1 Git: 0fef1a6d7 Fri Apr 3 23:00:21 2020 +0200 at vie abr 3 23:20:28 CEST 2020