aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
-rw-r--r--Eigen/src/SparseCore/SparseMatrix.h26
-rw-r--r--test/sparse_basic.cpp6
-rw-r--r--test/sparse_vector.cpp5
3 files changed, 26 insertions, 11 deletions
diff --git a/Eigen/src/SparseCore/SparseMatrix.h b/Eigen/src/SparseCore/SparseMatrix.h
index faed115ea..0a53ecbea 100644
--- a/Eigen/src/SparseCore/SparseMatrix.h
+++ b/Eigen/src/SparseCore/SparseMatrix.h
@@ -688,7 +688,6 @@ class SparseMatrix
template<typename OtherDerived>
EIGEN_DONT_INLINE SparseMatrix& operator=(const SparseMatrixBase<OtherDerived>& other)
{
- initAssignment(other.derived());
const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit);
if (needToTranspose)
{
@@ -700,40 +699,45 @@ class SparseMatrix
typedef typename internal::remove_all<OtherCopy>::type _OtherCopy;
OtherCopy otherCopy(other.derived());
- Eigen::Map<Matrix<Index, Dynamic, 1> > (m_outerIndex,outerSize()).setZero();
+ SparseMatrix dest(other.rows(),other.cols());
+ Eigen::Map<Matrix<Index, Dynamic, 1> > (dest.m_outerIndex,dest.outerSize()).setZero();
+
// pass 1
// FIXME the above copy could be merged with that pass
for (Index j=0; j<otherCopy.outerSize(); ++j)
for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it)
- ++m_outerIndex[it.index()];
+ ++dest.m_outerIndex[it.index()];
// prefix sum
Index count = 0;
- VectorXi positions(outerSize());
- for (Index j=0; j<outerSize(); ++j)
+ VectorXi positions(dest.outerSize());
+ for (Index j=0; j<dest.outerSize(); ++j)
{
- Index tmp = m_outerIndex[j];
- m_outerIndex[j] = count;
+ Index tmp = dest.m_outerIndex[j];
+ dest.m_outerIndex[j] = count;
positions[j] = count;
count += tmp;
}
- m_outerIndex[outerSize()] = count;
+ dest.m_outerIndex[dest.outerSize()] = count;
// alloc
- m_data.resize(count);
+ dest.m_data.resize(count);
// pass 2
for (Index j=0; j<otherCopy.outerSize(); ++j)
{
for (typename _OtherCopy::InnerIterator it(otherCopy, j); it; ++it)
{
Index pos = positions[it.index()]++;
- m_data.index(pos) = j;
- m_data.value(pos) = it.value();
+ dest.m_data.index(pos) = j;
+ dest.m_data.value(pos) = it.value();
}
}
+ this->swap(dest);
return *this;
}
else
{
+ if(other.isRValue())
+ initAssignment(other.derived());
// there is no special optimization
return Base::operator=(other.derived());
}
diff --git a/test/sparse_basic.cpp b/test/sparse_basic.cpp
index 767451450..4566de9f2 100644
--- a/test/sparse_basic.cpp
+++ b/test/sparse_basic.cpp
@@ -193,6 +193,12 @@ template<typename SparseMatrixType> void sparse_basic(const SparseMatrixType& re
// sparse cwise* dense
VERIFY_IS_APPROX(m3.cwiseProduct(refM4), refM3.cwiseProduct(refM4));
// VERIFY_IS_APPROX(m3.cwise()/refM4, refM3.cwise()/refM4);
+
+ // test aliasing
+ VERIFY_IS_APPROX((m1 = -m1), (refM1 = -refM1));
+ VERIFY_IS_APPROX((m1 = m1.transpose()), (refM1 = refM1.transpose().eval()));
+ VERIFY_IS_APPROX((m1 = -m1.transpose()), (refM1 = -refM1.transpose().eval()));
+ VERIFY_IS_APPROX((m1 += -m1), (refM1 += -refM1));
}
// test transpose
diff --git a/test/sparse_vector.cpp b/test/sparse_vector.cpp
index 7201afe5b..9d559f5bf 100644
--- a/test/sparse_vector.cpp
+++ b/test/sparse_vector.cpp
@@ -78,6 +78,11 @@ template<typename Scalar> void sparse_vector(int rows, int cols)
VERIFY_IS_APPROX(v1.squaredNorm(), refV1.squaredNorm());
+ // 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));
+
}
void test_sparse_vector()