From 4bb0fff151d587958e5b0e5b4a8a6c6ce822b3db Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Sat, 13 Jul 2013 19:45:05 +0200 Subject: [PATCH] Rationalize assignment to sparse vectors --- Eigen/src/SparseCore/SparseVector.h | 87 +++++++++++++++++------------ 1 file changed, 51 insertions(+), 36 deletions(-) diff --git a/Eigen/src/SparseCore/SparseVector.h b/Eigen/src/SparseCore/SparseVector.h index 188d9e1f1..869556176 100644 --- a/Eigen/src/SparseCore/SparseVector.h +++ b/Eigen/src/SparseCore/SparseVector.h @@ -45,6 +45,21 @@ struct traits > SupportedAccessPatterns = InnerRandomAccessPattern }; }; + +// Sparse-Vector-Assignment kinds: +enum { + SVA_RuntimeSwitch, + SVA_Inner, + SVA_Outer +}; + +template< typename Dest, typename Src, + int AssignmentKind = !bool(Src::IsVectorAtCompileTime) ? SVA_RuntimeSwitch + : (((Src::Flags&RowMajorBit)==RowMajorBit) && (Src::RowsAtCompileTime==1)) + || (((Src::Flags&RowMajorBit)==0) && (Src::ColsAtCompileTime==1)) ? SVA_Inner + : SVA_Outer> +struct sparse_vector_assign_selector; + } template @@ -241,11 +256,11 @@ class SparseVector template inline SparseVector& operator=(const SparseMatrixBase& other) { - if ( (bool(OtherDerived::IsVectorAtCompileTime) && int(RowsAtCompileTime)!=int(OtherDerived::RowsAtCompileTime)) - || ((!bool(OtherDerived::IsVectorAtCompileTime)) && ( bool(IsColVector) ? other.cols()>1 : other.rows()>1 ))) - return assign(other.transpose(), typename internal::conditional<((Flags & RowMajorBit) == (OtherDerived::Flags & RowMajorBit)),internal::true_type,internal::false_type>::type()); - else - return assign(other, typename internal::conditional<((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)),internal::true_type,internal::false_type>::type()); + SparseVector tmp(other.size()); + tmp.reserve(other.nonZeros()); + internal::sparse_vector_assign_selector::run(tmp,other.derived()); + this->swap(tmp); + return *this; } #ifndef EIGEN_PARSED_BY_DOXYGEN @@ -327,12 +342,6 @@ protected: EIGEN_STATIC_ASSERT((_Options&(ColMajor|RowMajor))==Options,INVALID_MATRIX_TEMPLATE_PARAMETERS); } - template - EIGEN_DONT_INLINE SparseVector& assign(const SparseMatrixBase& _other, internal::true_type); - - template - EIGEN_DONT_INLINE SparseVector& assign(const SparseMatrixBase& _other, internal::false_type); - Storage m_data; Index m_size; }; @@ -401,32 +410,38 @@ class SparseVector::ReverseInnerIterator const Index m_start; }; -template -template -EIGEN_DONT_INLINE SparseVector& SparseVector::assign(const SparseMatrixBase& _other, internal::true_type) -{ - const OtherDerived& other(_other.derived()); - - Index size = other.size(); - Index nnz = other.nonZeros(); - resize(size); - reserve(nnz); - for(Index i=0; i +struct sparse_vector_assign_selector { + static void run(Dest& dst, const Src& src) { + eigen_internal_assert(src.innerSize()==src.size()); + for(typename Src::InnerIterator it(src, 0); it; ++it) + dst.insert(it.index()) = it.value(); + } +}; + +template< typename Dest, typename Src> +struct sparse_vector_assign_selector { + static void run(Dest& dst, const Src& src) { + eigen_internal_assert(src.outerSize()==src.size()); + for(typename Dest::Index i=0; i +struct sparse_vector_assign_selector { + static void run(Dest& dst, const Src& src) { + if(src.outerSize()==1) sparse_vector_assign_selector::run(dst, src); + else sparse_vector_assign_selector::run(dst, src); + } +}; -template -template -EIGEN_DONT_INLINE SparseVector& SparseVector::assign(const SparseMatrixBase& _other, internal::false_type) -{ - const OtherDerived& other(_other.derived()); - // there is no special optimization - return Base::operator=(other); } } // end namespace Eigen