mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-01-06 14:14:46 +08:00
1- Introduce sub-evaluator types for unary, binary, product, and map expressions to ease specializing them.
2- Remove a lot of code which should not be there with evaluators, in particular coeff/packet methods implemented in the expressions.
This commit is contained in:
parent
0a6c472335
commit
78bb808337
@ -123,7 +123,11 @@ template<typename Derived> class ArrayBase
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& operator=(const ArrayBase& other)
|
||||
{
|
||||
#ifndef EIGEN_TEST_EVALUATORS
|
||||
return internal::assign_selector<Derived,Derived>::run(derived(), other.derived());
|
||||
#else
|
||||
internal::call_assignment(derived(), other.derived());
|
||||
#endif
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
|
@ -39,6 +39,7 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
|
||||
typedef ArrayBase<ArrayWrapper> Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper)
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper)
|
||||
typedef typename internal::remove_all<ExpressionType>::type NestedExpression;
|
||||
|
||||
typedef typename internal::conditional<
|
||||
internal::is_lvalue<ExpressionType>::value,
|
||||
@ -176,6 +177,7 @@ class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
|
||||
typedef MatrixBase<MatrixWrapper<ExpressionType> > Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(MatrixWrapper)
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper)
|
||||
typedef typename internal::remove_all<ExpressionType>::type NestedExpression;
|
||||
|
||||
typedef typename internal::conditional<
|
||||
internal::is_lvalue<ExpressionType>::value,
|
||||
|
@ -344,6 +344,9 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||
: public MapBase<Block<XprType, BlockRows, BlockCols, InnerPanel> >
|
||||
{
|
||||
typedef Block<XprType, BlockRows, BlockCols, InnerPanel> BlockType;
|
||||
enum {
|
||||
XprTypeIsRowMajor = (int(traits<XprType>::Flags)&RowMajorBit) != 0
|
||||
};
|
||||
public:
|
||||
|
||||
typedef MapBase<BlockType> Base;
|
||||
@ -354,9 +357,8 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline BlockImpl_dense(XprType& xpr, Index i)
|
||||
: Base(internal::const_cast_ptr(&xpr.coeffRef(
|
||||
(BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) ? i : 0,
|
||||
(BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) ? i : 0)),
|
||||
: Base(xpr.data() + i * ( ((BlockRows==1) && (BlockCols==XprType::ColsAtCompileTime) && (!XprTypeIsRowMajor))
|
||||
|| ((BlockRows==XprType::RowsAtCompileTime) && (BlockCols==1) && ( XprTypeIsRowMajor)) ? xpr.innerStride() : xpr.outerStride()),
|
||||
BlockRows==1 ? 1 : xpr.rows(),
|
||||
BlockCols==1 ? 1 : xpr.cols()),
|
||||
m_xpr(xpr)
|
||||
@ -368,7 +370,8 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||
*/
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline BlockImpl_dense(XprType& xpr, Index startRow, Index startCol)
|
||||
: Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol))), m_xpr(xpr)
|
||||
: Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol)),
|
||||
m_xpr(xpr)
|
||||
{
|
||||
init();
|
||||
}
|
||||
@ -379,7 +382,7 @@ class BlockImpl_dense<XprType,BlockRows,BlockCols, InnerPanel,true>
|
||||
inline BlockImpl_dense(XprType& xpr,
|
||||
Index startRow, Index startCol,
|
||||
Index blockRows, Index blockCols)
|
||||
: Base(internal::const_cast_ptr(&xpr.coeffRef(startRow,startCol)), blockRows, blockCols),
|
||||
: Base(xpr.data()+xpr.innerStride()*(XprTypeIsRowMajor?startCol:startRow) + xpr.outerStride()*(XprTypeIsRowMajor?startRow:startCol), blockRows, blockCols),
|
||||
m_xpr(xpr)
|
||||
{
|
||||
init();
|
||||
|
@ -27,14 +27,6 @@ struct storage_kind_to_evaluator_kind {
|
||||
typedef IndexBased Kind;
|
||||
};
|
||||
|
||||
// TODO to be moved to SparseCore:
|
||||
/*
|
||||
template<>
|
||||
struct storage_kind_to_evaluator_kind<Sparse> {
|
||||
typedef IteratorBased Kind
|
||||
};
|
||||
*/
|
||||
|
||||
// This class returns the evaluator shape from the expression storage kind.
|
||||
// It can be Dense, Sparse, Triangular, Diagonal, SelfAdjoint, Band, etc.
|
||||
template<typename StorageKind> struct storage_kind_to_shape;
|
||||
@ -45,22 +37,28 @@ struct storage_kind_to_shape<Dense> {
|
||||
typedef DenseShape Shape;
|
||||
};
|
||||
|
||||
// TODO to be moved to SparseCore:
|
||||
/*
|
||||
template<>
|
||||
struct storage_kind_to_shape<Sparse> {
|
||||
typedef SparseSpape Shape;
|
||||
};
|
||||
*/
|
||||
// Evaluators have to be specialized with respect to various criteria such as:
|
||||
// - storage/structure/shape
|
||||
// - scalar type
|
||||
// - etc.
|
||||
// Therefore, we need specialization of evaluator providing additional template arguments for each kind of evaluators.
|
||||
// We currently distinguish the following kind of evaluators:
|
||||
// - unary_evaluator for expressions taking only one arguments (CwiseUnaryOp, CwiseUnaryView, Transpose, MatrixWrapper, ArrayWrapper, Reverse, Replicate)
|
||||
// - binary_evaluator for expression taking two arguments (CwiseBinaryOp)
|
||||
// - product_evaluator for linear algebra products (Product); special case of binary_evaluator because it requires additional tags for dispatching.
|
||||
// - mapbase_evaluator for Map, Block, Ref
|
||||
// - block_evaluator for Block (special dispatching to a mapbase_evaluator or unary_evaluator)
|
||||
|
||||
|
||||
|
||||
template< typename T,
|
||||
typename LhsKind = typename evaluator_traits<typename T::Lhs>::Kind,
|
||||
typename RhsKind = typename evaluator_traits<typename T::Rhs>::Kind,
|
||||
typename LhsKind = typename evaluator_traits<typename T::Lhs>::Kind,
|
||||
typename RhsKind = typename evaluator_traits<typename T::Rhs>::Kind,
|
||||
typename LhsScalar = typename T::Lhs::Scalar,
|
||||
typename RhsScalar = typename T::Rhs::Scalar> struct binary_evaluator;
|
||||
|
||||
template< typename T,
|
||||
typename Kind = typename evaluator_traits<typename T::NestedExpression>::Kind,
|
||||
typename Scalar = typename T::Scalar> struct unary_evaluator;
|
||||
|
||||
// evaluator_traits<T> contains traits for evaluator<T>
|
||||
|
||||
template<typename T>
|
||||
@ -80,15 +78,20 @@ struct evaluator_traits_base
|
||||
static const int AssumeAliasing = 0;
|
||||
};
|
||||
|
||||
// Default evaluator traits
|
||||
template<typename T>
|
||||
struct evaluator_traits : public evaluator_traits_base<T>
|
||||
{
|
||||
};
|
||||
|
||||
// expression class for evaluating nested expression to a temporary
|
||||
|
||||
template<typename ArgType>
|
||||
class EvalToTemp;
|
||||
|
||||
// By default, we assume a unary expression:
|
||||
template<typename T>
|
||||
struct evaluator : public unary_evaluator<T>
|
||||
{
|
||||
typedef unary_evaluator<T> Base;
|
||||
evaluator(const T& xpr) : Base(xpr) {}
|
||||
};
|
||||
|
||||
|
||||
// TODO: Think about const-correctness
|
||||
@ -118,6 +121,8 @@ struct evaluator_base
|
||||
//
|
||||
// evaluator<PlainObjectBase> is a common base class for the
|
||||
// Matrix and Array evaluators.
|
||||
// Here we directly specialize evaluator. This is not really a unary expression, and it is, by definition, dense,
|
||||
// so no need for more sophisticated dispatching.
|
||||
|
||||
template<typename Derived>
|
||||
struct evaluator<PlainObjectBase<Derived> >
|
||||
@ -245,81 +250,10 @@ struct evaluator<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
|
||||
{ }
|
||||
};
|
||||
|
||||
// -------------------- EvalToTemp --------------------
|
||||
|
||||
template<typename ArgType>
|
||||
struct traits<EvalToTemp<ArgType> >
|
||||
: public traits<ArgType>
|
||||
{ };
|
||||
|
||||
template<typename ArgType>
|
||||
class EvalToTemp
|
||||
: public dense_xpr_base<EvalToTemp<ArgType> >::type
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename dense_xpr_base<EvalToTemp>::type Base;
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(EvalToTemp)
|
||||
|
||||
EvalToTemp(const ArgType& arg)
|
||||
: m_arg(arg)
|
||||
{ }
|
||||
|
||||
const ArgType& arg() const
|
||||
{
|
||||
return m_arg;
|
||||
}
|
||||
|
||||
Index rows() const
|
||||
{
|
||||
return m_arg.rows();
|
||||
}
|
||||
|
||||
Index cols() const
|
||||
{
|
||||
return m_arg.cols();
|
||||
}
|
||||
|
||||
private:
|
||||
const ArgType& m_arg;
|
||||
};
|
||||
|
||||
template<typename ArgType>
|
||||
struct evaluator<EvalToTemp<ArgType> >
|
||||
: public evaluator<typename ArgType::PlainObject>::type
|
||||
{
|
||||
typedef EvalToTemp<ArgType> XprType;
|
||||
typedef typename ArgType::PlainObject PlainObject;
|
||||
typedef typename evaluator<PlainObject>::type Base;
|
||||
|
||||
typedef evaluator type;
|
||||
typedef evaluator nestedType;
|
||||
|
||||
evaluator(const XprType& xpr)
|
||||
: m_result(xpr.rows(), xpr.cols())
|
||||
{
|
||||
::new (static_cast<Base*>(this)) Base(m_result);
|
||||
// TODO we should simply do m_result(xpr.arg());
|
||||
call_dense_assignment_loop(m_result, xpr.arg());
|
||||
}
|
||||
|
||||
// This constructor is used when nesting an EvalTo evaluator in another evaluator
|
||||
evaluator(const ArgType& arg)
|
||||
: m_result(arg.rows(), arg.cols())
|
||||
{
|
||||
::new (static_cast<Base*>(this)) Base(m_result);
|
||||
// TODO we should simply do m_result(xpr.arg());
|
||||
call_dense_assignment_loop(m_result, arg);
|
||||
}
|
||||
|
||||
protected:
|
||||
PlainObject m_result;
|
||||
};
|
||||
|
||||
// -------------------- Transpose --------------------
|
||||
|
||||
template<typename ArgType>
|
||||
struct evaluator<Transpose<ArgType> >
|
||||
struct unary_evaluator<Transpose<ArgType> >
|
||||
: evaluator_base<Transpose<ArgType> >
|
||||
{
|
||||
typedef Transpose<ArgType> XprType;
|
||||
@ -329,7 +263,7 @@ struct evaluator<Transpose<ArgType> >
|
||||
Flags = evaluator<ArgType>::Flags ^ RowMajorBit
|
||||
};
|
||||
|
||||
evaluator(const XprType& t) : m_argImpl(t.nestedExpression()) {}
|
||||
unary_evaluator(const XprType& t) : m_argImpl(t.nestedExpression()) {}
|
||||
|
||||
typedef typename XprType::Index Index;
|
||||
typedef typename XprType::Scalar Scalar;
|
||||
@ -386,6 +320,8 @@ protected:
|
||||
};
|
||||
|
||||
// -------------------- CwiseNullaryOp --------------------
|
||||
// Like Matrix and Array, this is not really a unary expression, so we directly specialize evaluator.
|
||||
// Likewise, there is not need to more sophisticated dispatching here.
|
||||
|
||||
template<typename NullaryOp, typename PlainObjectType>
|
||||
struct evaluator<CwiseNullaryOp<NullaryOp,PlainObjectType> >
|
||||
@ -441,7 +377,7 @@ protected:
|
||||
// -------------------- CwiseUnaryOp --------------------
|
||||
|
||||
template<typename UnaryOp, typename ArgType>
|
||||
struct evaluator<CwiseUnaryOp<UnaryOp, ArgType> >
|
||||
struct unary_evaluator<CwiseUnaryOp<UnaryOp, ArgType>, IndexBased >
|
||||
: evaluator_base<CwiseUnaryOp<UnaryOp, ArgType> >
|
||||
{
|
||||
typedef CwiseUnaryOp<UnaryOp, ArgType> XprType;
|
||||
@ -454,7 +390,7 @@ struct evaluator<CwiseUnaryOp<UnaryOp, ArgType> >
|
||||
| (functor_traits<UnaryOp>::PacketAccess ? PacketAccessBit : 0))
|
||||
};
|
||||
|
||||
evaluator(const XprType& op)
|
||||
unary_evaluator(const XprType& op)
|
||||
: m_functor(op.functor()),
|
||||
m_argImpl(op.nestedExpression())
|
||||
{ }
|
||||
@ -492,8 +428,19 @@ protected:
|
||||
|
||||
// -------------------- CwiseBinaryOp --------------------
|
||||
|
||||
// this is a binary expression
|
||||
template<typename BinaryOp, typename Lhs, typename Rhs>
|
||||
struct evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
||||
: public binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
||||
{
|
||||
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
|
||||
typedef binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > Base;
|
||||
|
||||
evaluator(const XprType& xpr) : Base(xpr) {}
|
||||
};
|
||||
|
||||
template<typename BinaryOp, typename Lhs, typename Rhs>
|
||||
struct binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
||||
: evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
||||
{
|
||||
typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
|
||||
@ -517,7 +464,7 @@ struct evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
||||
Flags = (Flags0 & ~RowMajorBit) | (LhsFlags & RowMajorBit)
|
||||
};
|
||||
|
||||
evaluator(const XprType& xpr)
|
||||
binary_evaluator(const XprType& xpr)
|
||||
: m_functor(xpr.functor()),
|
||||
m_lhsImpl(xpr.lhs()),
|
||||
m_rhsImpl(xpr.rhs())
|
||||
@ -560,7 +507,7 @@ protected:
|
||||
// -------------------- CwiseUnaryView --------------------
|
||||
|
||||
template<typename UnaryOp, typename ArgType>
|
||||
struct evaluator<CwiseUnaryView<UnaryOp, ArgType> >
|
||||
struct unary_evaluator<CwiseUnaryView<UnaryOp, ArgType> >
|
||||
: evaluator_base<CwiseUnaryView<UnaryOp, ArgType> >
|
||||
{
|
||||
typedef CwiseUnaryView<UnaryOp, ArgType> XprType;
|
||||
@ -571,7 +518,7 @@ struct evaluator<CwiseUnaryView<UnaryOp, ArgType> >
|
||||
Flags = (evaluator<ArgType>::Flags & (HereditaryBits | LinearAccessBit | DirectAccessBit))
|
||||
};
|
||||
|
||||
evaluator(const XprType& op)
|
||||
unary_evaluator(const XprType& op)
|
||||
: m_unaryOp(op.functor()),
|
||||
m_argImpl(op.nestedExpression())
|
||||
{ }
|
||||
@ -884,6 +831,7 @@ struct block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel, /* HasDirectAc
|
||||
|
||||
|
||||
// -------------------- Select --------------------
|
||||
// TODO shall we introduce a ternary_evaluator?
|
||||
|
||||
// TODO enable vectorization for Select
|
||||
template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType>
|
||||
@ -934,7 +882,7 @@ protected:
|
||||
// -------------------- Replicate --------------------
|
||||
|
||||
template<typename ArgType, int RowFactor, int ColFactor>
|
||||
struct evaluator<Replicate<ArgType, RowFactor, ColFactor> >
|
||||
struct unary_evaluator<Replicate<ArgType, RowFactor, ColFactor> >
|
||||
: evaluator_base<Replicate<ArgType, RowFactor, ColFactor> >
|
||||
{
|
||||
typedef Replicate<ArgType, RowFactor, ColFactor> XprType;
|
||||
@ -953,7 +901,7 @@ struct evaluator<Replicate<ArgType, RowFactor, ColFactor> >
|
||||
Flags = (evaluator<ArgTypeNestedCleaned>::Flags & HereditaryBits & ~RowMajorBit) | (traits<XprType>::Flags & RowMajorBit)
|
||||
};
|
||||
|
||||
evaluator(const XprType& replicate)
|
||||
unary_evaluator(const XprType& replicate)
|
||||
: m_arg(replicate.nestedExpression()),
|
||||
m_argImpl(m_arg),
|
||||
m_rows(replicate.nestedExpression().rows()),
|
||||
@ -1111,23 +1059,23 @@ protected:
|
||||
};
|
||||
|
||||
template<typename TArgType>
|
||||
struct evaluator<MatrixWrapper<TArgType> >
|
||||
struct unary_evaluator<MatrixWrapper<TArgType> >
|
||||
: evaluator_wrapper_base<MatrixWrapper<TArgType> >
|
||||
{
|
||||
typedef MatrixWrapper<TArgType> XprType;
|
||||
|
||||
evaluator(const XprType& wrapper)
|
||||
unary_evaluator(const XprType& wrapper)
|
||||
: evaluator_wrapper_base<MatrixWrapper<TArgType> >(wrapper.nestedExpression())
|
||||
{ }
|
||||
};
|
||||
|
||||
template<typename TArgType>
|
||||
struct evaluator<ArrayWrapper<TArgType> >
|
||||
struct unary_evaluator<ArrayWrapper<TArgType> >
|
||||
: evaluator_wrapper_base<ArrayWrapper<TArgType> >
|
||||
{
|
||||
typedef ArrayWrapper<TArgType> XprType;
|
||||
|
||||
evaluator(const XprType& wrapper)
|
||||
unary_evaluator(const XprType& wrapper)
|
||||
: evaluator_wrapper_base<ArrayWrapper<TArgType> >(wrapper.nestedExpression())
|
||||
{ }
|
||||
};
|
||||
@ -1139,7 +1087,7 @@ struct evaluator<ArrayWrapper<TArgType> >
|
||||
template<typename PacketScalar, bool ReversePacket> struct reverse_packet_cond;
|
||||
|
||||
template<typename ArgType, int Direction>
|
||||
struct evaluator<Reverse<ArgType, Direction> >
|
||||
struct unary_evaluator<Reverse<ArgType, Direction> >
|
||||
: evaluator_base<Reverse<ArgType, Direction> >
|
||||
{
|
||||
typedef Reverse<ArgType, Direction> XprType;
|
||||
@ -1173,7 +1121,7 @@ struct evaluator<Reverse<ArgType, Direction> >
|
||||
};
|
||||
typedef internal::reverse_packet_cond<PacketScalar,ReversePacket> reverse_packet;
|
||||
|
||||
evaluator(const XprType& reverse)
|
||||
unary_evaluator(const XprType& reverse)
|
||||
: m_argImpl(reverse.nestedExpression()),
|
||||
m_rows(ReverseRow ? reverse.nestedExpression().rows() : 0),
|
||||
m_cols(ReverseCol ? reverse.nestedExpression().cols() : 0)
|
||||
@ -1292,6 +1240,87 @@ private:
|
||||
EIGEN_STRONG_INLINE Index colOffset() const { return m_index.value() > 0 ? m_index.value() : 0; }
|
||||
};
|
||||
|
||||
|
||||
|
||||
//----------------------------------------------------------------------
|
||||
// deprecated code
|
||||
//----------------------------------------------------------------------
|
||||
|
||||
// -------------------- EvalToTemp --------------------
|
||||
|
||||
// expression class for evaluating nested expression to a temporary
|
||||
|
||||
template<typename ArgType> class EvalToTemp;
|
||||
|
||||
template<typename ArgType>
|
||||
struct traits<EvalToTemp<ArgType> >
|
||||
: public traits<ArgType>
|
||||
{ };
|
||||
|
||||
template<typename ArgType>
|
||||
class EvalToTemp
|
||||
: public dense_xpr_base<EvalToTemp<ArgType> >::type
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename dense_xpr_base<EvalToTemp>::type Base;
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(EvalToTemp)
|
||||
|
||||
EvalToTemp(const ArgType& arg)
|
||||
: m_arg(arg)
|
||||
{ }
|
||||
|
||||
const ArgType& arg() const
|
||||
{
|
||||
return m_arg;
|
||||
}
|
||||
|
||||
Index rows() const
|
||||
{
|
||||
return m_arg.rows();
|
||||
}
|
||||
|
||||
Index cols() const
|
||||
{
|
||||
return m_arg.cols();
|
||||
}
|
||||
|
||||
private:
|
||||
const ArgType& m_arg;
|
||||
};
|
||||
|
||||
template<typename ArgType>
|
||||
struct evaluator<EvalToTemp<ArgType> >
|
||||
: public evaluator<typename ArgType::PlainObject>::type
|
||||
{
|
||||
typedef EvalToTemp<ArgType> XprType;
|
||||
typedef typename ArgType::PlainObject PlainObject;
|
||||
typedef typename evaluator<PlainObject>::type Base;
|
||||
|
||||
typedef evaluator type;
|
||||
typedef evaluator nestedType;
|
||||
|
||||
evaluator(const XprType& xpr)
|
||||
: m_result(xpr.rows(), xpr.cols())
|
||||
{
|
||||
::new (static_cast<Base*>(this)) Base(m_result);
|
||||
// TODO we should simply do m_result(xpr.arg());
|
||||
call_dense_assignment_loop(m_result, xpr.arg());
|
||||
}
|
||||
|
||||
// This constructor is used when nesting an EvalTo evaluator in another evaluator
|
||||
evaluator(const ArgType& arg)
|
||||
: m_result(arg.rows(), arg.cols())
|
||||
{
|
||||
::new (static_cast<Base*>(this)) Base(m_result);
|
||||
// TODO we should simply do m_result(xpr.arg());
|
||||
call_dense_assignment_loop(m_result, arg);
|
||||
}
|
||||
|
||||
protected:
|
||||
PlainObject m_result;
|
||||
};
|
||||
|
||||
} // namespace internal
|
||||
|
||||
} // end namespace Eigen
|
||||
|
@ -94,23 +94,26 @@ struct traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
|
||||
template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind>
|
||||
class CwiseBinaryOpImpl;
|
||||
|
||||
template<typename BinaryOp, typename Lhs, typename Rhs>
|
||||
template<typename BinaryOp, typename LhsType, typename RhsType>
|
||||
class CwiseBinaryOp : internal::no_assignment_operator,
|
||||
public CwiseBinaryOpImpl<
|
||||
BinaryOp, Lhs, Rhs,
|
||||
typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind,
|
||||
typename internal::traits<Rhs>::StorageKind>::ret>
|
||||
BinaryOp, LhsType, RhsType,
|
||||
typename internal::promote_storage_type<typename internal::traits<LhsType>::StorageKind,
|
||||
typename internal::traits<RhsType>::StorageKind>::ret>
|
||||
{
|
||||
public:
|
||||
|
||||
typedef typename internal::remove_all<LhsType>::type Lhs;
|
||||
typedef typename internal::remove_all<RhsType>::type Rhs;
|
||||
|
||||
typedef typename CwiseBinaryOpImpl<
|
||||
BinaryOp, Lhs, Rhs,
|
||||
typename internal::promote_storage_type<typename internal::traits<Lhs>::StorageKind,
|
||||
BinaryOp, LhsType, RhsType,
|
||||
typename internal::promote_storage_type<typename internal::traits<LhsType>::StorageKind,
|
||||
typename internal::traits<Rhs>::StorageKind>::ret>::Base Base;
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp)
|
||||
|
||||
typedef typename internal::nested<Lhs>::type LhsNested;
|
||||
typedef typename internal::nested<Rhs>::type RhsNested;
|
||||
typedef typename internal::nested<LhsType>::type LhsNested;
|
||||
typedef typename internal::nested<RhsType>::type RhsNested;
|
||||
typedef typename internal::remove_reference<LhsNested>::type _LhsNested;
|
||||
typedef typename internal::remove_reference<RhsNested>::type _RhsNested;
|
||||
|
||||
@ -157,6 +160,7 @@ class CwiseBinaryOp : internal::no_assignment_operator,
|
||||
const BinaryOp m_functor;
|
||||
};
|
||||
|
||||
#ifndef EIGEN_TEST_EVALUATORS
|
||||
template<typename BinaryOp, typename Lhs, typename Rhs>
|
||||
class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Dense>
|
||||
: public internal::dense_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type
|
||||
@ -195,6 +199,16 @@ class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Dense>
|
||||
derived().rhs().template packet<LoadMode>(index));
|
||||
}
|
||||
};
|
||||
#else
|
||||
// Generic API dispatcher
|
||||
template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageKind>
|
||||
class CwiseBinaryOpImpl
|
||||
: public internal::generic_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type
|
||||
{
|
||||
public:
|
||||
typedef typename internal::generic_xpr_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::type Base;
|
||||
};
|
||||
#endif
|
||||
|
||||
/** replaces \c *this by \c *this - \a other.
|
||||
*
|
||||
|
@ -67,6 +67,7 @@ class CwiseUnaryOp : internal::no_assignment_operator,
|
||||
|
||||
typedef typename CwiseUnaryOpImpl<UnaryOp, XprType,typename internal::traits<XprType>::StorageKind>::Base Base;
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryOp)
|
||||
typedef typename internal::remove_all<XprType>::type NestedExpression;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline CwiseUnaryOp(const XprType& xpr, const UnaryOp& func = UnaryOp())
|
||||
@ -96,6 +97,7 @@ class CwiseUnaryOp : internal::no_assignment_operator,
|
||||
const UnaryOp m_functor;
|
||||
};
|
||||
|
||||
#ifndef EIGEN_TEST_EVALUATORS
|
||||
// This is the generic implementation for dense storage.
|
||||
// It can be used for any expression types implementing the dense concept.
|
||||
template<typename UnaryOp, typename XprType>
|
||||
@ -107,7 +109,7 @@ class CwiseUnaryOpImpl<UnaryOp,XprType,Dense>
|
||||
typedef CwiseUnaryOp<UnaryOp, XprType> Derived;
|
||||
typedef typename internal::dense_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
||||
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
EIGEN_STRONG_INLINE const Scalar coeff(Index rowId, Index colId) const
|
||||
{
|
||||
@ -133,6 +135,16 @@ class CwiseUnaryOpImpl<UnaryOp,XprType,Dense>
|
||||
return derived().functor().packetOp(derived().nestedExpression().template packet<LoadMode>(index));
|
||||
}
|
||||
};
|
||||
#else
|
||||
// Generic API dispatcher
|
||||
template<typename UnaryOp, typename XprType, typename StorageKind>
|
||||
class CwiseUnaryOpImpl
|
||||
: public internal::generic_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type
|
||||
{
|
||||
public:
|
||||
typedef typename internal::generic_xpr_base<CwiseUnaryOp<UnaryOp, XprType> >::type Base;
|
||||
};
|
||||
#endif
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
|
@ -66,6 +66,7 @@ class CwiseUnaryView : public CwiseUnaryViewImpl<ViewOp, MatrixType, typename in
|
||||
|
||||
typedef typename CwiseUnaryViewImpl<ViewOp, MatrixType,typename internal::traits<MatrixType>::StorageKind>::Base Base;
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryView)
|
||||
typedef typename internal::remove_all<MatrixType>::type NestedExpression;
|
||||
|
||||
inline CwiseUnaryView(const MatrixType& mat, const ViewOp& func = ViewOp())
|
||||
: m_matrix(mat), m_functor(func) {}
|
||||
@ -104,8 +105,8 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(CwiseUnaryViewImpl)
|
||||
|
||||
inline Scalar* data() { return &coeffRef(0); }
|
||||
inline const Scalar* data() const { return &coeff(0); }
|
||||
inline Scalar* data() { return &(this->coeffRef(0)); }
|
||||
inline const Scalar* data() const { return &(this->coeff(0)); }
|
||||
|
||||
inline Index innerStride() const
|
||||
{
|
||||
@ -116,6 +117,8 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
|
||||
{
|
||||
return derived().nestedExpression().outerStride() * sizeof(typename internal::traits<MatrixType>::Scalar) / sizeof(Scalar);
|
||||
}
|
||||
|
||||
#ifndef EIGEN_TEST_EVALUATORS
|
||||
|
||||
EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
|
||||
{
|
||||
@ -136,6 +139,8 @@ class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense>
|
||||
{
|
||||
return derived().functor()(const_cast_derived().nestedExpression().coeffRef(index));
|
||||
}
|
||||
|
||||
#endif
|
||||
};
|
||||
|
||||
} // end namespace Eigen
|
||||
|
@ -74,6 +74,7 @@ template<typename Derived> class DenseBase
|
||||
using Base::colIndexByOuterInner;
|
||||
using Base::coeff;
|
||||
using Base::coeffByOuterInner;
|
||||
#ifndef EIGEN_TEST_EVALUATORS
|
||||
using Base::packet;
|
||||
using Base::packetByOuterInner;
|
||||
using Base::writePacket;
|
||||
@ -84,6 +85,7 @@ template<typename Derived> class DenseBase
|
||||
using Base::copyCoeffByOuterInner;
|
||||
using Base::copyPacket;
|
||||
using Base::copyPacketByOuterInner;
|
||||
#endif
|
||||
using Base::operator();
|
||||
using Base::operator[];
|
||||
using Base::x;
|
||||
@ -280,7 +282,8 @@ template<typename Derived> class DenseBase
|
||||
Derived& operator=(const ReturnByValue<OtherDerived>& func);
|
||||
|
||||
#ifndef EIGEN_PARSED_BY_DOXYGEN
|
||||
/** Copies \a other into *this without evaluating other. \returns a reference to *this. */
|
||||
/** Copies \a other into *this without evaluating other. \returns a reference to *this.
|
||||
* \deprecated */
|
||||
template<typename OtherDerived>
|
||||
EIGEN_DEVICE_FUNC
|
||||
Derived& lazyAssign(const DenseBase<OtherDerived>& other);
|
||||
|
@ -97,8 +97,12 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
EIGEN_STRONG_INLINE CoeffReturnType coeff(Index row, Index col) const
|
||||
{
|
||||
eigen_internal_assert(row >= 0 && row < rows()
|
||||
&& col >= 0 && col < cols());
|
||||
&& col >= 0 && col < cols());
|
||||
#ifndef EIGEN_TEST_EVALUATORS
|
||||
return derived().coeff(row, col);
|
||||
#else
|
||||
return typename internal::evaluator<Derived>::type(derived()).coeff(row,col);
|
||||
#endif
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
@ -117,7 +121,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
{
|
||||
eigen_assert(row >= 0 && row < rows()
|
||||
&& col >= 0 && col < cols());
|
||||
return derived().coeff(row, col);
|
||||
return coeff(row, col);
|
||||
}
|
||||
|
||||
/** Short version: don't use this function, use
|
||||
@ -140,7 +144,11 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
coeff(Index index) const
|
||||
{
|
||||
eigen_internal_assert(index >= 0 && index < size());
|
||||
#ifndef EIGEN_TEST_EVALUATORS
|
||||
return derived().coeff(index);
|
||||
#else
|
||||
return typename internal::evaluator<Derived>::type(derived()).coeff(index);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -161,7 +169,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
|
||||
#endif
|
||||
eigen_assert(index >= 0 && index < size());
|
||||
return derived().coeff(index);
|
||||
return coeff(index);
|
||||
}
|
||||
|
||||
/** \returns the coefficient at given index.
|
||||
@ -179,7 +187,7 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
operator()(Index index) const
|
||||
{
|
||||
eigen_assert(index >= 0 && index < size());
|
||||
return derived().coeff(index);
|
||||
return coeff(index);
|
||||
}
|
||||
|
||||
/** equivalent to operator[](0). */
|
||||
@ -219,9 +227,12 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
template<int LoadMode>
|
||||
EIGEN_STRONG_INLINE PacketReturnType packet(Index row, Index col) const
|
||||
{
|
||||
eigen_internal_assert(row >= 0 && row < rows()
|
||||
&& col >= 0 && col < cols());
|
||||
eigen_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols());
|
||||
#ifndef EIGEN_TEST_EVALUATORS
|
||||
return derived().template packet<LoadMode>(row,col);
|
||||
#else
|
||||
return typename internal::evaluator<Derived>::type(derived()).template packet<LoadMode>(row,col);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@ -247,7 +258,11 @@ class DenseCoeffsBase<Derived,ReadOnlyAccessors> : public EigenBase<Derived>
|
||||
EIGEN_STRONG_INLINE PacketReturnType packet(Index index) const
|
||||
{
|
||||
eigen_internal_assert(index >= 0 && index < size());
|
||||
#ifndef EIGEN_TEST_EVALUATORS
|
||||
return derived().template packet<LoadMode>(index);
|
||||
#else
|
||||
return typename internal::evaluator<Derived>::type(derived()).template packet<LoadMode>(index);
|
||||
#endif
|
||||
}
|
||||
|
||||
protected:
|
||||
@ -327,8 +342,12 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
||||
EIGEN_STRONG_INLINE Scalar& coeffRef(Index row, Index col)
|
||||
{
|
||||
eigen_internal_assert(row >= 0 && row < rows()
|
||||
&& col >= 0 && col < cols());
|
||||
&& col >= 0 && col < cols());
|
||||
#ifndef EIGEN_TEST_EVALUATORS
|
||||
return derived().coeffRef(row, col);
|
||||
#else
|
||||
return typename internal::evaluator<Derived>::type(derived()).coeffRef(row,col);
|
||||
#endif
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
@ -350,7 +369,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
||||
{
|
||||
eigen_assert(row >= 0 && row < rows()
|
||||
&& col >= 0 && col < cols());
|
||||
return derived().coeffRef(row, col);
|
||||
return coeffRef(row, col);
|
||||
}
|
||||
|
||||
|
||||
@ -374,7 +393,11 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
||||
coeffRef(Index index)
|
||||
{
|
||||
eigen_internal_assert(index >= 0 && index < size());
|
||||
#ifndef EIGEN_TEST_EVALUATORS
|
||||
return derived().coeffRef(index);
|
||||
#else
|
||||
return typename internal::evaluator<Derived>::type(derived()).coeffRef(index);
|
||||
#endif
|
||||
}
|
||||
|
||||
/** \returns a reference to the coefficient at given index.
|
||||
@ -393,7 +416,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
||||
THE_BRACKET_OPERATOR_IS_ONLY_FOR_VECTORS__USE_THE_PARENTHESIS_OPERATOR_INSTEAD)
|
||||
#endif
|
||||
eigen_assert(index >= 0 && index < size());
|
||||
return derived().coeffRef(index);
|
||||
return coeffRef(index);
|
||||
}
|
||||
|
||||
/** \returns a reference to the coefficient at given index.
|
||||
@ -410,7 +433,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
||||
operator()(Index index)
|
||||
{
|
||||
eigen_assert(index >= 0 && index < size());
|
||||
return derived().coeffRef(index);
|
||||
return coeffRef(index);
|
||||
}
|
||||
|
||||
/** equivalent to operator[](0). */
|
||||
@ -437,6 +460,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
||||
EIGEN_STRONG_INLINE Scalar&
|
||||
w() { return (*this)[3]; }
|
||||
|
||||
#ifndef EIGEN_TEST_EVALUATORS
|
||||
/** \internal
|
||||
* Stores the given packet of coefficients, at the given row and column of this expression. It is your responsibility
|
||||
* to ensure that a packet really starts there. This method is only available on expressions having the
|
||||
@ -573,6 +597,7 @@ class DenseCoeffsBase<Derived, WriteAccessors> : public DenseCoeffsBase<Derived,
|
||||
derived().template copyPacket< OtherDerived, StoreMode, LoadMode>(row, col, other);
|
||||
}
|
||||
#endif
|
||||
#endif // EIGEN_TEST_EVALUATORS
|
||||
|
||||
};
|
||||
|
||||
|
@ -81,6 +81,7 @@ public:
|
||||
|
||||
typedef MatrixBase<Derived> Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
|
||||
typedef typename internal::remove_all<XprType>::type NestedExpression;
|
||||
|
||||
private:
|
||||
|
||||
@ -101,19 +102,19 @@ namespace internal {
|
||||
* \sa class Inverse
|
||||
*/
|
||||
template<typename XprType>
|
||||
struct evaluator<Inverse<XprType> >
|
||||
struct unary_evaluator<Inverse<XprType> >
|
||||
: public evaluator<typename Inverse<XprType>::PlainObject>::type
|
||||
{
|
||||
typedef Inverse<XprType> InverseType;
|
||||
typedef typename InverseType::PlainObject PlainObject;
|
||||
typedef typename evaluator<PlainObject>::type Base;
|
||||
|
||||
typedef evaluator type;
|
||||
typedef evaluator nestedType;
|
||||
typedef evaluator<XprType> type;
|
||||
typedef evaluator<XprType> nestedType;
|
||||
|
||||
enum { Flags = Base::Flags | EvalBeforeNestingBit };
|
||||
|
||||
evaluator(const InverseType& inv_xpr)
|
||||
unary_evaluator(const InverseType& inv_xpr)
|
||||
: m_result(inv_xpr.rows(), inv_xpr.cols())
|
||||
{
|
||||
::new (static_cast<Base*>(this)) Base(m_result);
|
||||
|
@ -74,6 +74,7 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate
|
||||
|
||||
typedef typename internal::dense_xpr_base<Replicate>::type Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Replicate)
|
||||
typedef typename internal::remove_all<MatrixType>::type NestedExpression;
|
||||
|
||||
template<typename OriginalMatrixType>
|
||||
inline explicit Replicate(const OriginalMatrixType& a_matrix)
|
||||
|
@ -92,6 +92,34 @@ Derived& DenseBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other)
|
||||
return derived();
|
||||
}
|
||||
|
||||
#ifdef EIGEN_TEST_EVALUATORS
|
||||
namespace internal {
|
||||
|
||||
template<typename Derived>
|
||||
struct evaluator<ReturnByValue<Derived> >
|
||||
: public evaluator<typename internal::traits<Derived>::ReturnType>::type
|
||||
{
|
||||
typedef ReturnByValue<Derived> XprType;
|
||||
typedef typename internal::traits<Derived>::ReturnType PlainObject;
|
||||
typedef typename evaluator<PlainObject>::type Base;
|
||||
|
||||
typedef evaluator type;
|
||||
typedef evaluator nestedType;
|
||||
|
||||
evaluator(const XprType& xpr)
|
||||
: m_result(xpr.rows(), xpr.cols())
|
||||
{
|
||||
::new (static_cast<Base*>(this)) Base(m_result);
|
||||
xpr.evalTo(m_result);
|
||||
}
|
||||
|
||||
protected:
|
||||
PlainObject m_result;
|
||||
};
|
||||
|
||||
} // end namespace internal
|
||||
#endif
|
||||
|
||||
} // end namespace Eigen
|
||||
|
||||
#endif // EIGEN_RETURNBYVALUE_H
|
||||
|
@ -77,6 +77,7 @@ template<typename MatrixType, int Direction> class Reverse
|
||||
|
||||
typedef typename internal::dense_xpr_base<Reverse>::type Base;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Reverse)
|
||||
typedef typename internal::remove_all<MatrixType>::type NestedExpression;
|
||||
using Base::IsRowMajor;
|
||||
|
||||
// next line is necessary because otherwise const version of operator()
|
||||
|
@ -68,6 +68,7 @@ template<typename MatrixType> class Transpose
|
||||
|
||||
typedef typename TransposeImpl<MatrixType,typename internal::traits<MatrixType>::StorageKind>::Base Base;
|
||||
EIGEN_GENERIC_PUBLIC_INTERFACE(Transpose)
|
||||
typedef typename internal::remove_all<MatrixType>::type NestedExpression;
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline Transpose(MatrixType& a_matrix) : m_matrix(a_matrix) {}
|
||||
@ -113,6 +114,7 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
|
||||
public:
|
||||
|
||||
typedef typename internal::TransposeImpl_base<MatrixType>::type Base;
|
||||
using Base::coeffRef;
|
||||
EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>)
|
||||
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(TransposeImpl)
|
||||
|
||||
@ -127,6 +129,8 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
|
||||
|
||||
inline ScalarWithConstIfNotLvalue* data() { return derived().nestedExpression().data(); }
|
||||
inline const Scalar* data() const { return derived().nestedExpression().data(); }
|
||||
|
||||
#ifndef EIGEN_TEST_EVALUATORS
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline ScalarWithConstIfNotLvalue& coeffRef(Index rowId, Index colId)
|
||||
@ -142,18 +146,6 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
|
||||
return derived().nestedExpression().const_cast_derived().coeffRef(index);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar& coeffRef(Index rowId, Index colId) const
|
||||
{
|
||||
return derived().nestedExpression().coeffRef(colId, rowId);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar& coeffRef(Index index) const
|
||||
{
|
||||
return derived().nestedExpression().coeffRef(index);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline CoeffReturnType coeff(Index rowId, Index colId) const
|
||||
{
|
||||
@ -189,6 +181,20 @@ template<typename MatrixType> class TransposeImpl<MatrixType,Dense>
|
||||
{
|
||||
derived().nestedExpression().const_cast_derived().template writePacket<LoadMode>(index, x);
|
||||
}
|
||||
#endif
|
||||
|
||||
// FIXME: shall we keep the const version of coeffRef?
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar& coeffRef(Index rowId, Index colId) const
|
||||
{
|
||||
return derived().nestedExpression().coeffRef(colId, rowId);
|
||||
}
|
||||
|
||||
EIGEN_DEVICE_FUNC
|
||||
inline const Scalar& coeffRef(Index index) const
|
||||
{
|
||||
return derived().nestedExpression().coeffRef(index);
|
||||
}
|
||||
};
|
||||
|
||||
/** \returns an expression of the transpose of *this.
|
||||
|
@ -1071,8 +1071,8 @@ struct evaluator_traits<TriangularView<MatrixType,Mode> >
|
||||
static const int AssumeAliasing = 0;
|
||||
};
|
||||
|
||||
template<typename MatrixType, unsigned int Mode, typename Kind>
|
||||
struct evaluator<TriangularView<MatrixType,Mode>, Kind, typename MatrixType::Scalar>
|
||||
template<typename MatrixType, unsigned int Mode>
|
||||
struct evaluator<TriangularView<MatrixType,Mode> >
|
||||
: evaluator<typename internal::remove_all<MatrixType>::type>
|
||||
{
|
||||
typedef TriangularView<MatrixType,Mode> XprType;
|
||||
|
@ -219,8 +219,8 @@ struct gemm_functor
|
||||
cols = m_rhs.cols();
|
||||
|
||||
Gemm::run(rows, cols, m_lhs.cols(),
|
||||
/*(const Scalar*)*/&m_lhs.coeffRef(row,0), m_lhs.outerStride(),
|
||||
/*(const Scalar*)*/&m_rhs.coeffRef(0,col), m_rhs.outerStride(),
|
||||
&m_lhs.coeffRef(row,0), m_lhs.outerStride(),
|
||||
&m_rhs.coeffRef(0,col), m_rhs.outerStride(),
|
||||
(Scalar*)&(m_dest.coeffRef(row,col)), m_dest.outerStride(),
|
||||
m_actualAlpha, m_blocking, info);
|
||||
}
|
||||
|
@ -38,9 +38,7 @@ template<typename Derived> struct accessors_level
|
||||
|
||||
template<typename T> struct evaluator_traits;
|
||||
|
||||
template< typename T,
|
||||
typename Kind = typename evaluator_traits<T>::Kind,
|
||||
typename Scalar = typename T::Scalar> struct evaluator;
|
||||
template< typename T> struct evaluator;
|
||||
|
||||
} // end namespace internal
|
||||
|
||||
|
@ -465,6 +465,15 @@ struct dense_xpr_base<Derived, ArrayXpr>
|
||||
typedef ArrayBase<Derived> type;
|
||||
};
|
||||
|
||||
template<typename Derived, typename XprKind = typename traits<Derived>::XprKind, typename StorageKind = typename traits<Derived>::StorageKind>
|
||||
struct generic_xpr_base;
|
||||
|
||||
template<typename Derived, typename XprKind>
|
||||
struct generic_xpr_base<Derived, XprKind, Dense>
|
||||
{
|
||||
typedef typename dense_xpr_base<Derived,XprKind>::type type;
|
||||
};
|
||||
|
||||
/** \internal Helper base class to add a scalar multiple operator
|
||||
* overloads for complex types */
|
||||
template<typename Derived,typename Scalar,typename OtherScalar,
|
||||
|
Loading…
Reference in New Issue
Block a user