From c2ff44cbf3c58045a38120d28316a992c0cc0d57 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Fri, 1 Aug 2014 16:23:30 +0200 Subject: [PATCH] Make assignment from general EigenBase object call evaluator, and support dense X= sparse --- Eigen/src/Core/EigenBase.h | 12 ++++++++++++ Eigen/src/SparseCore/SparseAssign.h | 25 +++++++++++++++++++++---- 2 files changed, 33 insertions(+), 4 deletions(-) diff --git a/Eigen/src/Core/EigenBase.h b/Eigen/src/Core/EigenBase.h index 1a577c2dc..986e2a196 100644 --- a/Eigen/src/Core/EigenBase.h +++ b/Eigen/src/Core/EigenBase.h @@ -121,7 +121,11 @@ template template Derived& DenseBase::operator=(const EigenBase &other) { +#ifndef EIGEN_TEST_EVALUATORS other.derived().evalTo(derived()); +#else + call_assignment(derived(), other.derived()); +#endif return derived(); } @@ -129,7 +133,11 @@ template template Derived& DenseBase::operator+=(const EigenBase &other) { +#ifndef EIGEN_TEST_EVALUATORS other.derived().addTo(derived()); +#else + call_assignment(derived(), other.derived(), internal::add_assign_op()); +#endif return derived(); } @@ -137,7 +145,11 @@ template template Derived& DenseBase::operator-=(const EigenBase &other) { +#ifndef EIGEN_TEST_EVALUATORS other.derived().subTo(derived()); +#else + call_assignment(derived(), other.derived(), internal::sub_assign_op()); +#endif return derived(); } diff --git a/Eigen/src/SparseCore/SparseAssign.h b/Eigen/src/SparseCore/SparseAssign.h index c2091ee49..0a29cb32f 100644 --- a/Eigen/src/SparseCore/SparseAssign.h +++ b/Eigen/src/SparseCore/SparseAssign.h @@ -172,9 +172,9 @@ struct storage_kind_to_shape { struct Sparse2Sparse {}; struct Sparse2Dense {}; -template<> struct AssignmentKind { typedef Sparse2Sparse Kind; }; -template<> struct AssignmentKind { typedef Sparse2Sparse Kind; }; -template<> struct AssignmentKind { typedef Sparse2Dense Kind; }; +template<> struct AssignmentKind { typedef Sparse2Sparse Kind; }; +template<> struct AssignmentKind { typedef Sparse2Sparse Kind; }; +template<> struct AssignmentKind { typedef Sparse2Dense Kind; }; template @@ -252,7 +252,24 @@ struct Assignment template< typename DstXprType, typename SrcXprType, typename Functor, typename Scalar> struct Assignment { - static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op &/*func*/) + static void run(DstXprType &dst, const SrcXprType &src, const Functor &func) + { + eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); + typedef typename SrcXprType::Index Index; + + typename internal::evaluator::type srcEval(src); + typename internal::evaluator::type dstEval(dst); + const Index outerEvaluationSize = (internal::evaluator::Flags&RowMajorBit) ? src.rows() : src.cols(); + for (Index j=0; j::InnerIterator i(srcEval,j); i; ++i) + func.assignCoeff(dstEval.coeffRef(i.row(),i.col()), i.value()); + } +}; + +template< typename DstXprType, typename SrcXprType, typename Scalar> +struct Assignment, Sparse2Dense, Scalar> +{ + static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op &) { eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols()); typedef typename SrcXprType::Index Index;