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 SparseMatrixType> void sparse_basic(const SparseMatrixType& ref)
00028 {
00029 typedef typename SparseMatrixType::Index Index;
00030
00031 const Index rows = ref.rows();
00032 const Index cols = ref.cols();
00033 typedef typename SparseMatrixType::Scalar Scalar;
00034 enum { Flags = SparseMatrixType::Flags };
00035
00036 double density = std::max(8./(rows*cols), 0.01);
00037 typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
00038 typedef Matrix<Scalar,Dynamic,1> DenseVector;
00039 Scalar eps = 1e-6;
00040
00041 SparseMatrixType m(rows, cols);
00042 DenseMatrix refMat = DenseMatrix::Zero(rows, cols);
00043 DenseVector vec1 = DenseVector::Random(rows);
00044 Scalar s1 = internal::random<Scalar>();
00045
00046 std::vector<Vector2i> zeroCoords;
00047 std::vector<Vector2i> nonzeroCoords;
00048 initSparse<Scalar>(density, refMat, m, 0, &zeroCoords, &nonzeroCoords);
00049
00050 if (zeroCoords.size()==0 || nonzeroCoords.size()==0)
00051 return;
00052
00053
00054 for (int i=0; i<(int)zeroCoords.size(); ++i)
00055 {
00056 VERIFY_IS_MUCH_SMALLER_THAN( m.coeff(zeroCoords[i].x(),zeroCoords[i].y()), eps );
00057 if(internal::is_same<SparseMatrixType,SparseMatrix<Scalar,Flags> >::value)
00058 VERIFY_RAISES_ASSERT( m.coeffRef(zeroCoords[0].x(),zeroCoords[0].y()) = 5 );
00059 }
00060 VERIFY_IS_APPROX(m, refMat);
00061
00062 m.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);
00063 refMat.coeffRef(nonzeroCoords[0].x(), nonzeroCoords[0].y()) = Scalar(5);
00064
00065 VERIFY_IS_APPROX(m, refMat);
00066
00067
00068
00069
00070
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
00088
00089
00090
00091
00092
00093
00094
00095
00096
00097
00098
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 {
00109 DenseMatrix m1(rows,cols);
00110 m1.setZero();
00111 SparseMatrixType m2(rows,cols);
00112 m2.reserve(10);
00113 for (int j=0; j<cols; ++j)
00114 {
00115 for (int k=0; k<rows/2; ++k)
00116 {
00117 int i = internal::random<int>(0,rows-1);
00118 if (m1.coeff(i,j)==Scalar(0))
00119 m2.insert(i,j) = m1(i,j) = internal::random<Scalar>();
00120 }
00121 }
00122 m2.finalize();
00123 VERIFY_IS_APPROX(m2,m1);
00124 }
00125
00126
00127 {
00128 DenseMatrix m1(rows,cols);
00129 m1.setZero();
00130 SparseMatrixType m2(rows,cols);
00131 m2.reserve(10);
00132 for (int k=0; k<rows*cols; ++k)
00133 {
00134 int i = internal::random<int>(0,rows-1);
00135 int j = internal::random<int>(0,cols-1);
00136 if (m1.coeff(i,j)==Scalar(0))
00137 m2.insert(i,j) = m1(i,j) = internal::random<Scalar>();
00138 }
00139 m2.finalize();
00140 VERIFY_IS_APPROX(m2,m1);
00141 }
00142
00143
00144 {
00145 DenseMatrix refM1 = DenseMatrix::Zero(rows, rows);
00146 DenseMatrix refM2 = DenseMatrix::Zero(rows, rows);
00147 DenseMatrix refM3 = DenseMatrix::Zero(rows, rows);
00148 DenseMatrix refM4 = DenseMatrix::Zero(rows, rows);
00149 SparseMatrixType m1(rows, rows);
00150 SparseMatrixType m2(rows, rows);
00151 SparseMatrixType m3(rows, rows);
00152 SparseMatrixType m4(rows, rows);
00153 initSparse<Scalar>(density, refM1, m1);
00154 initSparse<Scalar>(density, refM2, m2);
00155 initSparse<Scalar>(density, refM3, m3);
00156 initSparse<Scalar>(density, refM4, m4);
00157
00158 VERIFY_IS_APPROX(m1+m2, refM1+refM2);
00159 VERIFY_IS_APPROX(m1+m2+m3, refM1+refM2+refM3);
00160 VERIFY_IS_APPROX(m3.cwiseProduct(m1+m2), refM3.cwiseProduct(refM1+refM2));
00161 VERIFY_IS_APPROX(m1*s1-m2, refM1*s1-refM2);
00162
00163 VERIFY_IS_APPROX(m1*=s1, refM1*=s1);
00164 VERIFY_IS_APPROX(m1/=s1, refM1/=s1);
00165
00166 VERIFY_IS_APPROX(m1+=m2, refM1+=refM2);
00167 VERIFY_IS_APPROX(m1-=m2, refM1-=refM2);
00168
00169 VERIFY_IS_APPROX(m1.col(0).dot(refM2.row(0)), refM1.col(0).dot(refM2.row(0)));
00170
00171 refM4.setRandom();
00172
00173 VERIFY_IS_APPROX(m3.cwiseProduct(refM4), refM3.cwiseProduct(refM4));
00174
00175 }
00176
00177
00178 {
00179 DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);
00180 SparseMatrixType m2(rows, rows);
00181 initSparse<Scalar>(density, refMat2, m2);
00182 VERIFY_IS_APPROX(m2.transpose().eval(), refMat2.transpose().eval());
00183 VERIFY_IS_APPROX(m2.transpose(), refMat2.transpose());
00184
00185 VERIFY_IS_APPROX(SparseMatrixType(m2.adjoint()), refMat2.adjoint());
00186 }
00187
00188
00189 {
00190 DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);
00191 SparseMatrixType m2(rows, rows);
00192 initSparse<Scalar>(density, refMat2, m2);
00193 int j0 = internal::random(0,rows-1);
00194 int j1 = internal::random(0,rows-1);
00195 VERIFY_IS_APPROX(m2.innerVector(j0), refMat2.col(j0));
00196 VERIFY_IS_APPROX(m2.innerVector(j0)+m2.innerVector(j1), refMat2.col(j0)+refMat2.col(j1));
00197
00198
00199
00200 }
00201
00202
00203 {
00204 DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);
00205 SparseMatrixType m2(rows, rows);
00206 initSparse<Scalar>(density, refMat2, m2);
00207 int j0 = internal::random(0,rows-2);
00208 int j1 = internal::random(0,rows-2);
00209 int n0 = internal::random<int>(1,rows-std::max(j0,j1));
00210 VERIFY_IS_APPROX(m2.innerVectors(j0,n0), refMat2.block(0,j0,rows,n0));
00211 VERIFY_IS_APPROX(m2.innerVectors(j0,n0)+m2.innerVectors(j1,n0),
00212 refMat2.block(0,j0,rows,n0)+refMat2.block(0,j1,rows,n0));
00213
00214
00215 }
00216
00217
00218 {
00219 SparseMatrixType m2(rows, rows);
00220 DenseMatrix refM2(rows, rows);
00221 refM2.setZero();
00222 int countFalseNonZero = 0;
00223 int countTrueNonZero = 0;
00224 for (int j=0; j<m2.outerSize(); ++j)
00225 {
00226 m2.startVec(j);
00227 for (int i=0; i<m2.innerSize(); ++i)
00228 {
00229 float x = internal::random<float>(0,1);
00230 if (x<0.1)
00231 {
00232
00233 }
00234 else if (x<0.5)
00235 {
00236 countFalseNonZero++;
00237 m2.insertBackByOuterInner(j,i) = Scalar(0);
00238 }
00239 else
00240 {
00241 countTrueNonZero++;
00242 m2.insertBackByOuterInner(j,i) = refM2(i,j) = Scalar(1);
00243 }
00244 }
00245 }
00246 m2.finalize();
00247 VERIFY(countFalseNonZero+countTrueNonZero == m2.nonZeros());
00248 VERIFY_IS_APPROX(m2, refM2);
00249 m2.prune(Scalar(1));
00250 VERIFY(countTrueNonZero==m2.nonZeros());
00251 VERIFY_IS_APPROX(m2, refM2);
00252 }
00253
00254
00255 {
00256 DenseMatrix refMat2(rows, rows), refMat3(rows, rows);
00257 SparseMatrixType m2(rows, rows), m3(rows, rows);
00258 initSparse<Scalar>(density, refMat2, m2);
00259 refMat3 = refMat2.template selfadjointView<Lower>();
00260 m3 = m2.template selfadjointView<Lower>();
00261 VERIFY_IS_APPROX(m3, refMat3);
00262 }
00263
00264
00265 {
00266 DenseMatrix refMat2 = DenseMatrix::Zero(rows, rows);
00267 SparseMatrixType m2(rows, rows);
00268 initSparse<Scalar>(density, refMat2, m2);
00269 VERIFY_IS_APPROX(m2.eval(), refMat2.sparseView().eval());
00270 }
00271 }
00272
00273 void test_sparse_basic()
00274 {
00275 for(int i = 0; i < g_repeat; i++) {
00276 CALL_SUBTEST_1( sparse_basic(SparseMatrix<double>(8, 8)) );
00277 CALL_SUBTEST_2( sparse_basic(SparseMatrix<std::complex<double> >(16, 16)) );
00278 CALL_SUBTEST_1( sparse_basic(SparseMatrix<double>(33, 33)) );
00279
00280 CALL_SUBTEST_3( sparse_basic(DynamicSparseMatrix<double>(8, 8)) );
00281 }
00282 }