diff options
author | Gael Guennebaud <g.gael@free.fr> | 2013-07-13 19:45:05 +0200 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2013-07-13 19:45:05 +0200 |
commit | 4bb0fff151d587958e5b0e5b4a8a6c6ce822b3db (patch) | |
tree | 193b787bb497007af82fd8bc6b8fe3199e5dba61 /Eigen/src/SparseCore/SparseVector.h | |
parent | 9a16519d62c7315c8ecf00c6c4cb2dbd4a12f9d3 (diff) |
Rationalize assignment to sparse vectors
Diffstat (limited to 'Eigen/src/SparseCore/SparseVector.h')
-rw-r--r-- | Eigen/src/SparseCore/SparseVector.h | 85 |
1 files changed, 50 insertions, 35 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<SparseVector<_Scalar, _Options, _Index> > 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<typename _Scalar, int _Options, typename _Index> @@ -241,11 +256,11 @@ class SparseVector template<typename OtherDerived> inline SparseVector& operator=(const SparseMatrixBase<OtherDerived>& 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<SparseVector,OtherDerived>::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<typename OtherDerived> - EIGEN_DONT_INLINE SparseVector& assign(const SparseMatrixBase<OtherDerived>& _other, internal::true_type); - - template<typename OtherDerived> - EIGEN_DONT_INLINE SparseVector& assign(const SparseMatrixBase<OtherDerived>& _other, internal::false_type); - Storage m_data; Index m_size; }; @@ -401,32 +410,38 @@ class SparseVector<Scalar,_Options,_Index>::ReverseInnerIterator const Index m_start; }; -template<typename Scalar, int _Options, typename _Index> -template<typename OtherDerived> -EIGEN_DONT_INLINE SparseVector<Scalar,_Options,_Index>& SparseVector<Scalar,_Options,_Index>::assign(const SparseMatrixBase<OtherDerived>& _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<size; ++i) - { - typename OtherDerived::InnerIterator it(other, i); - if(it) - insert(i) = it.value(); +namespace internal { + +template< typename Dest, typename Src> +struct sparse_vector_assign_selector<Dest,Src,SVA_Inner> { + 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(); } - return *this; -} +}; + +template< typename Dest, typename Src> +struct sparse_vector_assign_selector<Dest,Src,SVA_Outer> { + static void run(Dest& dst, const Src& src) { + eigen_internal_assert(src.outerSize()==src.size()); + for(typename Dest::Index i=0; i<src.size(); ++i) + { + typename Src::InnerIterator it(src, i); + if(it) + dst.insert(i) = it.value(); + } + } +}; + +template< typename Dest, typename Src> +struct sparse_vector_assign_selector<Dest,Src,SVA_RuntimeSwitch> { + static void run(Dest& dst, const Src& src) { + if(src.outerSize()==1) sparse_vector_assign_selector<Dest,Src,SVA_Inner>::run(dst, src); + else sparse_vector_assign_selector<Dest,Src,SVA_Outer>::run(dst, src); + } +}; -template<typename Scalar, int _Options, typename _Index> -template<typename OtherDerived> -EIGEN_DONT_INLINE SparseVector<Scalar,_Options,_Index>& SparseVector<Scalar,_Options,_Index>::assign(const SparseMatrixBase<OtherDerived>& _other, internal::false_type) -{ - const OtherDerived& other(_other.derived()); - // there is no special optimization - return Base::operator=(other); } } // end namespace Eigen |