mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Started to move the SparseCore module to evaluators: implemented assignment and cwise-unary evaluator
This commit is contained in:
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user