mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-03-13 18:37:27 +08:00
Started to move the SparseCore module to evaluators: implemented assignment and cwise-unary evaluator
This commit is contained in:
parent
78bb808337
commit
c415b627a7
@ -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"
|
||||
|
||||
|
252
Eigen/src/SparseCore/SparseAssign.h
Normal file
252
Eigen/src/SparseCore/SparseAssign.h
Normal file
@ -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
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user