00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #include "sparse.h"
00026
00027 template<typename SetterType,typename DenseType, typename Scalar, int Options>
00028 bool test_random_setter(SparseMatrix<Scalar,Options>& sm, const DenseType& ref, const std::vector<Vector2i>& nonzeroCoords)
00029 {
00030 typedef SparseMatrix<Scalar,Options> SparseType;
00031 {
00032 sm.setZero();
00033 SetterType w(sm);
00034 std::vector<Vector2i> remaining = nonzeroCoords;
00035 while(!remaining.empty())
00036 {
00037 int i = ei_random<int>(0,remaining.size()-1);
00038 w(remaining[i].x(),remaining[i].y()) = ref.coeff(remaining[i].x(),remaining[i].y());
00039 remaining[i] = remaining.back();
00040 remaining.pop_back();
00041 }
00042 }
00043 return sm.isApprox(ref);
00044 }
00045
00046 template<typename SetterType,typename DenseType, typename T>
00047 bool test_random_setter(DynamicSparseMatrix<T>& sm, const DenseType& ref, const std::vector<Vector2i>& nonzeroCoords)
00048 {
00049 sm.setZero();
00050 std::vector<Vector2i> remaining = nonzeroCoords;
00051 while(!remaining.empty())
00052 {
00053 int i = ei_random<int>(0,remaining.size()-1);
00054 sm.coeffRef(remaining[i].x(),remaining[i].y()) = ref.coeff(remaining[i].x(),remaining[i].y());
00055 remaining[i] = remaining.back();
00056 remaining.pop_back();
00057 }
00058 return sm.isApprox(ref);
00059 }
00060
00061 template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& ref)
00062 {
00063 const int rows = ref.rows();
00064 const int cols = ref.cols();
00065 typedef typename SparseMatrixType::Scalar Scalar;
00066 enum { Flags = SparseMatrixType::Flags };
00067
00068 double density = std::max(8./(rows*cols), 0.01);
00069 typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
00070 typedef Matrix<Scalar,Dynamic,1> DenseVector;
00071 Scalar eps = 1e-6;
00072
00073 SparseMatrixType m(rows, cols);
00074 DenseMatrix refMat = DenseMatrix::Zero(rows, cols);
00075 DenseVector vec1 = DenseVector::Random(rows);
00076 Scalar s1 = ei_random<Scalar>();
00077
00078 std::vector<Vector2i> zeroCoords;
00079 std::vector<Vector2i> nonzeroCoords;
00080 initSparse<Scalar>(density, refMat, m, 0, &zeroCoords, &nonzeroCoords);
00081
00082 if (zeroCoords.size()==0 || nonzeroCoords.size()==0)
00083 return;
00084
00085
00086 for (int i=0; i<(int)zeroCoords.size(); ++i)
00087 {
00088 VERIFY_IS_MUCH_SMALLER_THAN( m.coeff(zeroCoords[i].x(),zeroCoords[i].y()), eps );
00089 if(ei_is_same_type<SparseMatrixType,SparseMatrix<Scalar,Flags> >::ret)
00090 VERIFY_RAISES_ASSERT( m.coeffRef(zeroCoords[0].x(),zeroCoords[0].y()) = 5 );
00091 }
00092 VERIFY_IS_APPROX(m, refMat);
00093
00094 m.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);
00095 refMat.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);
00096
00097 VERIFY_IS_APPROX(m, refMat);
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113
00114
00115
00116
00117
00118
00119
00120
00121
00122
00123
00124
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169 VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, StdMapTraits> >(m,refMat,nonzeroCoords) ));
00170 #ifdef EIGEN_UNORDERED_MAP_SUPPORT
00171 VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, StdUnorderedMapTraits> >(m,refMat,nonzeroCoords) ));
00172 #endif
00173 #ifdef _DENSE_HASH_MAP_H_
00174 VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, GoogleDenseHashMapTraits> >(m,refMat,nonzeroCoords) ));
00175 #endif
00176 #ifdef _SPARSE_HASH_MAP_H_
00177 VERIFY(( test_random_setter<RandomSetter<SparseMatrixType, GoogleSparseHashMapTraits> >(m,refMat,nonzeroCoords) ));
00178 #endif
00179
00180
00181 {
00182 DenseMatrix m1(rows,cols);
00183 m1.setZero();
00184 SparseMatrixType m2(rows,cols);
00185 m2.startFill();
00186 for (int j=0; j<cols; ++j)
00187 {
00188 for (int k=0; k<rows/2; ++k)
00189 {
00190 int i = ei_random<int>(0,rows-1);
00191 if (m1.coeff(i,j)==Scalar(0))
00192 m2.fillrand(i,j) = m1(i,j) = ei_random<Scalar>();
00193 }
00194 }
00195 m2.endFill();
00196 VERIFY_IS_APPROX(m2,m1);
00197 }
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214
00215
00216 {
00217 DenseMatrix refM1 = DenseMatrix::Zero(rows, rows);
00218 DenseMatrix refM2 = DenseMatrix::Zero(rows, rows);
00219 DenseMatrix refM3 = DenseMatrix::Zero(rows, rows);
00220 DenseMatrix refM4 = DenseMatrix::Zero(rows, rows);
00221 SparseMatrixType m1(rows, rows);
00222 SparseMatrixType m2(rows, rows);
00223 SparseMatrixType m3(rows, rows);
00224 SparseMatrixType m4(rows, rows);
00225 initSparse<Scalar>(density, refM1, m1);
00226 initSparse<Scalar>(density, refM2, m2);
00227 initSparse<Scalar>(density, refM3, m3);
00228 initSparse<Scalar>(density, refM4, m4);
00229
00230 VERIFY_IS_APPROX(m1+m2, refM1+refM2);
00231 VERIFY_IS_APPROX(m1+m2+m3, refM1+refM2+refM3);
00232 VERIFY_IS_APPROX(m3.cwise()*(m1+m2), refM3.cwise()*(refM1+refM2));
00233 VERIFY_IS_APPROX(m1*s1-m2, refM1*s1-refM2);
00234
00235 VERIFY_IS_APPROX(m1*=s1, refM1*=s1);
00236 VERIFY_IS_APPROX(m1/=s1, refM1/=s1);
00237
00238 VERIFY_IS_APPROX(m1+=m2, refM1+=refM2);
00239 VERIFY_IS_APPROX(m1-=m2, refM1-=refM2);
00240
00241 VERIFY_IS_APPROX(m1.col(0).eigen2_dot(refM2.row(0)), refM1.col(0).eigen2_dot(refM2.row(0)));
00242
00243 refM4.setRandom();
00244
00245 VERIFY_IS_APPROX(m3.cwise()*refM4, refM3.cwise()*refM4);
00246
00247 }
00248
00249
00250 {
00251 DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);
00252 SparseMatrixType m2(rows, rows);
00253 initSparse<Scalar>(density, refMat2, m2);
00254 int j0 = ei_random(0,rows-1);
00255 int j1 = ei_random(0,rows-1);
00256 VERIFY_IS_APPROX(m2.innerVector(j0), refMat2.col(j0));
00257 VERIFY_IS_APPROX(m2.innerVector(j0)+m2.innerVector(j1), refMat2.col(j0)+refMat2.col(j1));
00258
00259
00260
00261 }
00262
00263
00264 {
00265 DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);
00266 SparseMatrixType m2(rows, rows);
00267 initSparse<Scalar>(density, refMat2, m2);
00268 int j0 = ei_random(0,rows-2);
00269 int j1 = ei_random(0,rows-2);
00270 int n0 = ei_random<int>(1,rows-std::max(j0,j1));
00271 VERIFY_IS_APPROX(m2.innerVectors(j0,n0), refMat2.block(0,j0,rows,n0));
00272 VERIFY_IS_APPROX(m2.innerVectors(j0,n0)+m2.innerVectors(j1,n0),
00273 refMat2.block(0,j0,rows,n0)+refMat2.block(0,j1,rows,n0));
00274
00275
00276 }
00277
00278
00279 {
00280 DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);
00281 SparseMatrixType m2(rows, rows);
00282 initSparse<Scalar>(density, refMat2, m2);
00283 VERIFY_IS_APPROX(m2.transpose().eval(), refMat2.transpose().eval());
00284 VERIFY_IS_APPROX(m2.transpose(), refMat2.transpose());
00285 }
00286
00287
00288 {
00289 SparseMatrixType m2(rows, rows);
00290 DenseMatrix refM2(rows, rows);
00291 refM2.setZero();
00292 int countFalseNonZero = 0;
00293 int countTrueNonZero = 0;
00294 m2.startFill();
00295 for (int j=0; j<m2.outerSize(); ++j)
00296 for (int i=0; i<m2.innerSize(); ++i)
00297 {
00298 float x = ei_random<float>(0,1);
00299 if (x<0.1)
00300 {
00301
00302 }
00303 else if (x<0.5)
00304 {
00305 countFalseNonZero++;
00306 m2.fill(i,j) = Scalar(0);
00307 }
00308 else
00309 {
00310 countTrueNonZero++;
00311 m2.fill(i,j) = refM2(i,j) = Scalar(1);
00312 }
00313 }
00314 m2.endFill();
00315 VERIFY(countFalseNonZero+countTrueNonZero == m2.nonZeros());
00316 VERIFY_IS_APPROX(m2, refM2);
00317 m2.prune(1);
00318 VERIFY(countTrueNonZero==m2.nonZeros());
00319 VERIFY_IS_APPROX(m2, refM2);
00320 }
00321 }
00322
00323 void test_eigen2_sparse_basic()
00324 {
00325 for(int i = 0; i < g_repeat; i++) {
00326 CALL_SUBTEST_1( sparse_basic(SparseMatrix<double>(8, 8)) );
00327 CALL_SUBTEST_2( sparse_basic(SparseMatrix<std::complex<double> >(16, 16)) );
00328 CALL_SUBTEST_1( sparse_basic(SparseMatrix<double>(33, 33)) );
00329
00330 CALL_SUBTEST_3( sparse_basic(DynamicSparseMatrix<double>(8, 8)) );
00331 }
00332 }