diff options
-rw-r--r-- | Eigen/SparseCore | 5 | ||||
-rw-r--r-- | Eigen/src/SparseCore/SparseAssign.h | 252 | ||||
-rw-r--r-- | Eigen/src/SparseCore/SparseCwiseUnaryOp.h | 150 | ||||
-rw-r--r-- | Eigen/src/SparseCore/SparseMatrix.h | 93 | ||||
-rw-r--r-- | Eigen/src/SparseCore/SparseMatrixBase.h | 83 | ||||
-rw-r--r-- | Eigen/src/SparseCore/SparseUtil.h | 6 |
6 files changed, 508 insertions, 81 deletions
diff --git a/Eigen/SparseCore b/Eigen/SparseCore index 9b5be5e15..c0f0a4121 100644 --- a/Eigen/SparseCore +++ b/Eigen/SparseCore @@ -35,14 +35,16 @@ struct Sparse {}; #include "src/SparseCore/SparseUtil.h" #include "src/SparseCore/SparseMatrixBase.h" +#include "src/SparseCore/SparseAssign.h" #include "src/SparseCore/CompressedStorage.h" #include "src/SparseCore/AmbiVector.h" #include "src/SparseCore/SparseMatrix.h" #include "src/SparseCore/MappedSparseMatrix.h" #include "src/SparseCore/SparseVector.h" +#include "src/SparseCore/SparseCwiseUnaryOp.h" +#ifndef EIGEN_TEST_EVALUATORS #include "src/SparseCore/SparseBlock.h" #include "src/SparseCore/SparseTranspose.h" -#include "src/SparseCore/SparseCwiseUnaryOp.h" #include "src/SparseCore/SparseCwiseBinaryOp.h" #include "src/SparseCore/SparseDot.h" #include "src/SparseCore/SparsePermutation.h" @@ -57,6 +59,7 @@ struct Sparse {}; #include "src/SparseCore/SparseSelfAdjointView.h" #include "src/SparseCore/TriangularSolver.h" #include "src/SparseCore/SparseView.h" +#endif #include "src/Core/util/ReenableStupidWarnings.h" diff --git a/Eigen/src/SparseCore/SparseAssign.h b/Eigen/src/SparseCore/SparseAssign.h new file mode 100644 index 000000000..99a1a8712 --- /dev/null +++ b/Eigen/src/SparseCore/SparseAssign.h @@ -0,0 +1,252 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2014 Gael Guennebaud <gael.guennebaud@inria.fr> +// +// This Source Code Form is subject to the terms of the Mozilla +// 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_SPARSEASSIGN_H +#define EIGEN_SPARSEASSIGN_H + +namespace Eigen { + +#ifndef EIGEN_TEST_EVALUATORS + +template<typename Derived> +template<typename OtherDerived> +Derived& SparseMatrixBase<Derived>::operator=(const EigenBase<OtherDerived> &other) +{ + other.derived().evalTo(derived()); + return derived(); +} + +template<typename Derived> +template<typename OtherDerived> +Derived& SparseMatrixBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other) +{ + other.evalTo(derived()); + return derived(); +} + +template<typename Derived> +template<typename OtherDerived> +inline Derived& SparseMatrixBase<Derived>::operator=(const SparseMatrixBase<OtherDerived>& other) +{ + return assign(other.derived()); +} + +template<typename Derived> +inline Derived& SparseMatrixBase<Derived>::operator=(const Derived& other) +{ +// if (other.isRValue()) +// derived().swap(other.const_cast_derived()); +// else + return assign(other.derived()); +} + +template<typename Derived> +template<typename OtherDerived> +inline Derived& SparseMatrixBase<Derived>::assign(const OtherDerived& other) +{ + const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); + const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols(); + if ((!transpose) && other.isRValue()) + { + // eval without temporary + derived().resize(other.rows(), other.cols()); + derived().setZero(); + derived().reserve((std::max)(this->rows(),this->cols())*2); + for (Index j=0; j<outerSize; ++j) + { + derived().startVec(j); + for (typename OtherDerived::InnerIterator it(other, j); it; ++it) + { + Scalar v = it.value(); + derived().insertBackByOuterInner(j,it.index()) = v; + } + } + derived().finalize(); + } + else + { + assignGeneric(other); + } + return derived(); +} + +template<typename Derived> +template<typename OtherDerived> +inline void SparseMatrixBase<Derived>::assignGeneric(const OtherDerived& other) +{ + //const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); + eigen_assert(( ((internal::traits<Derived>::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) || + (!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) && + "the transpose operation is supposed to be handled in SparseMatrix::operator="); + + enum { Flip = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit) }; + + const Index outerSize = other.outerSize(); + //typedef typename internal::conditional<transpose, LinkedVectorMatrix<Scalar,Flags&RowMajorBit>, Derived>::type TempType; + // thanks to shallow copies, we always eval to a tempary + Derived temp(other.rows(), other.cols()); + + temp.reserve((std::max)(this->rows(),this->cols())*2); + for (Index j=0; j<outerSize; ++j) + { + temp.startVec(j); + for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it) + { + Scalar v = it.value(); + temp.insertBackByOuterInner(Flip?it.index():j,Flip?j:it.index()) = v; + } + } + temp.finalize(); + + derived() = temp.markAsRValue(); +} + +// template<typename Lhs, typename Rhs> +// inline Derived& operator=(const SparseSparseProduct<Lhs,Rhs>& product); +// +// template<typename OtherDerived> +// Derived& operator+=(const SparseMatrixBase<OtherDerived>& other); +// template<typename OtherDerived> +// Derived& operator-=(const SparseMatrixBase<OtherDerived>& other); +// +// Derived& operator*=(const Scalar& other); +// Derived& operator/=(const Scalar& other); +// +// template<typename OtherDerived> +// Derived& operator*=(const SparseMatrixBase<OtherDerived>& other); + +#else // EIGEN_TEST_EVALUATORS + +template<typename Derived> +template<typename OtherDerived> +Derived& SparseMatrixBase<Derived>::operator=(const EigenBase<OtherDerived> &other) +{ + other.derived().evalTo(derived()); + return derived(); +} + +template<typename Derived> +template<typename OtherDerived> +Derived& SparseMatrixBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other) +{ + other.evalTo(derived()); + return derived(); +} + +template<typename Derived> +template<typename OtherDerived> +inline Derived& SparseMatrixBase<Derived>::operator=(const SparseMatrixBase<OtherDerived>& other) +{ + internal::call_assignment_no_alias(derived(), other.derived()); + return derived(); +} + +template<typename Derived> +inline Derived& SparseMatrixBase<Derived>::operator=(const Derived& other) +{ + internal::call_assignment_no_alias(derived(), other.derived()); + return derived(); +} + +namespace internal { + +template<> +struct storage_kind_to_evaluator_kind<Sparse> { + typedef IteratorBased Kind; +}; + +template<> +struct storage_kind_to_shape<Sparse> { + typedef SparseShape Shape; +}; + +struct Sparse2Sparse {}; + +template<> struct AssignmentKind<SparseShape,SparseShape> { typedef Sparse2Sparse Kind; }; + + +template<typename DstXprType, typename SrcXprType> +void assign_sparse_to_sparse(DstXprType &dst, const SrcXprType &src) +{ + eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); + + typedef typename DstXprType::Index Index; + typedef typename DstXprType::Scalar Scalar; + typedef typename internal::evaluator<DstXprType>::type DstEvaluatorType; + typedef typename internal::evaluator<SrcXprType>::type SrcEvaluatorType; + + DstEvaluatorType dstEvaluator(dst); + SrcEvaluatorType srcEvaluator(src); + + const bool transpose = (DstEvaluatorType::Flags & RowMajorBit) != (SrcEvaluatorType::Flags & RowMajorBit); + const Index outerSize = (int(SrcEvaluatorType::Flags) & RowMajorBit) ? src.rows() : src.cols(); + if ((!transpose) && src.isRValue()) + { + // eval without temporary + dst.resize(src.rows(), src.cols()); + dst.setZero(); + dst.reserve((std::max)(src.rows(),src.cols())*2); + for (Index j=0; j<outerSize; ++j) + { + dst.startVec(j); + for (typename SrcEvaluatorType::InnerIterator it(srcEvaluator, j); it; ++it) + { + Scalar v = it.value(); + dst.insertBackByOuterInner(j,it.index()) = v; + } + } + dst.finalize(); + } + else + { + // eval through a temporary + eigen_assert(( ((internal::traits<DstXprType>::SupportedAccessPatterns & OuterRandomAccessPattern)==OuterRandomAccessPattern) || + (!((DstEvaluatorType::Flags & RowMajorBit) != (SrcEvaluatorType::Flags & RowMajorBit)))) && + "the transpose operation is supposed to be handled in SparseMatrix::operator="); + + enum { Flip = (DstEvaluatorType::Flags & RowMajorBit) != (SrcEvaluatorType::Flags & RowMajorBit) }; + + const Index outerSize = src.outerSize(); + DstXprType temp(src.rows(), src.cols()); + + temp.reserve((std::max)(src.rows(),src.cols())*2); + for (Index j=0; j<outerSize; ++j) + { + temp.startVec(j); + for (typename SrcEvaluatorType::InnerIterator it(src, j); it; ++it) + { + Scalar v = it.value(); + temp.insertBackByOuterInner(Flip?it.index():j,Flip?j:it.index()) = v; + } + } + temp.finalize(); + + dst = temp.markAsRValue(); + } +} + +// Generic Sparse to Sparse assignment +template< typename DstXprType, typename SrcXprType, typename Functor, typename Scalar> +struct Assignment<DstXprType, SrcXprType, Functor, Sparse2Sparse, Scalar> +{ + static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar> &/*func*/) + { + eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); + + assign_sparse_to_sparse(dst.derived(), src.derived()); + } +}; + +} // end namespace internal + +#endif // EIGEN_TEST_EVALUATORS + +} // end namespace Eigen + +#endif // EIGEN_SPARSEASSIGN_H diff --git a/Eigen/src/SparseCore/SparseCwiseUnaryOp.h b/Eigen/src/SparseCore/SparseCwiseUnaryOp.h index 5a50c7803..c5042504b 100644 --- a/Eigen/src/SparseCore/SparseCwiseUnaryOp.h +++ b/Eigen/src/SparseCore/SparseCwiseUnaryOp.h @@ -11,6 +11,8 @@ #define EIGEN_SPARSE_CWISE_UNARY_OP_H namespace Eigen { + +#ifndef EIGEN_TEST_EVALUATORS template<typename UnaryOp, typename MatrixType> class CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse> @@ -18,12 +20,12 @@ class CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse> { public: - class InnerIterator; - class ReverseInnerIterator; - typedef CwiseUnaryOp<UnaryOp, MatrixType> Derived; EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) + class InnerIterator; + class ReverseInnerIterator; + protected: typedef typename internal::traits<Derived>::_XprTypeNested _MatrixTypeNested; typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator; @@ -138,6 +140,148 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::ReverseInnerIterator const ViewOp m_functor; }; +#else // EIGEN_TEST_EVALUATORS + +namespace internal { + +template<typename UnaryOp, typename ArgType> +struct unary_evaluator<CwiseUnaryOp<UnaryOp,ArgType>, IteratorBased> + : public evaluator_base<CwiseUnaryOp<UnaryOp,ArgType> > +{ + public: + typedef CwiseUnaryOp<UnaryOp, ArgType> XprType; + + class InnerIterator; + class ReverseInnerIterator; + + enum { + CoeffReadCost = evaluator<ArgType>::CoeffReadCost + functor_traits<UnaryOp>::Cost, + Flags = XprType::Flags + }; + + unary_evaluator(const XprType& op) : m_functor(op.functor()), m_argImpl(op.nestedExpression()) {} + + protected: + typedef typename evaluator<ArgType>::InnerIterator EvalIterator; + typedef typename evaluator<ArgType>::ReverseInnerIterator EvalReverseIterator; + + const UnaryOp m_functor; + typename evaluator<ArgType>::nestedType m_argImpl; +}; + +template<typename UnaryOp, typename ArgType> +class unary_evaluator<CwiseUnaryOp<UnaryOp,ArgType>, IteratorBased>::InnerIterator + : public unary_evaluator<CwiseUnaryOp<UnaryOp,ArgType>, IteratorBased>::EvalIterator +{ + typedef typename XprType::Scalar Scalar; + typedef typename unary_evaluator<CwiseUnaryOp<UnaryOp,ArgType>, IteratorBased>::EvalIterator Base; + public: + + EIGEN_STRONG_INLINE InnerIterator(const unary_evaluator& unaryOp, typename XprType::Index outer) + : Base(unaryOp.m_argImpl,outer), m_functor(unaryOp.m_functor) + {} + + EIGEN_STRONG_INLINE InnerIterator& operator++() + { Base::operator++(); return *this; } + + EIGEN_STRONG_INLINE Scalar value() const { return m_functor(Base::value()); } + + protected: + const UnaryOp m_functor; + private: + Scalar& valueRef(); +}; + +template<typename UnaryOp, typename ArgType> +class unary_evaluator<CwiseUnaryOp<UnaryOp,ArgType>, IteratorBased>::ReverseInnerIterator + : public unary_evaluator<CwiseUnaryOp<UnaryOp,ArgType>, IteratorBased>::EvalReverseIterator +{ + typedef typename XprType::Scalar Scalar; + typedef typename unary_evaluator<CwiseUnaryOp<UnaryOp,ArgType>, IteratorBased>::EvalReverseIterator Base; + public: + + EIGEN_STRONG_INLINE ReverseInnerIterator(const XprType& unaryOp, typename XprType::Index outer) + : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) + {} + + EIGEN_STRONG_INLINE ReverseInnerIterator& operator--() + { Base::operator--(); return *this; } + + EIGEN_STRONG_INLINE Scalar value() const { return m_functor(Base::value()); } + + protected: + const UnaryOp m_functor; + private: + Scalar& valueRef(); +}; + + +// template<typename ViewOp, typename MatrixType> +// class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse> +// : public SparseMatrixBase<CwiseUnaryView<ViewOp, MatrixType> > +// { +// public: +// +// class InnerIterator; +// class ReverseInnerIterator; +// +// typedef CwiseUnaryView<ViewOp, MatrixType> Derived; +// EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) +// +// protected: +// typedef typename internal::traits<Derived>::_MatrixTypeNested _MatrixTypeNested; +// typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator; +// typedef typename _MatrixTypeNested::ReverseInnerIterator MatrixTypeReverseIterator; +// }; +// +// template<typename ViewOp, typename MatrixType> +// class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::InnerIterator +// : public CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeIterator +// { +// typedef typename CwiseUnaryViewImpl::Scalar Scalar; +// typedef typename CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeIterator Base; +// public: +// +// EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryViewImpl& unaryOp, typename CwiseUnaryViewImpl::Index outer) +// : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) +// {} +// +// EIGEN_STRONG_INLINE InnerIterator& operator++() +// { Base::operator++(); return *this; } +// +// EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar value() const { return m_functor(Base::value()); } +// EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar& valueRef() { return m_functor(Base::valueRef()); } +// +// protected: +// const ViewOp m_functor; +// }; +// +// template<typename ViewOp, typename MatrixType> +// class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::ReverseInnerIterator +// : public CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeReverseIterator +// { +// typedef typename CwiseUnaryViewImpl::Scalar Scalar; +// typedef typename CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::MatrixTypeReverseIterator Base; +// public: +// +// EIGEN_STRONG_INLINE ReverseInnerIterator(const CwiseUnaryViewImpl& unaryOp, typename CwiseUnaryViewImpl::Index outer) +// : Base(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived().functor()) +// {} +// +// EIGEN_STRONG_INLINE ReverseInnerIterator& operator--() +// { Base::operator--(); return *this; } +// +// EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar value() const { return m_functor(Base::value()); } +// EIGEN_STRONG_INLINE typename CwiseUnaryViewImpl::Scalar& valueRef() { return m_functor(Base::valueRef()); } +// +// protected: +// const ViewOp m_functor; +// }; + +} // end namespace internal + +#endif // EIGEN_TEST_EVALUATORS + template<typename Derived> EIGEN_STRONG_INLINE Derived& SparseMatrixBase<Derived>::operator*=(const Scalar& other) diff --git a/Eigen/src/SparseCore/SparseMatrix.h b/Eigen/src/SparseCore/SparseMatrix.h index 9ac18bcf6..a25bd83eb 100644 --- a/Eigen/src/SparseCore/SparseMatrix.h +++ b/Eigen/src/SparseCore/SparseMatrix.h @@ -1053,6 +1053,7 @@ void SparseMatrix<Scalar,_Options,_Index>::sumupDuplicates() m_data.resize(m_outerIndex[m_outerSize]); } +#ifndef EIGEN_TEST_EVALUATORS template<typename Scalar, int _Options, typename _Index> template<typename OtherDerived> EIGEN_DONT_INLINE SparseMatrix<Scalar,_Options,_Index>& SparseMatrix<Scalar,_Options,_Index>::operator=(const SparseMatrixBase<OtherDerived>& other) @@ -1114,6 +1115,71 @@ EIGEN_DONT_INLINE SparseMatrix<Scalar,_Options,_Index>& SparseMatrix<Scalar,_Opt return Base::operator=(other.derived()); } } +#else +template<typename Scalar, int _Options, typename _Index> +template<typename OtherDerived> +EIGEN_DONT_INLINE SparseMatrix<Scalar,_Options,_Index>& SparseMatrix<Scalar,_Options,_Index>::operator=(const SparseMatrixBase<OtherDerived>& other) +{ + EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value), + YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) + + const bool needToTranspose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); + if (needToTranspose) + { + // two passes algorithm: + // 1 - compute the number of coeffs per dest inner vector + // 2 - do the actual copy/eval + // Since each coeff of the rhs has to be evaluated twice, let's evaluate it if needed + typedef typename internal::nested_eval<OtherDerived,2>::type OtherCopy; + typedef typename internal::remove_all<OtherCopy>::type _OtherCopy; + typedef internal::evaluator<_OtherCopy> OtherCopyEval; + OtherCopy otherCopy(other.derived()); + OtherCopyEval otherCopyEval(otherCopy); + + 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 OtherCopyEval::InnerIterator it(otherCopyEval, j); it; ++it) + ++dest.m_outerIndex[it.index()]; + + // prefix sum + Index count = 0; + Matrix<Index,Dynamic,1> positions(dest.outerSize()); + for (Index j=0; j<dest.outerSize(); ++j) + { + Index tmp = dest.m_outerIndex[j]; + dest.m_outerIndex[j] = count; + positions[j] = count; + count += tmp; + } + dest.m_outerIndex[dest.outerSize()] = count; + // alloc + dest.m_data.resize(count); + // pass 2 + for (Index j=0; j<otherCopy.outerSize(); ++j) + { + for (typename OtherCopyEval::InnerIterator it(otherCopyEval, j); it; ++it) + { + Index pos = positions[it.index()]++; + 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()); + } +} +#endif template<typename _Scalar, int _Options, typename _Index> EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_Index>::Scalar& SparseMatrix<_Scalar,_Options,_Index>::insertUncompressed(Index row, Index col) @@ -1254,6 +1320,33 @@ EIGEN_DONT_INLINE typename SparseMatrix<_Scalar,_Options,_Index>::Scalar& Sparse return (m_data.value(p) = 0); } +#ifdef EIGEN_ENABLE_EVALUATORS +namespace internal { + +template<typename _Scalar, int _Options, typename _Index> +struct evaluator<SparseMatrix<_Scalar,_Options,_Index> > + : evaluator_base<SparseMatrix<_Scalar,_Options,_Index> > +{ + typedef SparseMatrix<_Scalar,_Options,_Index> SparseMatrixType; + typedef typename SparseMatrixType::InnerIterator InnerIterator; + typedef typename SparseMatrixType::ReverseInnerIterator ReverseInnerIterator; + + enum { + CoeffReadCost = NumTraits<_Scalar>::ReadCost, + Flags = SparseMatrixType::Flags + }; + + evaluator(const SparseMatrixType &mat) : m_matrix(mat) {} + + operator SparseMatrixType&() { return m_matrix.const_cast_derived(); } + operator const SparseMatrixType&() const { return m_matrix; } + + const SparseMatrixType &m_matrix; +}; + +} +#endif + } // end namespace Eigen #endif // EIGEN_SPARSEMATRIX_H diff --git a/Eigen/src/SparseCore/SparseMatrixBase.h b/Eigen/src/SparseCore/SparseMatrixBase.h index bbcf7fb1c..a87407fe9 100644 --- a/Eigen/src/SparseCore/SparseMatrixBase.h +++ b/Eigen/src/SparseCore/SparseMatrixBase.h @@ -39,11 +39,7 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> typedef EigenBase<Derived> Base; template<typename OtherDerived> - Derived& operator=(const EigenBase<OtherDerived> &other) - { - other.derived().evalTo(derived()); - return derived(); - } + Derived& operator=(const EigenBase<OtherDerived> &other); enum { @@ -175,87 +171,20 @@ template<typename Derived> class SparseMatrixBase : public EigenBase<Derived> template<typename OtherDerived> - Derived& operator=(const ReturnByValue<OtherDerived>& other) - { - other.evalTo(derived()); - return derived(); - } - + Derived& operator=(const ReturnByValue<OtherDerived>& other); template<typename OtherDerived> - inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other) - { - return assign(other.derived()); - } + inline Derived& operator=(const SparseMatrixBase<OtherDerived>& other); - inline Derived& operator=(const Derived& other) - { -// if (other.isRValue()) -// derived().swap(other.const_cast_derived()); -// else - return assign(other.derived()); - } + inline Derived& operator=(const Derived& other); protected: template<typename OtherDerived> - inline Derived& assign(const OtherDerived& other) - { - const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); - const Index outerSize = (int(OtherDerived::Flags) & RowMajorBit) ? other.rows() : other.cols(); - if ((!transpose) && other.isRValue()) - { - // eval without temporary - derived().resize(other.rows(), other.cols()); - derived().setZero(); - derived().reserve((std::max)(this->rows(),this->cols())*2); - for (Index j=0; j<outerSize; ++j) - { - derived().startVec(j); - for (typename OtherDerived::InnerIterator it(other, j); it; ++it) - { - Scalar v = it.value(); - derived().insertBackByOuterInner(j,it.index()) = v; - } - } - derived().finalize(); - } - else - { - assignGeneric(other); - } - return derived(); - } + inline Derived& assign(const OtherDerived& other); template<typename OtherDerived> - inline void assignGeneric(const OtherDerived& other) - { - //const bool transpose = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit); - eigen_assert(( ((internal::traits<Derived>::SupportedAccessPatterns&OuterRandomAccessPattern)==OuterRandomAccessPattern) || - (!((Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit)))) && - "the transpose operation is supposed to be handled in SparseMatrix::operator="); - - enum { Flip = (Flags & RowMajorBit) != (OtherDerived::Flags & RowMajorBit) }; - - const Index outerSize = other.outerSize(); - //typedef typename internal::conditional<transpose, LinkedVectorMatrix<Scalar,Flags&RowMajorBit>, Derived>::type TempType; - // thanks to shallow copies, we always eval to a tempary - Derived temp(other.rows(), other.cols()); - - temp.reserve((std::max)(this->rows(),this->cols())*2); - for (Index j=0; j<outerSize; ++j) - { - temp.startVec(j); - for (typename OtherDerived::InnerIterator it(other.derived(), j); it; ++it) - { - Scalar v = it.value(); - temp.insertBackByOuterInner(Flip?it.index():j,Flip?j:it.index()) = v; - } - } - temp.finalize(); - - derived() = temp.markAsRValue(); - } + inline void assignGeneric(const OtherDerived& other); public: diff --git a/Eigen/src/SparseCore/SparseUtil.h b/Eigen/src/SparseCore/SparseUtil.h index 05023858b..e23576572 100644 --- a/Eigen/src/SparseCore/SparseUtil.h +++ b/Eigen/src/SparseCore/SparseUtil.h @@ -133,6 +133,12 @@ template<typename T> struct plain_matrix_type<T,Sparse> typedef SparseMatrix<_Scalar, _Options, _Index> type; }; +template<typename Derived> +struct generic_xpr_base<Derived, MatrixXpr, Sparse> +{ + typedef SparseMatrixBase<Derived> type; +}; + } // end namespace internal /** \ingroup SparseCore_Module |