1 // This file is part of Eigen, a lightweight C++ template library
4 // Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
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/.
12 template<typename Scalar
,typename Index
> void sparse_vector(int rows
, int cols
)
14 double densityMat
= (std::max
)(8./(rows
*cols
), 0.01);
15 double densityVec
= (std::max
)(8./float(rows
), 0.1);
16 typedef Matrix
<Scalar
,Dynamic
,Dynamic
> DenseMatrix
;
17 typedef Matrix
<Scalar
,Dynamic
,1> DenseVector
;
18 typedef SparseVector
<Scalar
,0,Index
> SparseVectorType
;
19 typedef SparseMatrix
<Scalar
,0,Index
> SparseMatrixType
;
22 SparseMatrixType
m1(rows
,rows
);
23 SparseVectorType
v1(rows
), v2(rows
), v3(rows
);
24 DenseMatrix refM1
= DenseMatrix::Zero(rows
, rows
);
25 DenseVector refV1
= DenseVector::Random(rows
),
26 refV2
= DenseVector::Random(rows
),
27 refV3
= DenseVector::Random(rows
);
29 std::vector
<int> zerocoords
, nonzerocoords
;
30 initSparse
<Scalar
>(densityVec
, refV1
, v1
, &zerocoords
, &nonzerocoords
);
31 initSparse
<Scalar
>(densityMat
, refM1
, m1
);
33 initSparse
<Scalar
>(densityVec
, refV2
, v2
);
34 initSparse
<Scalar
>(densityVec
, refV3
, v3
);
36 Scalar s1
= internal::random
<Scalar
>();
38 // test coeff and coeffRef
39 for (unsigned int i
=0; i
<zerocoords
.size(); ++i
)
41 VERIFY_IS_MUCH_SMALLER_THAN( v1
.coeff(zerocoords
[i
]), eps
);
42 //VERIFY_RAISES_ASSERT( v1.coeffRef(zerocoords[i]) = 5 );
45 VERIFY(int(nonzerocoords
.size()) == v1
.nonZeros());
47 for (typename
SparseVectorType::InnerIterator
it(v1
); it
; ++it
,++j
)
49 VERIFY(nonzerocoords
[j
]==it
.index());
50 VERIFY(it
.value()==v1
.coeff(it
.index()));
51 VERIFY(it
.value()==refV1
.coeff(it
.index()));
54 VERIFY_IS_APPROX(v1
, refV1
);
56 v1
.coeffRef(nonzerocoords
[0]) = Scalar(5);
57 refV1
.coeffRef(nonzerocoords
[0]) = Scalar(5);
58 VERIFY_IS_APPROX(v1
, refV1
);
60 VERIFY_IS_APPROX(v1
+v2
, refV1
+refV2
);
61 VERIFY_IS_APPROX(v1
+v2
+v3
, refV1
+refV2
+refV3
);
63 VERIFY_IS_APPROX(v1
*s1
-v2
, refV1
*s1
-refV2
);
65 VERIFY_IS_APPROX(v1
*=s1
, refV1
*=s1
);
66 VERIFY_IS_APPROX(v1
/=s1
, refV1
/=s1
);
68 VERIFY_IS_APPROX(v1
+=v2
, refV1
+=refV2
);
69 VERIFY_IS_APPROX(v1
-=v2
, refV1
-=refV2
);
71 VERIFY_IS_APPROX(v1
.dot(v2
), refV1
.dot(refV2
));
72 VERIFY_IS_APPROX(v1
.dot(refV2
), refV1
.dot(refV2
));
74 VERIFY_IS_APPROX(v1
.dot(m1
*v2
), refV1
.dot(refM1
*refV2
));
75 int i
= internal::random
<int>(0,rows
-1);
76 VERIFY_IS_APPROX(v1
.dot(m1
.col(i
)), refV1
.dot(refM1
.col(i
)));
79 VERIFY_IS_APPROX(v1
.squaredNorm(), refV1
.squaredNorm());
81 VERIFY_IS_APPROX(v1
.blueNorm(), refV1
.blueNorm());
84 VERIFY_IS_APPROX((v1
= -v1
), (refV1
= -refV1
));
85 VERIFY_IS_APPROX((v1
= v1
.transpose()), (refV1
= refV1
.transpose().eval()));
86 VERIFY_IS_APPROX((v1
+= -v1
), (refV1
+= -refV1
));
88 // sparse matrix to sparse vector
90 VERIFY_IS_APPROX((mv1
=v1
),v1
);
91 VERIFY_IS_APPROX(mv1
,(v1
=mv1
));
92 VERIFY_IS_APPROX(mv1
,(v1
=mv1
.transpose()));
94 // check copy to dense vector with transpose
96 VERIFY_IS_APPROX(refV3
= v1
.transpose(),v1
.toDense());
97 VERIFY_IS_APPROX(DenseVector(v1
),v1
.toDense());
101 void test_sparse_vector()
103 for(int i
= 0; i
< g_repeat
; i
++) {
104 CALL_SUBTEST_1(( sparse_vector
<double,int>(8, 8) ));
105 CALL_SUBTEST_2(( sparse_vector
<std::complex<double>, int>(16, 16) ));
106 CALL_SUBTEST_1(( sparse_vector
<double,long int>(299, 535) ));
107 CALL_SUBTEST_1(( sparse_vector
<double,short>(299, 535) ));