1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163
|
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra.
//
// Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
//
// This Source Code Form is subject to the terms of the Mozilla
// Public License v. 2.0. If a copy of the MPL was not distributed
// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
#include "sparse.h"
template<typename Scalar,typename StorageIndex> void sparse_vector(int rows, int cols)
{
double densityMat = (std::max)(8./(rows*cols), 0.01);
double densityVec = (std::max)(8./(rows), 0.1);
typedef Matrix<Scalar,Dynamic,Dynamic> DenseMatrix;
typedef Matrix<Scalar,Dynamic,1> DenseVector;
typedef SparseVector<Scalar,0,StorageIndex> SparseVectorType;
typedef SparseMatrix<Scalar,0,StorageIndex> SparseMatrixType;
Scalar eps = 1e-6;
SparseMatrixType m1(rows,rows);
SparseVectorType v1(rows), v2(rows), v3(rows);
DenseMatrix refM1 = DenseMatrix::Zero(rows, rows);
DenseVector refV1 = DenseVector::Random(rows),
refV2 = DenseVector::Random(rows),
refV3 = DenseVector::Random(rows);
std::vector<int> zerocoords, nonzerocoords;
initSparse<Scalar>(densityVec, refV1, v1, &zerocoords, &nonzerocoords);
initSparse<Scalar>(densityMat, refM1, m1);
initSparse<Scalar>(densityVec, refV2, v2);
initSparse<Scalar>(densityVec, refV3, v3);
Scalar s1 = internal::random<Scalar>();
// test coeff and coeffRef
for (unsigned int i=0; i<zerocoords.size(); ++i)
{
VERIFY_IS_MUCH_SMALLER_THAN( v1.coeff(zerocoords[i]), eps );
//VERIFY_RAISES_ASSERT( v1.coeffRef(zerocoords[i]) = 5 );
}
{
VERIFY(int(nonzerocoords.size()) == v1.nonZeros());
int j=0;
for (typename SparseVectorType::InnerIterator it(v1); it; ++it,++j)
{
VERIFY(nonzerocoords[j]==it.index());
VERIFY(it.value()==v1.coeff(it.index()));
VERIFY(it.value()==refV1.coeff(it.index()));
}
}
VERIFY_IS_APPROX(v1, refV1);
// test coeffRef with reallocation
{
SparseVectorType v4(rows);
DenseVector v5 = DenseVector::Zero(rows);
for(int k=0; k<rows; ++k)
{
int i = internal::random<int>(0,rows-1);
Scalar v = internal::random<Scalar>();
v4.coeffRef(i) += v;
v5.coeffRef(i) += v;
}
VERIFY_IS_APPROX(v4,v5);
}
v1.coeffRef(nonzerocoords[0]) = Scalar(5);
refV1.coeffRef(nonzerocoords[0]) = Scalar(5);
VERIFY_IS_APPROX(v1, refV1);
VERIFY_IS_APPROX(v1+v2, refV1+refV2);
VERIFY_IS_APPROX(v1+v2+v3, refV1+refV2+refV3);
VERIFY_IS_APPROX(v1*s1-v2, refV1*s1-refV2);
VERIFY_IS_APPROX(v1*=s1, refV1*=s1);
VERIFY_IS_APPROX(v1/=s1, refV1/=s1);
VERIFY_IS_APPROX(v1+=v2, refV1+=refV2);
VERIFY_IS_APPROX(v1-=v2, refV1-=refV2);
VERIFY_IS_APPROX(v1.dot(v2), refV1.dot(refV2));
VERIFY_IS_APPROX(v1.dot(refV2), refV1.dot(refV2));
VERIFY_IS_APPROX(m1*v2, refM1*refV2);
VERIFY_IS_APPROX(v1.dot(m1*v2), refV1.dot(refM1*refV2));
{
int i = internal::random<int>(0,rows-1);
VERIFY_IS_APPROX(v1.dot(m1.col(i)), refV1.dot(refM1.col(i)));
}
VERIFY_IS_APPROX(v1.squaredNorm(), refV1.squaredNorm());
VERIFY_IS_APPROX(v1.blueNorm(), refV1.blueNorm());
// test aliasing
VERIFY_IS_APPROX((v1 = -v1), (refV1 = -refV1));
VERIFY_IS_APPROX((v1 = v1.transpose()), (refV1 = refV1.transpose().eval()));
VERIFY_IS_APPROX((v1 += -v1), (refV1 += -refV1));
// sparse matrix to sparse vector
SparseMatrixType mv1;
VERIFY_IS_APPROX((mv1=v1),v1);
VERIFY_IS_APPROX(mv1,(v1=mv1));
VERIFY_IS_APPROX(mv1,(v1=mv1.transpose()));
// check copy to dense vector with transpose
refV3.resize(0);
VERIFY_IS_APPROX(refV3 = v1.transpose(),v1.toDense());
VERIFY_IS_APPROX(DenseVector(v1),v1.toDense());
// test conservative resize
{
std::vector<StorageIndex> inc;
if(rows > 3)
inc.push_back(-3);
inc.push_back(0);
inc.push_back(3);
inc.push_back(1);
inc.push_back(10);
for(std::size_t i = 0; i< inc.size(); i++) {
StorageIndex incRows = inc[i];
SparseVectorType vec1(rows);
DenseVector refVec1 = DenseVector::Zero(rows);
initSparse<Scalar>(densityVec, refVec1, vec1);
vec1.conservativeResize(rows+incRows);
refVec1.conservativeResize(rows+incRows);
if (incRows > 0) refVec1.tail(incRows).setZero();
VERIFY_IS_APPROX(vec1, refVec1);
// Insert new values
if (incRows > 0)
vec1.insert(vec1.rows()-1) = refVec1(refVec1.rows()-1) = 1;
VERIFY_IS_APPROX(vec1, refVec1);
}
}
}
EIGEN_DECLARE_TEST(sparse_vector)
{
for(int i = 0; i < g_repeat; i++) {
int r = Eigen::internal::random<int>(1,500), c = Eigen::internal::random<int>(1,500);
if(Eigen::internal::random<int>(0,4) == 0) {
r = c; // check square matrices in 25% of tries
}
EIGEN_UNUSED_VARIABLE(r+c);
CALL_SUBTEST_1(( sparse_vector<double,int>(8, 8) ));
CALL_SUBTEST_2(( sparse_vector<std::complex<double>, int>(r, c) ));
CALL_SUBTEST_1(( sparse_vector<double,long int>(r, c) ));
CALL_SUBTEST_1(( sparse_vector<double,short>(r, c) ));
}
}
|