MRPT  1.9.9
CSparseMatrix_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-2018, 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 
11 #include <mrpt/random.h>
12 #include <CTraitsTest.h>
13 #include <gtest/gtest.h>
14 
15 using namespace mrpt;
16 using namespace mrpt::math;
17 using namespace std;
18 
19 template class mrpt::CTraitsTest<mrpt::math::CSparseMatrix>;
20 
22  size_t N, size_t M, size_t nEntries, CSparseMatrix& MAT)
23 {
24  MAT.clear();
25 
26  MAT.setRowCount(N);
27  MAT.setColCount(M);
28 
29  for (size_t i = 0; i < nEntries; i++)
30  {
31  MAT.insert_entry(
32  mrpt::random::getRandomGenerator().drawUniform32bit() % N,
33  mrpt::random::getRandomGenerator().drawUniform32bit() % M,
34  mrpt::random::getRandomGenerator().drawGaussian1D(0, 1));
35  }
36 
37  // Return already compressed:
38  MAT.compressFromTriplet();
39 }
40 
41 void do_test_init_to_unit(size_t N)
42 {
43  CMatrixDouble dense1;
44  dense1.unit(N, 1.0);
45 
46  CSparseMatrix SM(dense1);
47 
48  CMatrixDouble dense_out;
49  SM.get_dense(dense_out);
50 
51  EXPECT_TRUE(dense_out == dense1) << "Failed with N=" << N << "\n";
52 }
53 
54 TEST(SparseMatrix, InitFromDenseUnit)
55 {
59 }
60 
61 void do_test_init_random(size_t N)
62 {
63  CMatrixDouble dense1;
65  CSparseMatrix SM(dense1);
66  CMatrixDouble dense_out;
67  SM.get_dense(dense_out);
68  EXPECT_TRUE(dense_out == dense1) << "Failed with N=" << N << "\n";
69 }
70 
71 TEST(SparseMatrix, InitFromDenseRandom)
72 {
76 }
77 
78 TEST(SparseMatrix, InitFromTriplet)
79 {
80  CSparseMatrix SM;
81  CMatrixDouble D(10, 20);
82 
83  SM.insert_entry(2, 2, 4.0);
84  D(2, 2) = 4.0;
85  SM.insert_entry(6, 8, -2.0);
86  D(6, 8) = -2.0;
87 
88  SM.setRowCount(10);
89  SM.setColCount(20);
90 
91  CMatrixDouble dense_out1;
92  SM.get_dense(dense_out1);
93 
95 
96  CMatrixDouble dense_out2;
97  SM.get_dense(dense_out2);
98 
99  EXPECT_TRUE(dense_out1 == dense_out2);
100 }
101 
102 TEST(SparseMatrix, InitFromSparse)
103 {
104  CMatrixDouble D(4, 5);
106  D(1, 2) = 2.0;
107  S(1, 2) = 2.0;
108 
109  D(3, 1) = -7.0;
110  S(3, 1) = -7.0;
111 
112  CSparseMatrix SM(S);
113  CMatrixDouble dense_out;
114  SM.get_dense(dense_out);
115  EXPECT_TRUE(dense_out == D) << "Dense: \n"
116  << D << "Sparse:\n"
117  << dense_out << endl;
118 }
119 
120 TEST(SparseMatrix, InitFromRandom)
121 {
122  CSparseMatrix SM;
123  generateRandomSparseMatrix(100, 100, 25, SM);
124  generateRandomSparseMatrix(20, 10, 15, SM);
125 }
126 
127 using TMatrixSMOperator = void (*)(
128  const CSparseMatrix& M1, const CSparseMatrix& M2, CSparseMatrix& res);
129 using TMatrixDenseOperator = void (*)(
130  const CMatrixDouble& M1, const CMatrixDouble& M2, CMatrixDouble& res);
131 
133  size_t nRows1, size_t nCols1, size_t nNonZeros1, size_t nRows2,
134  size_t nCols2, size_t nNonZeros2, TMatrixSMOperator op1,
136 {
137  CSparseMatrix SM1, SM2;
138  generateRandomSparseMatrix(nRows1, nCols1, nNonZeros1, SM1);
139  generateRandomSparseMatrix(nRows2, nCols2, nNonZeros2, SM2);
140 
141  CSparseMatrix SM_res;
142  (*op1)(SM1, SM2, SM_res);
143 
144  // Check:
145  CMatrixDouble D1, D2, Dres;
146  SM1.get_dense(D1);
147  SM2.get_dense(D2);
148  SM_res.get_dense(Dres);
149 
150  CMatrixDouble RES;
151  (*op2)(D1, D2, RES);
152 
153  const double err = (RES - Dres).array().abs().maxCoeff();
154 
155  EXPECT_TRUE(err < 1e-10) << "M1:\n"
156  << D1 << "M2:\n"
157  << D2 << "Real op result:\n"
158  << RES << "SM result:\n"
159  << Dres << "ERR:\n"
160  << (RES - Dres);
161 }
162 
164  const CSparseMatrix& M1, const CSparseMatrix& M2, CSparseMatrix& res)
165 {
166  res = M1 + M2;
167 }
169  const CMatrixDouble& M1, const CMatrixDouble& M2, CMatrixDouble& res)
170 {
171  res = M1 + M2;
172 }
173 
174 TEST(SparseMatrix, Op_Add)
175 {
176  do_matrix_op_test(1, 1, 0, 1, 1, 0, &op_sparse_add, &op_dense_add);
177  do_matrix_op_test(1, 1, 1, 1, 1, 1, &op_sparse_add, &op_dense_add);
178  do_matrix_op_test(2, 2, 1, 2, 2, 1, &op_sparse_add, &op_dense_add);
179  do_matrix_op_test(10, 20, 33, 10, 20, 33, &op_sparse_add, &op_dense_add);
180  do_matrix_op_test(11, 21, 34, 11, 21, 34, &op_sparse_add, &op_dense_add);
181 }
182 
184  const CSparseMatrix& M1, const CSparseMatrix& M2, CSparseMatrix& res)
185 {
186  res = M1 * M2;
187 }
189  const CMatrixDouble& M1, const CMatrixDouble& M2, CMatrixDouble& res)
190 {
191  res = M1 * M2;
192 }
193 
194 TEST(SparseMatrix, Op_Multiply_AB)
195 {
197  1, 1, 0, 1, 1, 0, &op_sparse_multiply_AB, &op_dense_multiply_AB);
199  1, 1, 1, 1, 1, 1, &op_sparse_multiply_AB, &op_dense_multiply_AB);
201  2, 2, 1, 2, 2, 1, &op_sparse_multiply_AB, &op_dense_multiply_AB);
203  10, 20, 33, 20, 15, 33, &op_sparse_multiply_AB, &op_dense_multiply_AB);
205  8, 34, 100, 34, 3, 100, &op_sparse_multiply_AB, &op_dense_multiply_AB);
206 }
207 
208 TEST(SparseMatrix, CholeskyDecomp)
209 {
210  CSparseMatrix SM(10, 10);
211  const CMatrixDouble COV1 =
214  const CMatrixDouble COV2 =
217 
218  SM.insert_submatrix(0, 0, COV1);
219  SM.insert_submatrix(6, 6, COV2);
220  SM.compressFromTriplet();
221 
223 
224  const CMatrixDouble L = Chol.get_L(); // lower triangle
225 
226  // Compare with the dense matrix implementation:
227  CMatrixDouble D;
228  SM.get_dense(D);
229 
230  CMatrixDouble Ud; // Upper triangle
231  D.chol(Ud);
232 
233  const double err = ((Ud.transpose()) - L).array().abs().mean();
234  EXPECT_TRUE(err < 1e-8);
235 }
MATRIX drawDefinitePositiveMatrix(const size_t dim, const double std_scale=1.0, const double diagonal_epsilon=1e-8)
Generates a random definite-positive matrix of the given size, using the formula C = v*v^t + epsilon*...
void setColCount(const size_t nCols)
void do_matrix_op_test(size_t nRows1, size_t nCols1, size_t nNonZeros1, size_t nRows2, size_t nCols2, size_t nNonZeros2, TMatrixSMOperator op1, TMatrixDenseOperator op2)
void drawGaussian1DMatrix(MAT &matrix, const double mean=0, const double std=1)
Fills the given matrix with independent, 1D-normally distributed samples.
Auxiliary class to hold the results of a Cholesky factorization of a sparse matrix.
A sparse matrix structure, wrapping T.
Definition: CSparseMatrix.h:95
STL namespace.
void compressFromTriplet()
ONLY for TRIPLET matrices: convert the matrix in a column-compressed form.
void(*)(const CMatrixDouble &M1, const CMatrixDouble &M2, CMatrixDouble &res) TMatrixDenseOperator
void op_dense_multiply_AB(const CMatrixDouble &M1, const CMatrixDouble &M2, CMatrixDouble &res)
void insert_entry(const size_t row, const size_t col, const double val)
@ Access the matrix, get, set elements, etc.
A sparse matrix container (with cells of any type), with iterators.
CMatrixDouble get_L() const
Return the L matrix (L*L&#39; = M), as a dense matrix.
void get_dense(CMatrixDouble &outMat) const
Return a dense representation of the sparse matrix.
This base provides a set of functions for maths stuff.
void op_sparse_multiply_AB(const CSparseMatrix &M1, const CSparseMatrix &M2, CSparseMatrix &res)
void do_test_init_to_unit(size_t N)
TEST(SparseMatrix, InitFromDenseUnit)
void do_test_init_random(size_t N)
void setRowCount(const size_t nRows)
Change the number of rows in the matrix (can&#39;t be lower than current size)
void clear(const size_t nRows=1, const size_t nCols=1)
Erase all previous contents and leave the matrix as a "triplet" ROWS x COLS matrix without any nonzer...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void op_dense_add(const CMatrixDouble &M1, const CMatrixDouble &M2, CMatrixDouble &res)
void insert_submatrix(const size_t row, const size_t col, const MATRIX &M)
ONLY for TRIPLET matrices: insert a given matrix (in any of the MRPT formats) at a given location of ...
typedef void(APIENTRYP PFNGLBLENDCOLORPROC)(GLclampf red
GLuint res
Definition: glext.h:7268
CRandomGenerator & getRandomGenerator()
A static instance of a CRandomGenerator class, for use in single-thread applications.
void op_sparse_add(const CSparseMatrix &M1, const CSparseMatrix &M2, CSparseMatrix &res)
void(*)(const CSparseMatrix &M1, const CSparseMatrix &M2, CSparseMatrix &res) TMatrixSMOperator
void generateRandomSparseMatrix(size_t N, size_t M, size_t nEntries, CSparseMatrix &MAT)



Page generated by Doxygen 1.8.14 for MRPT 1.9.9 Git: 7d5e6d718 Fri Aug 24 01:51:28 2018 +0200 at lun nov 2 08:35:50 CET 2020