source: pacpussensors/trunk/Vislab/lib3dv/eigen/test/eigen2/eigen2_sparse_basic.cpp@ 136

Last change on this file since 136 was 136, checked in by ldecherf, 7 years ago

Doc

File size: 10.5 KB
Line 
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra. Eigen itself is part of the KDE project.
3//
4// Copyright (C) 2008 Daniel Gomez Ferro <dgomezferro@gmail.com>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
10#include "sparse.h"
11
12template<typename SetterType,typename DenseType, typename Scalar, int Options>
13bool test_random_setter(SparseMatrix<Scalar,Options>& sm, const DenseType& ref, const std::vector<Vector2i>& nonzeroCoords)
14{
15 typedef SparseMatrix<Scalar,Options> SparseType;
16 {
17 sm.setZero();
18 SetterType w(sm);
19 std::vector<Vector2i> remaining = nonzeroCoords;
20 while(!remaining.empty())
21 {
22 int i = ei_random<int>(0,remaining.size()-1);
23 w(remaining[i].x(),remaining[i].y()) = ref.coeff(remaining[i].x(),remaining[i].y());
24 remaining[i] = remaining.back();
25 remaining.pop_back();
26 }
27 }
28 return sm.isApprox(ref);
29}
30
31template<typename SetterType,typename DenseType, typename T>
32bool test_random_setter(DynamicSparseMatrix<T>& sm, const DenseType& ref, const std::vector<Vector2i>& nonzeroCoords)
33{
34 sm.setZero();
35 std::vector<Vector2i> remaining = nonzeroCoords;
36 while(!remaining.empty())
37 {
38 int i = ei_random<int>(0,remaining.size()-1);
39 sm.coeffRef(remaining[i].x(),remaining[i].y()) = ref.coeff(remaining[i].x(),remaining[i].y());
40 remaining[i] = remaining.back();
41 remaining.pop_back();
42 }
43 return sm.isApprox(ref);
44}
45
46template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& ref)
47{
48 const int rows = ref.rows();
49 const int cols = ref.cols();
50 typedef typename SparseMatrixType::Scalar Scalar;
51 enum { Flags = SparseMatrixType::Flags };
52
53 double density = std::max(8./(rows*cols), 0.01);
54 typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
55 typedef Matrix<Scalar,Dynamic,1> DenseVector;
56 Scalar eps = 1e-6;
57
58 SparseMatrixType m(rows, cols);
59 DenseMatrix refMat = DenseMatrix::Zero(rows, cols);
60 DenseVector vec1 = DenseVector::Random(rows);
61 Scalar s1 = ei_random<Scalar>();
62
63 std::vector<Vector2i> zeroCoords;
64 std::vector<Vector2i> nonzeroCoords;
65 initSparse<Scalar>(density, refMat, m, 0, &zeroCoords, &nonzeroCoords);
66
67 if (zeroCoords.size()==0 || nonzeroCoords.size()==0)
68 return;
69
70 // test coeff and coeffRef
71 for (int i=0; i<(int)zeroCoords.size(); ++i)
72 {
73 VERIFY_IS_MUCH_SMALLER_THAN( m.coeff(zeroCoords[i].x(),zeroCoords[i].y()), eps );
74 if(ei_is_same_type<SparseMatrixType,SparseMatrix<Scalar,Flags> >::ret)
75 VERIFY_RAISES_ASSERT( m.coeffRef(zeroCoords[0].x(),zeroCoords[0].y()) = 5 );
76 }
77 VERIFY_IS_APPROX(m, refMat);
78
79 m.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);
80 refMat.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);
81
82 VERIFY_IS_APPROX(m, refMat);
83 /*
84 // test InnerIterators and Block expressions
85 for (int t=0; t<10; ++t)
86 {
87 int j = ei_random<int>(0,cols-1);
88 int i = ei_random<int>(0,rows-1);
89 int w = ei_random<int>(1,cols-j-1);
90 int h = ei_random<int>(1,rows-i-1);
91
92// VERIFY_IS_APPROX(m.block(i,j,h,w), refMat.block(i,j,h,w));
93 for(int c=0; c<w; c++)
94 {
95 VERIFY_IS_APPROX(m.block(i,j,h,w).col(c), refMat.block(i,j,h,w).col(c));
96 for(int r=0; r<h; r++)
97 {
98// VERIFY_IS_APPROX(m.block(i,j,h,w).col(c).coeff(r), refMat.block(i,j,h,w).col(c).coeff(r));
99 }
100 }
101// for(int r=0; r<h; r++)
102// {
103// VERIFY_IS_APPROX(m.block(i,j,h,w).row(r), refMat.block(i,j,h,w).row(r));
104// for(int c=0; c<w; c++)
105// {
106// VERIFY_IS_APPROX(m.block(i,j,h,w).row(r).coeff(c), refMat.block(i,j,h,w).row(r).coeff(c));
107// }
108// }
109 }
110
111 for(int c=0; c<cols; c++)
112 {
113 VERIFY_IS_APPROX(m.col(c) + m.col(c), (m + m).col(c));
114 VERIFY_IS_APPROX(m.col(c) + m.col(c), refMat.col(c) + refMat.col(c));
115 }
116
117 for(int r=0; r<rows; r++)
118 {
119 VERIFY_IS_APPROX(m.row(r) + m.row(r), (m + m).row(r));
120 VERIFY_IS_APPROX(m.row(r) + m.row(r), refMat.row(r) + refMat.row(r));
121 }
122 */
123
124 // test SparseSetters
125 // coherent setter
126 // TODO extend the MatrixSetter
127// {
128// m.setZero();
129// VERIFY_IS_NOT_APPROX(m, refMat);
130// SparseSetter<SparseMatrixType, FullyCoherentAccessPattern> w(m);
131// for (int i=0; i<nonzeroCoords.size(); ++i)
132// {
133// w->coeffRef(nonzeroCoords[i].x(),nonzeroCoords[i].y()) = refMat.coeff(nonzeroCoords[i].x(),nonzeroCoords[i].y());
134// }
135// }
136// VERIFY_IS_APPROX(m, refMat);
137
138 // random setter
139// {
140// m.setZero();
141// VERIFY_IS_NOT_APPROX(m, refMat);
142// SparseSetter<SparseMatrixType, RandomAccessPattern> w(m);
143// std::vector<Vector2i> remaining = nonzeroCoords;
144// while(!remaining.empty())
145// {
146// int i = ei_random<int>(0,remaining.size()-1);
147// w->coeffRef(remaining[i].x(),remaining[i].y()) = refMat.coeff(remaining[i].x(),remaining[i].y());
148// remaining[i] = remaining.back();
149// remaining.pop_back();
150// }
151// }
152// VERIFY_IS_APPROX(m, refMat);
153
154 VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, StdMapTraits> >(m,refMat,nonzeroCoords) ));
155 #ifdef EIGEN_UNORDERED_MAP_SUPPORT
156 VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, StdUnorderedMapTraits> >(m,refMat,nonzeroCoords) ));
157 #endif
158 #ifdef _DENSE_HASH_MAP_H_
159 VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, GoogleDenseHashMapTraits> >(m,refMat,nonzeroCoords) ));
160 #endif
161 #ifdef _SPARSE_HASH_MAP_H_
162 VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, GoogleSparseHashMapTraits> >(m,refMat,nonzeroCoords) ));
163 #endif
164
165 // test fillrand
166 {
167 DenseMatrix m1(rows,cols);
168 m1.setZero();
169 SparseMatrixType m2(rows,cols);
170 m2.startFill();
171 for (int j=0; j<cols; ++j)
172 {
173 for (int k=0; k<rows/2; ++k)
174 {
175 int i = ei_random<int>(0,rows-1);
176 if (m1.coeff(i,j)==Scalar(0))
177 m2.fillrand(i,j) = m1(i,j) = ei_random<Scalar>();
178 }
179 }
180 m2.endFill();
181 VERIFY_IS_APPROX(m2,m1);
182 }
183
184 // test RandomSetter
185 /*{
186 SparseMatrixType m1(rows,cols), m2(rows,cols);
187 DenseMatrix refM1 = DenseMatrix::Zero(rows, rows);
188 initSparse<Scalar>(density, refM1, m1);
189 {
190 Eigen::RandomSetter<SparseMatrixType > setter(m2);
191 for (int j=0; j<m1.outerSize(); ++j)
192 for (typename SparseMatrixType::InnerIterator i(m1,j); i; ++i)
193 setter(i.index(), j) = i.value();
194 }
195 VERIFY_IS_APPROX(m1, m2);
196 }*/
197// std::cerr << m.transpose() << "\n\n" << refMat.transpose() << "\n\n";
198// VERIFY_IS_APPROX(m, refMat);
199
200 // test basic computations
201 {
202 DenseMatrix refM1 = DenseMatrix::Zero(rows, rows);
203 DenseMatrix refM2 = DenseMatrix::Zero(rows, rows);
204 DenseMatrix refM3 = DenseMatrix::Zero(rows, rows);
205 DenseMatrix refM4 = DenseMatrix::Zero(rows, rows);
206 SparseMatrixType m1(rows, rows);
207 SparseMatrixType m2(rows, rows);
208 SparseMatrixType m3(rows, rows);
209 SparseMatrixType m4(rows, rows);
210 initSparse<Scalar>(density, refM1, m1);
211 initSparse<Scalar>(density, refM2, m2);
212 initSparse<Scalar>(density, refM3, m3);
213 initSparse<Scalar>(density, refM4, m4);
214
215 VERIFY_IS_APPROX(m1+m2, refM1+refM2);
216 VERIFY_IS_APPROX(m1+m2+m3, refM1+refM2+refM3);
217 VERIFY_IS_APPROX(m3.cwise()*(m1+m2), refM3.cwise()*(refM1+refM2));
218 VERIFY_IS_APPROX(m1*s1-m2, refM1*s1-refM2);
219
220 VERIFY_IS_APPROX(m1*=s1, refM1*=s1);
221 VERIFY_IS_APPROX(m1/=s1, refM1/=s1);
222
223 VERIFY_IS_APPROX(m1+=m2, refM1+=refM2);
224 VERIFY_IS_APPROX(m1-=m2, refM1-=refM2);
225
226 VERIFY_IS_APPROX(m1.col(0).eigen2_dot(refM2.row(0)), refM1.col(0).eigen2_dot(refM2.row(0)));
227
228 refM4.setRandom();
229 // sparse cwise* dense
230 VERIFY_IS_APPROX(m3.cwise()*refM4, refM3.cwise()*refM4);
231// VERIFY_IS_APPROX(m3.cwise()/refM4, refM3.cwise()/refM4);
232 }
233
234 // test innerVector()
235 {
236 DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);
237 SparseMatrixType m2(rows, rows);
238 initSparse<Scalar>(density, refMat2, m2);
239 int j0 = ei_random(0,rows-1);
240 int j1 = ei_random(0,rows-1);
241 VERIFY_IS_APPROX(m2.innerVector(j0), refMat2.col(j0));
242 VERIFY_IS_APPROX(m2.innerVector(j0)+m2.innerVector(j1), refMat2.col(j0)+refMat2.col(j1));
243 //m2.innerVector(j0) = 2*m2.innerVector(j1);
244 //refMat2.col(j0) = 2*refMat2.col(j1);
245 //VERIFY_IS_APPROX(m2, refMat2);
246 }
247
248 // test innerVectors()
249 {
250 DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);
251 SparseMatrixType m2(rows, rows);
252 initSparse<Scalar>(density, refMat2, m2);
253 int j0 = ei_random(0,rows-2);
254 int j1 = ei_random(0,rows-2);
255 int n0 = ei_random<int>(1,rows-std::max(j0,j1));
256 VERIFY_IS_APPROX(m2.innerVectors(j0,n0), refMat2.block(0,j0,rows,n0));
257 VERIFY_IS_APPROX(m2.innerVectors(j0,n0)+m2.innerVectors(j1,n0),
258 refMat2.block(0,j0,rows,n0)+refMat2.block(0,j1,rows,n0));
259 //m2.innerVectors(j0,n0) = m2.innerVectors(j0,n0) + m2.innerVectors(j1,n0);
260 //refMat2.block(0,j0,rows,n0) = refMat2.block(0,j0,rows,n0) + refMat2.block(0,j1,rows,n0);
261 }
262
263 // test transpose
264 {
265 DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);
266 SparseMatrixType m2(rows, rows);
267 initSparse<Scalar>(density, refMat2, m2);
268 VERIFY_IS_APPROX(m2.transpose().eval(), refMat2.transpose().eval());
269 VERIFY_IS_APPROX(m2.transpose(), refMat2.transpose());
270 }
271
272 // test prune
273 {
274 SparseMatrixType m2(rows, rows);
275 DenseMatrix refM2(rows, rows);
276 refM2.setZero();
277 int countFalseNonZero = 0;
278 int countTrueNonZero = 0;
279 m2.startFill();
280 for (int j=0; j<m2.outerSize(); ++j)
281 for (int i=0; i<m2.innerSize(); ++i)
282 {
283 float x = ei_random<float>(0,1);
284 if (x<0.1)
285 {
286 // do nothing
287 }
288 else if (x<0.5)
289 {
290 countFalseNonZero++;
291 m2.fill(i,j) = Scalar(0);
292 }
293 else
294 {
295 countTrueNonZero++;
296 m2.fill(i,j) = refM2(i,j) = Scalar(1);
297 }
298 }
299 m2.endFill();
300 VERIFY(countFalseNonZero+countTrueNonZero == m2.nonZeros());
301 VERIFY_IS_APPROX(m2, refM2);
302 m2.prune(1);
303 VERIFY(countTrueNonZero==m2.nonZeros());
304 VERIFY_IS_APPROX(m2, refM2);
305 }
306}
307
308void test_eigen2_sparse_basic()
309{
310 for(int i = 0; i < g_repeat; i++) {
311 CALL_SUBTEST_1( sparse_basic(SparseMatrix<double>(8, 8)) );
312 CALL_SUBTEST_2( sparse_basic(SparseMatrix<std::complex<double> >(16, 16)) );
313 CALL_SUBTEST_1( sparse_basic(SparseMatrix<double>(33, 33)) );
314
315 CALL_SUBTEST_3( sparse_basic(DynamicSparseMatrix<double>(8, 8)) );
316 }
317}
Note: See TracBrowser for help on using the repository browser.