Main MRPT website > C++ reference for MRPT 1.5.7
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-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 
12 #include <mrpt/random.h>
13 #include <gtest/gtest.h>
14 
15 using namespace mrpt;
16 using namespace mrpt::utils;
17 using namespace mrpt::math;
18 using namespace std;
19 
20 
21 void generateRandomSparseMatrix(size_t N, size_t M, size_t nEntries, CSparseMatrix &MAT)
22 {
23  MAT.clear();
24 
25  MAT.setRowCount(N);
26  MAT.setColCount(M);
27 
28  for (size_t i=0;i<nEntries;i++)
29  {
30  MAT.insert_entry(
31  mrpt::random::randomGenerator.drawUniform32bit() % N,
32  mrpt::random::randomGenerator.drawUniform32bit() % M,
33  mrpt::random::randomGenerator.drawGaussian1D(0,1) );
34  }
35 
36  // Return already compressed:
37  MAT.compressFromTriplet();
38 }
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 ) <<
52  "Failed with N=" << N << "\n";
53 }
54 
55 TEST(SparseMatrix, InitFromDenseUnit)
56 {
60 }
61 
62 
63 void do_test_init_random(size_t N)
64 {
65  CMatrixDouble dense1;
67  CSparseMatrix SM(dense1);
68  CMatrixDouble dense_out;
69  SM.get_dense(dense_out);
70  EXPECT_TRUE( dense_out==dense1 ) <<
71  "Failed with N=" << N << "\n";
72 }
73 
74 TEST(SparseMatrix, InitFromDenseRandom)
75 {
79 }
80 
81 
82 TEST(SparseMatrix, InitFromTriplet)
83 {
84  CSparseMatrix SM;
85  CMatrixDouble D(10,20);
86 
87  SM.insert_entry(2,2, 4.0); D(2,2) = 4.0;
88  SM.insert_entry(6,8, -2.0); D(6,8) = -2.0;
89 
90  SM.setRowCount(10);
91  SM.setColCount(20);
92 
93  CMatrixDouble dense_out1;
94  SM.get_dense(dense_out1);
95 
97 
98  CMatrixDouble dense_out2;
99  SM.get_dense(dense_out2);
100 
101  EXPECT_TRUE(dense_out1==dense_out2);
102 }
103 
104 
105 TEST(SparseMatrix, InitFromSparse)
106 {
107  CMatrixDouble D(4,5);
109  D(1,2) = 2.0;
110  S(1,2) = 2.0;
111 
112  D(3,1) = -7.0;
113  S(3,1) = -7.0;
114 
115  CSparseMatrix SM(S);
116  CMatrixDouble dense_out;
117  SM.get_dense(dense_out);
118  EXPECT_TRUE( dense_out==D )
119  << "Dense: \n" << D
120  << "Sparse:\n" << dense_out << endl;
121 }
122 
123 TEST(SparseMatrix, InitFromRandom)
124 {
125  CSparseMatrix SM;
126  generateRandomSparseMatrix(100,100, 25, SM);
127  generateRandomSparseMatrix(20,10, 15, SM);
128 }
129 
132 
134  size_t nRows1, size_t nCols1, size_t nNonZeros1,
135  size_t nRows2, size_t nCols2, size_t nNonZeros2,
137 {
138  CSparseMatrix SM1, SM2;
139  generateRandomSparseMatrix(nRows1,nCols1,nNonZeros1, SM1);
140  generateRandomSparseMatrix(nRows2,nCols2,nNonZeros2, SM2);
141 
142  CSparseMatrix SM_res;
143  (*op1)(SM1,SM2,SM_res);
144 
145  // Check:
146  CMatrixDouble D1,D2,Dres;
147  SM1.get_dense(D1);
148  SM2.get_dense(D2);
149  SM_res.get_dense(Dres);
150 
151  CMatrixDouble RES;
152  (*op2)(D1,D2,RES);
153 
154  const double err = (RES-Dres).array().abs().maxCoeff();
155 
156  EXPECT_TRUE(err<1e-10)
157  << "M1:\n" << D1
158  << "M2:\n" << D2
159  << "Real op result:\n" << RES
160  << "SM result:\n" << Dres
161  << "ERR:\n" << (RES-Dres);
162 }
163 
164 void op_sparse_add(const CSparseMatrix &M1, const CSparseMatrix &M2, CSparseMatrix &res) { res = M1+M2; }
165 void op_dense_add(const CMatrixDouble &M1, const CMatrixDouble &M2, CMatrixDouble &res) { res = M1+M2; }
166 
167 
168 TEST(SparseMatrix, Op_Add)
169 {
170  do_matrix_op_test(1,1,0, 1,1,0, &op_sparse_add, &op_dense_add);
171  do_matrix_op_test(1,1,1, 1,1,1, &op_sparse_add, &op_dense_add);
172  do_matrix_op_test(2,2,1, 2,2,1, &op_sparse_add, &op_dense_add);
173  do_matrix_op_test(10,20,33, 10,20,33, &op_sparse_add, &op_dense_add);
174  do_matrix_op_test(11,21,34, 11,21,34, &op_sparse_add, &op_dense_add);
175 }
176 
177 void op_sparse_multiply_AB(const CSparseMatrix &M1, const CSparseMatrix &M2, CSparseMatrix &res) { res = M1*M2; }
178 void op_dense_multiply_AB(const CMatrixDouble &M1, const CMatrixDouble &M2, CMatrixDouble &res) { res = M1*M2; }
179 
180 
181 TEST(SparseMatrix, Op_Multiply_AB)
182 {
188 }
189 
190 
191 TEST(SparseMatrix, CholeskyDecomp)
192 {
193  CSparseMatrix SM(10,10);
196 
197  SM.insert_submatrix(0,0, COV1);
198  SM.insert_submatrix(6,6, COV2);
199  SM.compressFromTriplet();
200 
202 
203  const CMatrixDouble L = Chol.get_L(); // lower triangle
204 
205  // Compare with the dense matrix implementation:
206  CMatrixDouble D;
207  SM.get_dense(D);
208 
209  CMatrixDouble Ud; // Upper triangle
210  D.chol(Ud);
211 
212  const double err = ((Ud.transpose())-L).array().abs().mean();
213  EXPECT_TRUE(err<1e-8);
214 }
215 
Classes for serialization, sockets, ini-file manipulation, streams, list of properties-values, timewatch, extensions to STL.
Definition: zip.h:16
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)
BASE_IMPEXP CRandomGenerator randomGenerator
A static instance of a CRandomGenerator class, for use in single-thread applications.
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:92
STL namespace.
void compressFromTriplet()
ONLY for TRIPLET matrices: convert the matrix in a column-compressed form.
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.
Definition: CArrayNumeric.h:19
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...
mrpt::math::CMatrixDouble 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*...
This is the global namespace for all Mobile Robot Programming Toolkit (MRPT) libraries.
void(* TMatrixSMOperator)(const CSparseMatrix &M1, const CSparseMatrix &M2, CSparseMatrix &res)
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:6298
void op_sparse_add(const CSparseMatrix &M1, const CSparseMatrix &M2, CSparseMatrix &res)
void generateRandomSparseMatrix(size_t N, size_t M, size_t nEntries, CSparseMatrix &MAT)
void(* TMatrixDenseOperator)(const CMatrixDouble &M1, const CMatrixDouble &M2, CMatrixDouble &res)



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