Make assignment from general EigenBase object call evaluator, and support dense X= sparse

This commit is contained in:
Gael Guennebaud 2014-08-01 16:23:30 +02:00
parent 2a3c3c49a1
commit c2ff44cbf3
2 changed files with 33 additions and 4 deletions

View File

@ -121,7 +121,11 @@ template<typename Derived>
template<typename OtherDerived>
Derived& DenseBase<Derived>::operator=(const EigenBase<OtherDerived> &other)
{
#ifndef EIGEN_TEST_EVALUATORS
other.derived().evalTo(derived());
#else
call_assignment(derived(), other.derived());
#endif
return derived();
}
@ -129,7 +133,11 @@ template<typename Derived>
template<typename OtherDerived>
Derived& DenseBase<Derived>::operator+=(const EigenBase<OtherDerived> &other)
{
#ifndef EIGEN_TEST_EVALUATORS
other.derived().addTo(derived());
#else
call_assignment(derived(), other.derived(), internal::add_assign_op<Scalar>());
#endif
return derived();
}
@ -137,7 +145,11 @@ template<typename Derived>
template<typename OtherDerived>
Derived& DenseBase<Derived>::operator-=(const EigenBase<OtherDerived> &other)
{
#ifndef EIGEN_TEST_EVALUATORS
other.derived().subTo(derived());
#else
call_assignment(derived(), other.derived(), internal::sub_assign_op<Scalar>());
#endif
return derived();
}

View File

@ -172,9 +172,9 @@ struct storage_kind_to_shape<Sparse> {
struct Sparse2Sparse {};
struct Sparse2Dense {};
template<> struct AssignmentKind<SparseShape,SparseShape> { typedef Sparse2Sparse Kind; };
template<> struct AssignmentKind<SparseShape,SparseTriangularShape> { typedef Sparse2Sparse Kind; };
template<> struct AssignmentKind<DenseShape,SparseShape> { typedef Sparse2Dense Kind; };
template<> struct AssignmentKind<SparseShape, SparseShape> { typedef Sparse2Sparse Kind; };
template<> struct AssignmentKind<SparseShape, SparseTriangularShape> { typedef Sparse2Sparse Kind; };
template<> struct AssignmentKind<DenseShape, SparseShape> { typedef Sparse2Dense Kind; };
template<typename DstXprType, typename SrcXprType>
@ -252,7 +252,24 @@ struct Assignment<DstXprType, SrcXprType, Functor, Sparse2Sparse, Scalar>
template< typename DstXprType, typename SrcXprType, typename Functor, typename Scalar>
struct Assignment<DstXprType, SrcXprType, Functor, Sparse2Dense, Scalar>
{
static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar> &/*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<SrcXprType>::type srcEval(src);
typename internal::evaluator<DstXprType>::type dstEval(dst);
const Index outerEvaluationSize = (internal::evaluator<SrcXprType>::Flags&RowMajorBit) ? src.rows() : src.cols();
for (Index j=0; j<outerEvaluationSize; ++j)
for (typename internal::evaluator<SrcXprType>::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<DstXprType, SrcXprType, internal::assign_op<typename DstXprType::Scalar>, Sparse2Dense, Scalar>
{
static void run(DstXprType &dst, const SrcXprType &src, const internal::assign_op<typename DstXprType::Scalar> &)
{
eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
typedef typename SrcXprType::Index Index;