aboutsummaryrefslogtreecommitdiff
path: root/test/sparse_basic.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/sparse_basic.cpp')
-rw-r--r--test/sparse_basic.cpp126
1 files changed, 99 insertions, 27 deletions
diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp
index 384985028..9453111b7 100644
--- a/test/sparse_basic.cpp
+++ b/test/sparse_basic.cpp
@@ -9,9 +9,16 @@
// 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/.
+#ifndef EIGEN_SPARSE_TEST_INCLUDED_FROM_SPARSE_EXTRA
static long g_realloc_count = 0;
#define EIGEN_SPARSE_COMPRESSED_STORAGE_REALLOCATE_PLUGIN g_realloc_count++;
+static long g_dense_op_sparse_count = 0;
+#define EIGEN_SPARSE_ASSIGNMENT_FROM_DENSE_OP_SPARSE_PLUGIN g_dense_op_sparse_count++;
+#define EIGEN_SPARSE_ASSIGNMENT_FROM_SPARSE_ADD_DENSE_PLUGIN g_dense_op_sparse_count+=10;
+#define EIGEN_SPARSE_ASSIGNMENT_FROM_SPARSE_SUB_DENSE_PLUGIN g_dense_op_sparse_count+=20;
+#endif
+
#include "sparse.h"
template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& ref)
@@ -194,6 +201,7 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
VERIFY_IS_APPROX(refM4.cwiseProduct(m3), refM4.cwiseProduct(refM3));
// VERIFY_IS_APPROX(m3.cwise()/refM4, refM3.cwise()/refM4);
+ // mixed sparse-dense
VERIFY_IS_APPROX(refM4 + m3, refM4 + refM3);
VERIFY_IS_APPROX(m3 + refM4, refM3 + refM4);
VERIFY_IS_APPROX(refM4 - m3, refM4 - refM3);
@@ -222,14 +230,34 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
VERIFY_IS_APPROX(m1+=m2, refM1+=refM2);
VERIFY_IS_APPROX(m1-=m2, refM1-=refM2);
+ refM3 = refM1;
+
+ VERIFY_IS_APPROX(refM1+=m2, refM3+=refM2);
+ VERIFY_IS_APPROX(refM1-=m2, refM3-=refM2);
+
+ g_dense_op_sparse_count=0; VERIFY_IS_APPROX(refM1 =m2+refM4, refM3 =refM2+refM4); VERIFY_IS_EQUAL(g_dense_op_sparse_count,10);
+ g_dense_op_sparse_count=0; VERIFY_IS_APPROX(refM1+=m2+refM4, refM3+=refM2+refM4); VERIFY_IS_EQUAL(g_dense_op_sparse_count,1);
+ g_dense_op_sparse_count=0; VERIFY_IS_APPROX(refM1-=m2+refM4, refM3-=refM2+refM4); VERIFY_IS_EQUAL(g_dense_op_sparse_count,1);
+ g_dense_op_sparse_count=0; VERIFY_IS_APPROX(refM1 =refM4+m2, refM3 =refM2+refM4); VERIFY_IS_EQUAL(g_dense_op_sparse_count,1);
+ g_dense_op_sparse_count=0; VERIFY_IS_APPROX(refM1+=refM4+m2, refM3+=refM2+refM4); VERIFY_IS_EQUAL(g_dense_op_sparse_count,1);
+ g_dense_op_sparse_count=0; VERIFY_IS_APPROX(refM1-=refM4+m2, refM3-=refM2+refM4); VERIFY_IS_EQUAL(g_dense_op_sparse_count,1);
+
+ g_dense_op_sparse_count=0; VERIFY_IS_APPROX(refM1 =m2-refM4, refM3 =refM2-refM4); VERIFY_IS_EQUAL(g_dense_op_sparse_count,20);
+ g_dense_op_sparse_count=0; VERIFY_IS_APPROX(refM1+=m2-refM4, refM3+=refM2-refM4); VERIFY_IS_EQUAL(g_dense_op_sparse_count,1);
+ g_dense_op_sparse_count=0; VERIFY_IS_APPROX(refM1-=m2-refM4, refM3-=refM2-refM4); VERIFY_IS_EQUAL(g_dense_op_sparse_count,1);
+ g_dense_op_sparse_count=0; VERIFY_IS_APPROX(refM1 =refM4-m2, refM3 =refM4-refM2); VERIFY_IS_EQUAL(g_dense_op_sparse_count,1);
+ g_dense_op_sparse_count=0; VERIFY_IS_APPROX(refM1+=refM4-m2, refM3+=refM4-refM2); VERIFY_IS_EQUAL(g_dense_op_sparse_count,1);
+ g_dense_op_sparse_count=0; VERIFY_IS_APPROX(refM1-=refM4-m2, refM3-=refM4-refM2); VERIFY_IS_EQUAL(g_dense_op_sparse_count,1);
+ refM3 = m3;
+
if (rows>=2 && cols>=2)
{
VERIFY_RAISES_ASSERT( m1 += m1.innerVector(0) );
VERIFY_RAISES_ASSERT( m1 -= m1.innerVector(0) );
VERIFY_RAISES_ASSERT( refM1 -= m1.innerVector(0) );
VERIFY_RAISES_ASSERT( refM1 += m1.innerVector(0) );
- m1 = m4; refM1 = refM4;
}
+ m1 = m4; refM1 = refM4;
// test aliasing
VERIFY_IS_APPROX((m1 = -m1), (refM1 = -refM1));
@@ -385,7 +413,7 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
m.setFromTriplets(triplets.begin(), triplets.end(), std::multiplies<Scalar>());
VERIFY_IS_APPROX(m, refMat_prod);
-#if (defined(__cplusplus) && __cplusplus >= 201103L)
+#if (EIGEN_COMP_CXXVER >= 11)
m.setFromTriplets(triplets.begin(), triplets.end(), [] (Scalar,Scalar b) { return b; });
VERIFY_IS_APPROX(m, refMat_last);
#endif
@@ -518,7 +546,7 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
{
DenseVector d = DenseVector::Random(rows);
DenseMatrix refMat2 = d.asDiagonal();
- SparseMatrixType m2(rows, rows);
+ SparseMatrixType m2;
m2 = d.asDiagonal();
VERIFY_IS_APPROX(m2, refMat2);
SparseMatrixType m3(d.asDiagonal());
@@ -526,6 +554,28 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
refMat2 += d.asDiagonal();
m2 += d.asDiagonal();
VERIFY_IS_APPROX(m2, refMat2);
+ m2.setZero(); m2 += d.asDiagonal();
+ refMat2.setZero(); refMat2 += d.asDiagonal();
+ VERIFY_IS_APPROX(m2, refMat2);
+ m2.setZero(); m2 -= d.asDiagonal();
+ refMat2.setZero(); refMat2 -= d.asDiagonal();
+ VERIFY_IS_APPROX(m2, refMat2);
+
+ initSparse<Scalar>(density, refMat2, m2);
+ m2.makeCompressed();
+ m2 += d.asDiagonal();
+ refMat2 += d.asDiagonal();
+ VERIFY_IS_APPROX(m2, refMat2);
+
+ initSparse<Scalar>(density, refMat2, m2);
+ m2.makeCompressed();
+ VectorXi res(rows);
+ for(Index i=0; i<rows; ++i)
+ res(i) = internal::random<int>(0,3);
+ m2.reserve(res);
+ m2 -= d.asDiagonal();
+ refMat2 -= d.asDiagonal();
+ VERIFY_IS_APPROX(m2, refMat2);
}
// test conservative resize
@@ -537,30 +587,38 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
inc.push_back(std::pair<StorageIndex,StorageIndex>(3,2));
inc.push_back(std::pair<StorageIndex,StorageIndex>(3,0));
inc.push_back(std::pair<StorageIndex,StorageIndex>(0,3));
-
+ inc.push_back(std::pair<StorageIndex,StorageIndex>(0,-1));
+ inc.push_back(std::pair<StorageIndex,StorageIndex>(-1,0));
+ inc.push_back(std::pair<StorageIndex,StorageIndex>(-1,-1));
+
for(size_t i = 0; i< inc.size(); i++) {
StorageIndex incRows = inc[i].first;
StorageIndex incCols = inc[i].second;
SparseMatrixType m1(rows, cols);
DenseMatrix refMat1 = DenseMatrix::Zero(rows, cols);
initSparse<Scalar>(density, refMat1, m1);
-
+
+ SparseMatrixType m2 = m1;
+ m2.makeCompressed();
+
m1.conservativeResize(rows+incRows, cols+incCols);
+ m2.conservativeResize(rows+incRows, cols+incCols);
refMat1.conservativeResize(rows+incRows, cols+incCols);
if (incRows > 0) refMat1.bottomRows(incRows).setZero();
if (incCols > 0) refMat1.rightCols(incCols).setZero();
-
+
VERIFY_IS_APPROX(m1, refMat1);
-
+ VERIFY_IS_APPROX(m2, refMat1);
+
// Insert new values
if (incRows > 0)
m1.insert(m1.rows()-1, 0) = refMat1(refMat1.rows()-1, 0) = 1;
if (incCols > 0)
m1.insert(0, m1.cols()-1) = refMat1(0, refMat1.cols()-1) = 1;
-
+
VERIFY_IS_APPROX(m1, refMat1);
-
-
+
+
}
}
@@ -612,6 +670,14 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
iters[0] = IteratorType(m2,0);
iters[1] = IteratorType(m2,m2.outerSize()-1);
}
+
+ // test reserve with empty rows/columns
+ {
+ SparseMatrixType m1(0,cols);
+ m1.reserve(ArrayXi::Constant(m1.outerSize(),1));
+ SparseMatrixType m2(rows,0);
+ m2.reserve(ArrayXi::Constant(m2.outerSize(),1));
+ }
}
@@ -622,7 +688,7 @@ void big_sparse_triplet(Index rows, Index cols, double density) {
typedef Triplet<Scalar,Index> TripletType;
std::vector<TripletType> triplets;
double nelements = density * rows*cols;
- VERIFY(nelements>=0 && nelements < NumTraits<StorageIndex>::highest());
+ VERIFY(nelements>=0 && nelements < static_cast<double>(NumTraits<StorageIndex>::highest()));
Index ntriplets = Index(nelements);
triplets.reserve(ntriplets);
Scalar sum = Scalar(0);
@@ -630,7 +696,8 @@ void big_sparse_triplet(Index rows, Index cols, double density) {
{
Index r = internal::random<Index>(0,rows-1);
Index c = internal::random<Index>(0,cols-1);
- Scalar v = internal::random<Scalar>();
+ // use positive values to prevent numerical cancellation errors in sum
+ Scalar v = numext::abs(internal::random<Scalar>());
triplets.push_back(TripletType(r,c,v));
sum += v;
}
@@ -640,9 +707,26 @@ void big_sparse_triplet(Index rows, Index cols, double density) {
VERIFY_IS_APPROX(sum, m.sum());
}
+template<int>
+void bug1105()
+{
+ // Regression test for bug 1105
+ int n = Eigen::internal::random<int>(200,600);
+ SparseMatrix<std::complex<double>,0, long> mat(n, n);
+ std::complex<double> val;
+
+ for(int i=0; i<n; ++i)
+ {
+ mat.coeffRef(i, i%(n/10)) = val;
+ VERIFY(mat.data().allocatedSize()<20*n);
+ }
+}
+
+#ifndef EIGEN_SPARSE_TEST_INCLUDED_FROM_SPARSE_EXTRA
-void test_sparse_basic()
+EIGEN_DECLARE_TEST(sparse_basic)
{
+ g_dense_op_sparse_count = 0; // Suppresses compiler warning.
for(int i = 0; i < g_repeat; i++) {
int r = Eigen::internal::random<int>(1,200), c = Eigen::internal::random<int>(1,200);
if(Eigen::internal::random<int>(0,4) == 0) {
@@ -671,18 +755,6 @@ void test_sparse_basic()
CALL_SUBTEST_3((big_sparse_triplet<SparseMatrix<float, RowMajor, int> >(10000, 10000, 0.125)));
CALL_SUBTEST_4((big_sparse_triplet<SparseMatrix<double, ColMajor, long int> >(10000, 10000, 0.125)));
- // Regression test for bug 1105
-#ifdef EIGEN_TEST_PART_7
- {
- int n = Eigen::internal::random<int>(200,600);
- SparseMatrix<std::complex<double>,0, long> mat(n, n);
- std::complex<double> val;
-
- for(int i=0; i<n; ++i)
- {
- mat.coeffRef(i, i%(n/10)) = val;
- VERIFY(mat.data().allocatedSize()<20*n);
- }
- }
-#endif
+ CALL_SUBTEST_7( bug1105<0>() );
}
+#endif