aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Eigen/src/SparseCore/CompressedStorage.h27
-rw-r--r--test/sparse_vector.cpp18
2 files changed, 39 insertions, 6 deletions
diff --git a/Eigen/src/SparseCore/CompressedStorage.h b/Eigen/src/SparseCore/CompressedStorage.h
index 4f3695773..f408dd3a6 100644
--- a/Eigen/src/SparseCore/CompressedStorage.h
+++ b/Eigen/src/SparseCore/CompressedStorage.h
@@ -172,12 +172,31 @@ class CompressedStorage
size_t id = searchLowerIndex(0,m_size,key);
if (id>=m_size || m_indices[id]!=key)
{
- resize(m_size+1,1);
- for (size_t j=m_size-1; j>id; --j)
+ if (m_allocatedSize<m_size+1)
{
- m_indices[j] = m_indices[j-1];
- m_values[j] = m_values[j-1];
+ m_allocatedSize = 2*(m_size+1);
+ internal::scoped_array<Scalar> newValues(m_allocatedSize);
+ internal::scoped_array<Index> newIndices(m_allocatedSize);
+
+ // copy first chunk
+ internal::smart_copy(m_values, m_values +id, newValues.ptr());
+ internal::smart_copy(m_indices, m_indices+id, newIndices.ptr());
+
+ // copy the rest
+ if(m_size>id)
+ {
+ internal::smart_copy(m_values +id, m_values +m_size, newValues.ptr() +id+1);
+ internal::smart_copy(m_indices+id, m_indices+m_size, newIndices.ptr()+id+1);
+ }
+ std::swap(m_values,newValues.ptr());
+ std::swap(m_indices,newIndices.ptr());
}
+ else if(m_size>id)
+ {
+ internal::smart_memmove(m_values +id, m_values +m_size, m_values +id+1);
+ internal::smart_memmove(m_indices+id, m_indices+m_size, m_indices+id+1);
+ }
+ m_size++;
m_indices[id] = key;
m_values[id] = defaultValue;
}
diff --git a/test/sparse_vector.cpp b/test/sparse_vector.cpp
index 5eea9edfd..5dc421976 100644
--- a/test/sparse_vector.cpp
+++ b/test/sparse_vector.cpp
@@ -23,8 +23,8 @@ template<typename Scalar,typename Index> void sparse_vector(int rows, int cols)
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);
+ refV2 = DenseVector::Random(rows),
+ refV3 = DenseVector::Random(rows);
std::vector<int> zerocoords, nonzerocoords;
initSparse<Scalar>(densityVec, refV1, v1, &zerocoords, &nonzerocoords);
@@ -52,6 +52,20 @@ template<typename Scalar,typename Index> void sparse_vector(int rows, int cols)
}
}
VERIFY_IS_APPROX(v1, refV1);
+
+ // test coeffRef with reallocation
+ {
+ SparseVectorType v1(rows);
+ DenseVector v2 = DenseVector::Zero(rows);
+ for(int k=0; k<rows; ++k)
+ {
+ int i = internal::random<int>(0,rows-1);
+ Scalar v = internal::random<Scalar>();
+ v1.coeffRef(i) += v;
+ v2.coeffRef(i) += v;
+ }
+ VERIFY_IS_APPROX(v1,v2);
+ }
v1.coeffRef(nonzerocoords[0]) = Scalar(5);
refV1.coeffRef(nonzerocoords[0]) = Scalar(5);