13 #ifndef EIGEN_COREEVALUATORS_H
14 #define EIGEN_COREEVALUATORS_H
24 template<
typename StorageKind>
25 struct storage_kind_to_evaluator_kind {
26 typedef IndexBased Kind;
31 template<
typename StorageKind>
struct storage_kind_to_shape;
33 template<>
struct storage_kind_to_shape<Dense> {
typedef DenseShape Shape; };
34 template<>
struct storage_kind_to_shape<SolverStorage> {
typedef SolverShape Shape; };
35 template<>
struct storage_kind_to_shape<PermutationStorage> {
typedef PermutationShape Shape; };
36 template<>
struct storage_kind_to_shape<TranspositionsStorage> {
typedef TranspositionsShape Shape; };
52 typename Arg1Kind =
typename evaluator_traits<typename T::Arg1>::Kind,
53 typename Arg2Kind =
typename evaluator_traits<typename T::Arg2>::Kind,
54 typename Arg3Kind =
typename evaluator_traits<typename T::Arg3>::Kind,
55 typename Arg1Scalar =
typename traits<typename T::Arg1>::Scalar,
56 typename Arg2Scalar =
typename traits<typename T::Arg2>::Scalar,
57 typename Arg3Scalar =
typename traits<typename T::Arg3>::Scalar>
struct ternary_evaluator;
60 typename LhsKind =
typename evaluator_traits<typename T::Lhs>::Kind,
61 typename RhsKind =
typename evaluator_traits<typename T::Rhs>::Kind,
62 typename LhsScalar =
typename traits<typename T::Lhs>::Scalar,
63 typename RhsScalar =
typename traits<typename T::Rhs>::Scalar>
struct binary_evaluator;
66 typename Kind =
typename evaluator_traits<typename T::NestedExpression>::Kind,
67 typename Scalar =
typename T::Scalar>
struct unary_evaluator;
72 struct evaluator_traits_base
75 typedef typename storage_kind_to_evaluator_kind<typename traits<T>::StorageKind>::Kind Kind;
76 typedef typename storage_kind_to_shape<typename traits<T>::StorageKind>::Shape Shape;
81 struct evaluator_traits :
public evaluator_traits_base<T>
85 template<typename T, typename Shape = typename evaluator_traits<T>::Shape >
86 struct evaluator_assume_aliasing {
87 static const bool value =
false;
92 struct evaluator :
public unary_evaluator<T>
94 typedef unary_evaluator<T> Base;
96 explicit evaluator(
const T& xpr) : Base(xpr) {}
102 struct evaluator<const
T>
106 explicit evaluator(
const T& xpr) : evaluator<
T>(xpr) {}
111 template<
typename ExpressionType>
112 struct evaluator_base
115 typedef traits<ExpressionType> ExpressionTraits;
138 template<
typename Scalar,
int OuterStr
ide>
class plainobjectbase_evaluator_data {
141 plainobjectbase_evaluator_data(
const Scalar* ptr,
Index outerStride) :
data(ptr)
143 #ifndef EIGEN_INTERNAL_DEBUGGING
153 template<
typename Scalar>
class plainobjectbase_evaluator_data<Scalar,
Dynamic> {
156 plainobjectbase_evaluator_data(
const Scalar* ptr,
Index outerStride) :
data(ptr), m_outerStride(outerStride) {}
158 Index outerStride()
const {
return m_outerStride; }
164 template<
typename Derived>
165 struct evaluator<PlainObjectBase<Derived> >
166 : evaluator_base<Derived>
168 typedef PlainObjectBase<Derived> PlainObjectType;
169 typedef typename PlainObjectType::Scalar Scalar;
170 typedef typename PlainObjectType::CoeffReturnType CoeffReturnType;
173 IsRowMajor = PlainObjectType::IsRowMajor,
174 IsVectorAtCompileTime = PlainObjectType::IsVectorAtCompileTime,
175 RowsAtCompileTime = PlainObjectType::RowsAtCompileTime,
176 ColsAtCompileTime = PlainObjectType::ColsAtCompileTime,
179 Flags = traits<Derived>::EvaluatorFlags,
180 Alignment = traits<Derived>::Alignment
184 OuterStrideAtCompileTime = IsVectorAtCompileTime ? 0
185 : int(IsRowMajor) ? ColsAtCompileTime
191 : m_d(0,OuterStrideAtCompileTime)
197 explicit evaluator(
const PlainObjectType&
m)
198 : m_d(
m.
data(),IsVectorAtCompileTime ? 0 :
m.outerStride())
207 return m_d.data[
row * m_d.outerStride() +
col];
209 return m_d.data[
row +
col * m_d.outerStride()];
213 CoeffReturnType coeff(
Index index)
const
215 return m_d.data[index];
222 return const_cast<Scalar*
>(m_d.data)[
row * m_d.outerStride() +
col];
224 return const_cast<Scalar*
>(m_d.data)[
row +
col * m_d.outerStride()];
228 Scalar& coeffRef(
Index index)
230 return const_cast<Scalar*
>(m_d.data)[index];
233 template<
int LoadMode,
typename PacketType>
238 return ploadt<PacketType, LoadMode>(m_d.data +
row * m_d.outerStride() +
col);
240 return ploadt<PacketType, LoadMode>(m_d.data +
row +
col * m_d.outerStride());
243 template<
int LoadMode,
typename PacketType>
245 PacketType packet(
Index index)
const
247 return ploadt<PacketType, LoadMode>(m_d.data + index);
250 template<
int StoreMode,
typename PacketType>
255 return pstoret<Scalar, PacketType, StoreMode>
256 (
const_cast<Scalar*
>(m_d.data) +
row * m_d.outerStride() +
col,
x);
258 return pstoret<Scalar, PacketType, StoreMode>
259 (
const_cast<Scalar*
>(m_d.data) +
row +
col * m_d.outerStride(),
x);
262 template<
int StoreMode,
typename PacketType>
264 void writePacket(
Index index,
const PacketType&
x)
266 return pstoret<Scalar, PacketType, StoreMode>(
const_cast<Scalar*
>(m_d.data) + index,
x);
271 plainobjectbase_evaluator_data<Scalar,OuterStrideAtCompileTime> m_d;
274 template<
typename Scalar,
int Rows,
int Cols,
int Options,
int MaxRows,
int MaxCols>
275 struct evaluator<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
276 : evaluator<PlainObjectBase<Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > >
278 typedef Matrix<Scalar, Rows, Cols, Options, MaxRows, MaxCols> XprType;
284 explicit evaluator(
const XprType&
m)
285 : evaluator<PlainObjectBase<XprType> >(
m)
289 template<
typename Scalar,
int Rows,
int Cols,
int Options,
int MaxRows,
int MaxCols>
290 struct evaluator<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> >
291 : evaluator<PlainObjectBase<Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> > >
293 typedef Array<Scalar, Rows, Cols, Options, MaxRows, MaxCols> XprType;
299 explicit evaluator(
const XprType&
m)
300 : evaluator<PlainObjectBase<XprType> >(
m)
306 template<
typename ArgType>
307 struct unary_evaluator<Transpose<ArgType>, IndexBased>
308 : evaluator_base<Transpose<ArgType> >
310 typedef Transpose<ArgType> XprType;
313 CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
315 Alignment = evaluator<ArgType>::Alignment
319 explicit unary_evaluator(
const XprType& t) : m_argImpl(t.nestedExpression()) {}
321 typedef typename XprType::Scalar Scalar;
322 typedef typename XprType::CoeffReturnType CoeffReturnType;
327 return m_argImpl.coeff(
col,
row);
331 CoeffReturnType coeff(
Index index)
const
333 return m_argImpl.coeff(index);
339 return m_argImpl.coeffRef(
col,
row);
343 typename XprType::Scalar& coeffRef(
Index index)
345 return m_argImpl.coeffRef(index);
348 template<
int LoadMode,
typename PacketType>
352 return m_argImpl.template packet<LoadMode,PacketType>(
col,
row);
355 template<
int LoadMode,
typename PacketType>
357 PacketType packet(
Index index)
const
359 return m_argImpl.template packet<LoadMode,PacketType>(index);
362 template<
int StoreMode,
typename PacketType>
366 m_argImpl.template writePacket<StoreMode,PacketType>(
col,
row,
x);
369 template<
int StoreMode,
typename PacketType>
371 void writePacket(
Index index,
const PacketType&
x)
373 m_argImpl.template writePacket<StoreMode,PacketType>(index,
x);
377 evaluator<ArgType> m_argImpl;
384 template<
typename Scalar,
typename NullaryOp,
385 bool has_nullary = has_nullary_operator<NullaryOp>::value,
386 bool has_unary = has_unary_operator<NullaryOp>::value,
387 bool has_binary = has_binary_operator<NullaryOp>::value>
388 struct nullary_wrapper
390 template <
typename IndexType>
392 template <
typename IndexType>
395 template <
typename T,
typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
T packetOp(
const NullaryOp& op, IndexType
i, IndexType
j)
const {
return op.template packetOp<T>(
i,
j); }
396 template <
typename T,
typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
T packetOp(
const NullaryOp& op, IndexType
i)
const {
return op.template packetOp<T>(
i); }
399 template<
typename Scalar,
typename NullaryOp>
400 struct nullary_wrapper<Scalar,NullaryOp,true,false,false>
402 template <
typename IndexType>
404 template <
typename T,
typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
T packetOp(
const NullaryOp& op, IndexType=0, IndexType=0)
const {
return op.template packetOp<T>(); }
407 template<
typename Scalar,
typename NullaryOp>
408 struct nullary_wrapper<Scalar,NullaryOp,false,false,true>
410 template <
typename IndexType>
412 template <
typename T,
typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
T packetOp(
const NullaryOp& op, IndexType
i, IndexType
j=0)
const {
return op.template packetOp<T>(
i,
j); }
418 template<
typename Scalar,
typename NullaryOp>
419 struct nullary_wrapper<Scalar,NullaryOp,false,true,false>
421 template <
typename IndexType>
426 template <
typename T,
typename IndexType>
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
T packetOp(
const NullaryOp& op, IndexType
i, IndexType
j)
const {
428 return op.template packetOp<T>(
i+
j);
431 template <
typename IndexType>
433 template <
typename T,
typename IndexType>
434 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
T packetOp(
const NullaryOp& op, IndexType
i)
const {
return op.template packetOp<T>(
i); }
437 template<
typename Scalar,
typename NullaryOp>
438 struct nullary_wrapper<Scalar,NullaryOp,false,false,false> {};
440 #if 0 && EIGEN_COMP_MSVC>0
458 template<
typename T>
struct nullary_wrapper_workaround_msvc {
459 nullary_wrapper_workaround_msvc(
const T&);
463 template<
typename Scalar,
typename NullaryOp>
464 struct nullary_wrapper<Scalar,NullaryOp,true,true,true>
466 template <
typename IndexType>
468 return nullary_wrapper<Scalar,NullaryOp,
469 has_nullary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
470 has_unary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
471 has_binary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value>().
operator()(op,
i,
j);
473 template <
typename IndexType>
475 return nullary_wrapper<Scalar,NullaryOp,
476 has_nullary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
477 has_unary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
478 has_binary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value>().
operator()(op,
i);
481 template <
typename T,
typename IndexType>
482 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
T packetOp(
const NullaryOp& op, IndexType
i, IndexType
j)
const {
483 return nullary_wrapper<Scalar,NullaryOp,
484 has_nullary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
485 has_unary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
486 has_binary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value>().
template packetOp<T>(op,
i,
j);
488 template <
typename T,
typename IndexType>
490 return nullary_wrapper<Scalar,NullaryOp,
491 has_nullary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
492 has_unary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value,
493 has_binary_operator<NullaryOp,nullary_wrapper_workaround_msvc<IndexType> >::value>().
template packetOp<T>(op,
i);
498 template<
typename NullaryOp,
typename PlainObjectType>
499 struct evaluator<CwiseNullaryOp<NullaryOp,PlainObjectType> >
500 : evaluator_base<CwiseNullaryOp<NullaryOp,PlainObjectType> >
502 typedef CwiseNullaryOp<NullaryOp,PlainObjectType> XprType;
503 typedef internal::remove_all_t<PlainObjectType> PlainObjectTypeCleaned;
506 CoeffReadCost = internal::functor_traits<NullaryOp>::Cost,
508 Flags = (evaluator<PlainObjectTypeCleaned>::Flags
517 : m_functor(
n.functor()), m_wrapper()
522 typedef typename XprType::CoeffReturnType CoeffReturnType;
524 template <
typename IndexType>
526 CoeffReturnType coeff(IndexType
row, IndexType
col)
const
528 return m_wrapper(m_functor,
row,
col);
531 template <
typename IndexType>
533 CoeffReturnType coeff(IndexType index)
const
535 return m_wrapper(m_functor,index);
538 template<
int LoadMode,
typename PacketType,
typename IndexType>
540 PacketType packet(IndexType
row, IndexType
col)
const
542 return m_wrapper.template packetOp<PacketType>(m_functor,
row,
col);
545 template<
int LoadMode,
typename PacketType,
typename IndexType>
547 PacketType packet(IndexType index)
const
549 return m_wrapper.template packetOp<PacketType>(m_functor, index);
553 const NullaryOp m_functor;
554 const internal::nullary_wrapper<CoeffReturnType,NullaryOp> m_wrapper;
559 template<
typename UnaryOp,
typename ArgType>
560 struct unary_evaluator<CwiseUnaryOp<UnaryOp, ArgType>, IndexBased >
561 : evaluator_base<CwiseUnaryOp<UnaryOp, ArgType> >
563 typedef CwiseUnaryOp<UnaryOp, ArgType> XprType;
566 CoeffReadCost = int(evaluator<ArgType>::CoeffReadCost) + int(functor_traits<UnaryOp>::Cost),
568 Flags = evaluator<ArgType>::Flags
570 Alignment = evaluator<ArgType>::Alignment
574 explicit unary_evaluator(
const XprType& op) : m_d(op)
580 typedef typename XprType::CoeffReturnType CoeffReturnType;
585 return m_d.func()(m_d.argImpl.coeff(
row,
col));
589 CoeffReturnType coeff(
Index index)
const
591 return m_d.func()(m_d.argImpl.coeff(index));
594 template<
int LoadMode,
typename PacketType>
598 return m_d.func().packetOp(m_d.argImpl.template packet<LoadMode, PacketType>(
row,
col));
601 template<
int LoadMode,
typename PacketType>
603 PacketType packet(
Index index)
const
605 return m_d.func().packetOp(m_d.argImpl.template packet<LoadMode, PacketType>(index));
614 Data(
const XprType& xpr) : op(xpr.functor()), argImpl(xpr.nestedExpression()) {}
616 const UnaryOp& func()
const {
return op; }
618 evaluator<ArgType> argImpl;
626 template <
typename SrcType,
typename DstType,
typename ArgType>
627 struct unary_evaluator<CwiseUnaryOp<core_cast_op<SrcType, DstType>, ArgType>, IndexBased> {
628 using CastOp = core_cast_op<SrcType, DstType>;
629 using XprType = CwiseUnaryOp<CastOp, ArgType>;
632 using SrcPacketType =
typename packet_traits<SrcType>::type;
634 static constexpr
int SrcPacketBytes = SrcPacketSize *
sizeof(SrcType);
637 CoeffReadCost = int(evaluator<ArgType>::CoeffReadCost) + int(functor_traits<CastOp>::Cost),
638 PacketAccess = functor_traits<CastOp>::PacketAccess,
641 IsRowMajor = (evaluator<ArgType>::Flags &
RowMajorBit),
642 Alignment = evaluator<ArgType>::Alignment
645 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
explicit unary_evaluator(
const XprType& xpr)
646 : m_argImpl(xpr.nestedExpression()), m_rows(xpr.
rows()), m_cols(xpr.
cols()) {
651 template <
typename DstPacketType>
653 template <
typename DstPacketType>
655 template <
typename DstPacketType>
657 template <
typename DstPacketType>
659 template <
typename DstPacketType>
662 template <
bool UseRowMajor = IsRowMajor, std::enable_if_t<UseRowMajor,
bool> = true>
664 return col + packetSize <=
cols();
666 template <
bool UseRowMajor = IsRowMajor, std::enable_if_t<!UseRowMajor,
bool> = true>
668 return row + packetSize <=
rows();
671 return index + packetSize <=
size();
677 return m_argImpl.coeff(actualRow, actualCol);
680 Index actualIndex = index + offset;
681 return m_argImpl.coeff(actualIndex);
685 return cast<SrcType, DstType>(srcCoeff(
row,
col, 0));
687 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE DstType coeff(
Index index)
const {
return cast<SrcType, DstType>(srcCoeff(index, 0)); }
689 template <
int LoadMode,
typename PacketType = SrcPacketType>
692 Index actualRow = IsRowMajor ?
row :
row + (offset * PacketSize);
693 Index actualCol = IsRowMajor ?
col + (offset * PacketSize) :
col;
694 eigen_assert(check_array_bounds(actualRow, actualCol, PacketSize) &&
"Array index out of bounds");
695 return m_argImpl.template packet<LoadMode, PacketType>(actualRow, actualCol);
697 template <
int LoadMode,
typename PacketType = SrcPacketType>
698 EIGEN_STRONG_INLINE PacketType srcPacket(
Index index,
Index offset)
const {
700 Index actualIndex = index + (offset * PacketSize);
701 eigen_assert(check_array_bounds(actualIndex, PacketSize) &&
"Array index out of bounds");
702 return m_argImpl.template packet<LoadMode, PacketType>(actualIndex);
714 template <
int LoadMode,
typename DstPacketType, AltSrcScalarOp<DstPacketType> = true>
717 constexpr
int SrcBytesIncrement = DstPacketSize *
sizeof(SrcType);
718 constexpr
int SrcLoadMode =
plain_enum_min(SrcBytesIncrement, LoadMode);
721 src = srcPacket<SrcLoadMode>(
row,
col, 0);
723 Array<SrcType, SrcPacketSize, 1> srcArray;
724 for (
size_t k = 0; k < DstPacketSize; k++) srcArray[k] = srcCoeff(
row,
col, k);
725 for (
size_t k = DstPacketSize; k < SrcPacketSize; k++) srcArray[k] = SrcType(0);
726 src = pload<SrcPacketType>(srcArray.data());
728 return pcast<SrcPacketType, DstPacketType>(src);
731 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs1<DstPacketType> = true>
734 using SizedSrcPacketType =
typename find_packet_by_size<SrcType, DstPacketSize>::type;
735 constexpr
int SrcBytesIncrement = DstPacketSize *
sizeof(SrcType);
736 constexpr
int SrcLoadMode =
plain_enum_min(SrcBytesIncrement, LoadMode);
737 return pcast<SizedSrcPacketType, DstPacketType>(
738 srcPacket<SrcLoadMode, SizedSrcPacketType>(
row,
col, 0));
741 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs2<DstPacketType> = true>
743 constexpr
int SrcLoadMode =
plain_enum_min(SrcPacketBytes, LoadMode);
744 return pcast<SrcPacketType, DstPacketType>(
745 srcPacket<SrcLoadMode>(
row,
col, 0), srcPacket<SrcLoadMode>(
row,
col, 1));
748 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs4<DstPacketType> = true>
750 constexpr
int SrcLoadMode =
plain_enum_min(SrcPacketBytes, LoadMode);
751 return pcast<SrcPacketType, DstPacketType>(
752 srcPacket<SrcLoadMode>(
row,
col, 0), srcPacket<SrcLoadMode>(
row,
col, 1),
753 srcPacket<SrcLoadMode>(
row,
col, 2), srcPacket<SrcLoadMode>(
row,
col, 3));
756 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs8<DstPacketType> = true>
758 constexpr
int SrcLoadMode =
plain_enum_min(SrcPacketBytes, LoadMode);
759 return pcast<SrcPacketType, DstPacketType>(
760 srcPacket<SrcLoadMode>(
row,
col, 0), srcPacket<SrcLoadMode>(
row,
col, 1),
761 srcPacket<SrcLoadMode>(
row,
col, 2), srcPacket<SrcLoadMode>(
row,
col, 3),
762 srcPacket<SrcLoadMode>(
row,
col, 4), srcPacket<SrcLoadMode>(
row,
col, 5),
763 srcPacket<SrcLoadMode>(
row,
col, 6), srcPacket<SrcLoadMode>(
row,
col, 7));
767 template <
int LoadMode,
typename DstPacketType, AltSrcScalarOp<DstPacketType> = true>
768 EIGEN_STRONG_INLINE DstPacketType packet(
Index index)
const {
770 constexpr
int SrcBytesIncrement = DstPacketSize *
sizeof(SrcType);
771 constexpr
int SrcLoadMode =
plain_enum_min(SrcBytesIncrement, LoadMode);
774 src = srcPacket<SrcLoadMode>(index, 0);
776 Array<SrcType, SrcPacketSize, 1> srcArray;
777 for (
size_t k = 0; k < DstPacketSize; k++) srcArray[k] = srcCoeff(index, k);
778 for (
size_t k = DstPacketSize; k < SrcPacketSize; k++) srcArray[k] = SrcType(0);
779 src = pload<SrcPacketType>(srcArray.data());
781 return pcast<SrcPacketType, DstPacketType>(src);
783 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs1<DstPacketType> = true>
784 EIGEN_STRONG_INLINE DstPacketType packet(
Index index)
const {
786 using SizedSrcPacketType =
typename find_packet_by_size<SrcType, DstPacketSize>::type;
787 constexpr
int SrcBytesIncrement = DstPacketSize *
sizeof(SrcType);
788 constexpr
int SrcLoadMode =
plain_enum_min(SrcBytesIncrement, LoadMode);
789 return pcast<SizedSrcPacketType, DstPacketType>(
790 srcPacket<SrcLoadMode, SizedSrcPacketType>(index, 0));
792 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs2<DstPacketType> = true>
793 EIGEN_STRONG_INLINE DstPacketType packet(
Index index)
const {
794 constexpr
int SrcLoadMode =
plain_enum_min(SrcPacketBytes, LoadMode);
795 return pcast<SrcPacketType, DstPacketType>(
796 srcPacket<SrcLoadMode>(index, 0), srcPacket<SrcLoadMode>(index, 1));
798 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs4<DstPacketType> = true>
799 EIGEN_STRONG_INLINE DstPacketType packet(
Index index)
const {
800 constexpr
int SrcLoadMode =
plain_enum_min(SrcPacketBytes, LoadMode);
801 return pcast<SrcPacketType, DstPacketType>(
802 srcPacket<SrcLoadMode>(index, 0), srcPacket<SrcLoadMode>(index, 1),
803 srcPacket<SrcLoadMode>(index, 2), srcPacket<SrcLoadMode>(index, 3));
805 template <
int LoadMode,
typename DstPacketType, SrcPacketArgs8<DstPacketType> = true>
806 EIGEN_STRONG_INLINE DstPacketType packet(
Index index)
const {
807 constexpr
int SrcLoadMode =
plain_enum_min(SrcPacketBytes, LoadMode);
808 return pcast<SrcPacketType, DstPacketType>(
809 srcPacket<SrcLoadMode>(index, 0), srcPacket<SrcLoadMode>(index, 1),
810 srcPacket<SrcLoadMode>(index, 2), srcPacket<SrcLoadMode>(index, 3),
811 srcPacket<SrcLoadMode>(index, 4), srcPacket<SrcLoadMode>(index, 5),
812 srcPacket<SrcLoadMode>(index, 6), srcPacket<SrcLoadMode>(index, 7));
820 const evaluator<ArgType> m_argImpl;
821 const variable_if_dynamic<Index, XprType::RowsAtCompileTime> m_rows;
822 const variable_if_dynamic<Index, XprType::ColsAtCompileTime> m_cols;
828 template<
typename TernaryOp,
typename Arg1,
typename Arg2,
typename Arg3>
829 struct evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> >
830 :
public ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> >
832 typedef CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> XprType;
833 typedef ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> > Base;
838 template<
typename TernaryOp,
typename Arg1,
typename Arg2,
typename Arg3>
839 struct ternary_evaluator<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3>, IndexBased, IndexBased>
840 : evaluator_base<CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> >
842 typedef CwiseTernaryOp<TernaryOp, Arg1, Arg2, Arg3> XprType;
845 CoeffReadCost = int(evaluator<Arg1>::CoeffReadCost) + int(evaluator<Arg2>::CoeffReadCost) + int(evaluator<Arg3>::CoeffReadCost) + int(functor_traits<TernaryOp>::Cost),
847 Arg1Flags = evaluator<Arg1>::Flags,
848 Arg2Flags = evaluator<Arg2>::Flags,
849 Arg3Flags = evaluator<Arg3>::Flags,
850 SameType = is_same<typename Arg1::Scalar,typename Arg2::Scalar>::value && is_same<typename Arg1::Scalar,typename Arg3::Scalar>::value,
852 Flags0 = (
int(Arg1Flags) | int(Arg2Flags) | int(Arg3Flags)) & (
854 | (
int(Arg1Flags) &
int(Arg2Flags) &
int(Arg3Flags) &
856 | (functor_traits<TernaryOp>::PacketAccess && StorageOrdersAgree && SameType ?
PacketAccessBit : 0)
862 plain_enum_min(evaluator<Arg1>::Alignment, evaluator<Arg2>::Alignment),
863 evaluator<Arg3>::Alignment)
872 typedef typename XprType::CoeffReturnType CoeffReturnType;
877 return m_d.func()(m_d.arg1Impl.coeff(
row,
col), m_d.arg2Impl.coeff(
row,
col), m_d.arg3Impl.coeff(
row,
col));
881 CoeffReturnType coeff(
Index index)
const
883 return m_d.func()(m_d.arg1Impl.coeff(index), m_d.arg2Impl.coeff(index), m_d.arg3Impl.coeff(index));
886 template<
int LoadMode,
typename PacketType>
890 return m_d.func().packetOp(m_d.arg1Impl.template packet<LoadMode,PacketType>(
row,
col),
891 m_d.arg2Impl.template packet<LoadMode,PacketType>(
row,
col),
892 m_d.arg3Impl.template packet<LoadMode,PacketType>(
row,
col));
895 template<
int LoadMode,
typename PacketType>
897 PacketType packet(
Index index)
const
899 return m_d.func().packetOp(m_d.arg1Impl.template packet<LoadMode,PacketType>(index),
900 m_d.arg2Impl.template packet<LoadMode,PacketType>(index),
901 m_d.arg3Impl.template packet<LoadMode,PacketType>(index));
909 Data(
const XprType& xpr) : op(xpr.functor()), arg1Impl(xpr.arg1()), arg2Impl(xpr.arg2()), arg3Impl(xpr.arg3()) {}
911 const TernaryOp& func()
const {
return op; }
913 evaluator<Arg1> arg1Impl;
914 evaluator<Arg2> arg2Impl;
915 evaluator<Arg3> arg3Impl;
924 template<
typename BinaryOp,
typename Lhs,
typename Rhs>
925 struct evaluator<CwiseBinaryOp<
BinaryOp, Lhs, Rhs> >
926 :
public binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
928 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
929 typedef binary_evaluator<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > Base;
932 explicit evaluator(
const XprType& xpr) : Base(xpr) {}
935 template<
typename BinaryOp,
typename Lhs,
typename Rhs>
936 struct binary_evaluator<CwiseBinaryOp<
BinaryOp, Lhs, Rhs>, IndexBased, IndexBased>
937 : evaluator_base<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
939 typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> XprType;
942 CoeffReadCost = int(evaluator<Lhs>::CoeffReadCost) + int(evaluator<Rhs>::CoeffReadCost) + int(functor_traits<BinaryOp>::Cost),
944 LhsFlags = evaluator<Lhs>::Flags,
945 RhsFlags = evaluator<Rhs>::Flags,
946 SameType = is_same<typename Lhs::Scalar,typename Rhs::Scalar>::value,
948 Flags0 = (
int(LhsFlags) | int(RhsFlags)) & (
950 | (
int(LhsFlags) &
int(RhsFlags) &
952 | (functor_traits<BinaryOp>::PacketAccess && StorageOrdersAgree && SameType ?
PacketAccessBit : 0)
957 Alignment =
plain_enum_min(evaluator<Lhs>::Alignment, evaluator<Rhs>::Alignment)
961 explicit binary_evaluator(
const XprType& xpr) : m_d(xpr)
967 typedef typename XprType::CoeffReturnType CoeffReturnType;
972 return m_d.func()(m_d.lhsImpl.coeff(
row,
col), m_d.rhsImpl.coeff(
row,
col));
976 CoeffReturnType coeff(
Index index)
const
978 return m_d.func()(m_d.lhsImpl.coeff(index), m_d.rhsImpl.coeff(index));
981 template<
int LoadMode,
typename PacketType>
985 return m_d.func().packetOp(m_d.lhsImpl.template packet<LoadMode,PacketType>(
row,
col),
986 m_d.rhsImpl.template packet<LoadMode,PacketType>(
row,
col));
989 template<
int LoadMode,
typename PacketType>
991 PacketType packet(
Index index)
const
993 return m_d.func().packetOp(m_d.lhsImpl.template packet<LoadMode,PacketType>(index),
994 m_d.rhsImpl.template packet<LoadMode,PacketType>(index));
1003 Data(
const XprType& xpr) : op(xpr.functor()), lhsImpl(xpr.lhs()), rhsImpl(xpr.rhs()) {}
1005 const BinaryOp& func()
const {
return op; }
1007 evaluator<Lhs> lhsImpl;
1008 evaluator<Rhs> rhsImpl;
1016 template<
typename UnaryOp,
typename ArgType,
typename Str
ideType>
1017 struct unary_evaluator<CwiseUnaryView<UnaryOp, ArgType, StrideType>, IndexBased>
1018 : evaluator_base<CwiseUnaryView<UnaryOp, ArgType, StrideType> >
1020 typedef CwiseUnaryView<UnaryOp, ArgType, StrideType> XprType;
1023 CoeffReadCost = int(evaluator<ArgType>::CoeffReadCost) + int(functor_traits<UnaryOp>::Cost),
1036 typedef typename XprType::Scalar Scalar;
1037 typedef typename XprType::CoeffReturnType CoeffReturnType;
1042 return m_d.func()(m_d.argImpl.coeff(
row,
col));
1046 CoeffReturnType coeff(
Index index)
const
1048 return m_d.func()(m_d.argImpl.coeff(index));
1054 return m_d.func()(m_d.argImpl.coeffRef(
row,
col));
1058 Scalar& coeffRef(
Index index)
1060 return m_d.func()(m_d.argImpl.coeffRef(index));
1069 Data(
const XprType& xpr) : op(xpr.functor()), argImpl(xpr.nestedExpression()) {}
1071 const UnaryOp& func()
const {
return op; }
1073 evaluator<ArgType> argImpl;
1083 template<
typename Derived,
typename PlainObjectType>
1084 struct mapbase_evaluator;
1086 template<
typename Derived,
typename PlainObjectType>
1087 struct mapbase_evaluator : evaluator_base<Derived>
1089 typedef Derived XprType;
1090 typedef typename XprType::PointerType PointerType;
1091 typedef typename XprType::Scalar Scalar;
1092 typedef typename XprType::CoeffReturnType CoeffReturnType;
1095 IsRowMajor = XprType::RowsAtCompileTime,
1096 ColsAtCompileTime = XprType::ColsAtCompileTime,
1101 explicit mapbase_evaluator(
const XprType& map)
1102 : m_data(const_cast<PointerType>(map.
data())),
1103 m_innerStride(map.innerStride()),
1104 m_outerStride(map.outerStride())
1107 internal::inner_stride_at_compile_time<Derived>::ret == 1),
1108 PACKET_ACCESS_REQUIRES_TO_HAVE_INNER_STRIDE_FIXED_TO_1);
1115 return m_data[
col * colStride() +
row * rowStride()];
1119 CoeffReturnType coeff(
Index index)
const
1121 return m_data[index * m_innerStride.value()];
1127 return m_data[
col * colStride() +
row * rowStride()];
1131 Scalar& coeffRef(
Index index)
1133 return m_data[index * m_innerStride.value()];
1136 template<
int LoadMode,
typename PacketType>
1140 PointerType ptr = m_data +
row * rowStride() +
col * colStride();
1141 return internal::ploadt<PacketType, LoadMode>(ptr);
1144 template<
int LoadMode,
typename PacketType>
1146 PacketType packet(
Index index)
const
1148 return internal::ploadt<PacketType, LoadMode>(m_data + index * m_innerStride.value());
1151 template<
int StoreMode,
typename PacketType>
1155 PointerType ptr = m_data +
row * rowStride() +
col * colStride();
1156 return internal::pstoret<Scalar, PacketType, StoreMode>(ptr,
x);
1159 template<
int StoreMode,
typename PacketType>
1161 void writePacket(
Index index,
const PacketType&
x)
1163 internal::pstoret<Scalar, PacketType, StoreMode>(m_data + index * m_innerStride.value(),
x);
1168 return XprType::IsRowMajor ? m_outerStride.value() : m_innerStride.value();
1172 return XprType::IsRowMajor ? m_innerStride.value() : m_outerStride.value();
1176 const internal::variable_if_dynamic<Index, XprType::InnerStrideAtCompileTime> m_innerStride;
1177 const internal::variable_if_dynamic<Index, XprType::OuterStrideAtCompileTime> m_outerStride;
1180 template<
typename PlainObjectType,
int MapOptions,
typename Str
ideType>
1181 struct evaluator<Map<PlainObjectType, MapOptions, StrideType> >
1182 :
public mapbase_evaluator<Map<PlainObjectType, MapOptions, StrideType>, PlainObjectType>
1184 typedef Map<PlainObjectType, MapOptions, StrideType> XprType;
1185 typedef typename XprType::Scalar Scalar;
1187 typedef typename packet_traits<Scalar>::type PacketScalar;
1190 InnerStrideAtCompileTime = StrideType::InnerStrideAtCompileTime == 0
1191 ? int(PlainObjectType::InnerStrideAtCompileTime)
1192 : int(StrideType::InnerStrideAtCompileTime),
1193 OuterStrideAtCompileTime = StrideType::OuterStrideAtCompileTime == 0
1194 ? int(PlainObjectType::OuterStrideAtCompileTime)
1195 : int(StrideType::OuterStrideAtCompileTime),
1196 HasNoInnerStride = InnerStrideAtCompileTime == 1,
1197 HasNoOuterStride = StrideType::OuterStrideAtCompileTime == 0,
1198 HasNoStride = HasNoInnerStride && HasNoOuterStride,
1199 IsDynamicSize = PlainObjectType::SizeAtCompileTime==
Dynamic,
1202 LinearAccessMask =
bool(HasNoStride) ||
bool(PlainObjectType::IsVectorAtCompileTime) ? ~int(0) : ~int(
LinearAccessBit),
1203 Flags = int( evaluator<PlainObjectType>::Flags) & (LinearAccessMask&PacketAccessMask),
1209 : mapbase_evaluator<XprType, PlainObjectType>(map)
1215 template<
typename PlainObjectType,
int RefOptions,
typename Str
ideType>
1216 struct evaluator<Ref<PlainObjectType, RefOptions, StrideType> >
1217 :
public mapbase_evaluator<Ref<PlainObjectType, RefOptions, StrideType>, PlainObjectType>
1219 typedef Ref<PlainObjectType, RefOptions, StrideType> XprType;
1222 Flags = evaluator<Map<PlainObjectType, RefOptions, StrideType> >::Flags,
1223 Alignment = evaluator<Map<PlainObjectType, RefOptions, StrideType> >::Alignment
1227 explicit evaluator(
const XprType& ref)
1228 : mapbase_evaluator<XprType, PlainObjectType>(ref)
1234 template<
typename ArgType,
int BlockRows,
int BlockCols,
bool InnerPanel,
1235 bool HasDirectAccess = internal::has_direct_access<ArgType>::ret>
struct block_evaluator;
1237 template<
typename ArgType,
int BlockRows,
int BlockCols,
bool InnerPanel>
1238 struct evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel> >
1239 : block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel>
1241 typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
1242 typedef typename XprType::Scalar Scalar;
1244 typedef typename packet_traits<Scalar>::type PacketScalar;
1247 CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
1249 RowsAtCompileTime = traits<XprType>::RowsAtCompileTime,
1250 ColsAtCompileTime = traits<XprType>::ColsAtCompileTime,
1251 MaxRowsAtCompileTime = traits<XprType>::MaxRowsAtCompileTime,
1252 MaxColsAtCompileTime = traits<XprType>::MaxColsAtCompileTime,
1254 ArgTypeIsRowMajor = (int(evaluator<ArgType>::Flags)&
RowMajorBit) != 0,
1255 IsRowMajor = (MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1) ? 1
1256 : (MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1) ? 0
1257 : ArgTypeIsRowMajor,
1258 HasSameStorageOrderAsArgType = (IsRowMajor == ArgTypeIsRowMajor),
1259 InnerSize = IsRowMajor ? int(ColsAtCompileTime) : int(RowsAtCompileTime),
1260 InnerStrideAtCompileTime = HasSameStorageOrderAsArgType
1261 ? int(inner_stride_at_compile_time<ArgType>::ret)
1262 : int(outer_stride_at_compile_time<ArgType>::ret),
1263 OuterStrideAtCompileTime = HasSameStorageOrderAsArgType
1264 ? int(outer_stride_at_compile_time<ArgType>::ret)
1265 : int(inner_stride_at_compile_time<ArgType>::ret),
1266 MaskPacketAccessBit = (InnerStrideAtCompileTime == 1 || HasSameStorageOrderAsArgType) ?
PacketAccessBit : 0,
1268 FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1 || (InnerPanel && (evaluator<ArgType>::Flags&
LinearAccessBit))) ?
LinearAccessBit : 0,
1272 MaskPacketAccessBit),
1273 Flags = Flags0 | FlagsLinearAccessBit | FlagsRowMajorBit,
1275 PacketAlignment = unpacket_traits<PacketScalar>::alignment,
1276 Alignment0 = (InnerPanel && (OuterStrideAtCompileTime!=
Dynamic)
1277 && (OuterStrideAtCompileTime!=0)
1278 && (((OuterStrideAtCompileTime * int(sizeof(Scalar))) % int(PacketAlignment)) == 0)) ? int(PacketAlignment) : 0,
1279 Alignment =
plain_enum_min(evaluator<ArgType>::Alignment, Alignment0)
1281 typedef block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel> block_evaluator_type;
1283 explicit evaluator(
const XprType&
block) : block_evaluator_type(
block)
1290 template<
typename ArgType,
int BlockRows,
int BlockCols,
bool InnerPanel>
1291 struct block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel, false>
1292 : unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel> >
1294 typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
1297 explicit block_evaluator(
const XprType&
block)
1298 : unary_evaluator<XprType>(
block)
1302 template<
typename ArgType,
int BlockRows,
int BlockCols,
bool InnerPanel>
1303 struct unary_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>, IndexBased>
1304 : evaluator_base<Block<ArgType, BlockRows, BlockCols, InnerPanel> >
1306 typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
1309 explicit unary_evaluator(
const XprType&
block)
1310 : m_argImpl(
block.nestedExpression()),
1311 m_startRow(
block.startRow()),
1312 m_startCol(
block.startCol()),
1313 m_linear_offset(ForwardLinearAccess?(ArgType::IsRowMajor ?
block.startRow()*
block.nestedExpression().
cols() +
block.startCol() :
block.startCol()*
block.nestedExpression().
rows() +
block.startRow()):0)
1316 typedef typename XprType::Scalar Scalar;
1317 typedef typename XprType::CoeffReturnType CoeffReturnType;
1320 RowsAtCompileTime = XprType::RowsAtCompileTime,
1321 ForwardLinearAccess = (InnerPanel || int(XprType::IsRowMajor)==int(ArgType::IsRowMajor)) &&
bool(evaluator<ArgType>::Flags&
LinearAccessBit)
1327 return m_argImpl.coeff(m_startRow.value() +
row, m_startCol.value() +
col);
1331 CoeffReturnType coeff(
Index index)
const
1333 return linear_coeff_impl(index, bool_constant<ForwardLinearAccess>());
1339 return m_argImpl.coeffRef(m_startRow.value() +
row, m_startCol.value() +
col);
1343 Scalar& coeffRef(
Index index)
1345 return linear_coeffRef_impl(index, bool_constant<ForwardLinearAccess>());
1348 template<
int LoadMode,
typename PacketType>
1352 return m_argImpl.template packet<LoadMode,PacketType>(m_startRow.value() +
row, m_startCol.value() +
col);
1355 template<
int LoadMode,
typename PacketType>
1357 PacketType packet(
Index index)
const
1359 if (ForwardLinearAccess)
1360 return m_argImpl.template packet<LoadMode,PacketType>(m_linear_offset.value() + index);
1362 return packet<LoadMode,PacketType>(RowsAtCompileTime == 1 ? 0 : index,
1363 RowsAtCompileTime == 1 ? index : 0);
1366 template<
int StoreMode,
typename PacketType>
1370 return m_argImpl.template writePacket<StoreMode,PacketType>(m_startRow.value() +
row, m_startCol.value() +
col,
x);
1373 template<
int StoreMode,
typename PacketType>
1375 void writePacket(
Index index,
const PacketType&
x)
1377 if (ForwardLinearAccess)
1378 return m_argImpl.template writePacket<StoreMode,PacketType>(m_linear_offset.value() + index,
x);
1380 return writePacket<StoreMode,PacketType>(RowsAtCompileTime == 1 ? 0 : index,
1381 RowsAtCompileTime == 1 ? index : 0,
1387 CoeffReturnType linear_coeff_impl(
Index index, internal::true_type )
const
1389 return m_argImpl.coeff(m_linear_offset.value() + index);
1392 CoeffReturnType linear_coeff_impl(
Index index, internal::false_type )
const
1394 return coeff(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
1398 Scalar& linear_coeffRef_impl(
Index index, internal::true_type )
1400 return m_argImpl.coeffRef(m_linear_offset.value() + index);
1403 Scalar& linear_coeffRef_impl(
Index index, internal::false_type )
1405 return coeffRef(RowsAtCompileTime == 1 ? 0 : index, RowsAtCompileTime == 1 ? index : 0);
1408 evaluator<ArgType> m_argImpl;
1409 const variable_if_dynamic<
Index, (ArgType::RowsAtCompileTime == 1 && BlockRows==1) ? 0 :
Dynamic> m_startRow;
1410 const variable_if_dynamic<
Index, (ArgType::ColsAtCompileTime == 1 && BlockCols==1) ? 0 :
Dynamic> m_startCol;
1411 const variable_if_dynamic<Index, ForwardLinearAccess ? Dynamic : 0> m_linear_offset;
1417 template<
typename ArgType,
int BlockRows,
int BlockCols,
bool InnerPanel>
1418 struct block_evaluator<ArgType, BlockRows, BlockCols, InnerPanel, true>
1419 : mapbase_evaluator<Block<ArgType, BlockRows, BlockCols, InnerPanel>,
1420 typename Block<ArgType, BlockRows, BlockCols, InnerPanel>::PlainObject>
1422 typedef Block<ArgType, BlockRows, BlockCols, InnerPanel> XprType;
1423 typedef typename XprType::Scalar Scalar;
1426 explicit block_evaluator(
const XprType&
block)
1427 : mapbase_evaluator<XprType, typename XprType::PlainObject>(
block)
1430 &&
"data is not aligned");
1439 template<
typename ConditionMatrixType,
typename ThenMatrixType,
typename ElseMatrixType>
1440 struct evaluator<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
1441 : evaluator_base<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >
1443 typedef Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> XprType;
1445 CoeffReadCost = evaluator<ConditionMatrixType>::CoeffReadCost
1447 evaluator<ElseMatrixType>::CoeffReadCost),
1449 Flags = (
unsigned int)evaluator<ThenMatrixType>::Flags & evaluator<ElseMatrixType>::Flags &
HereditaryBits,
1451 Alignment =
plain_enum_min(evaluator<ThenMatrixType>::Alignment, evaluator<ElseMatrixType>::Alignment)
1455 explicit evaluator(
const XprType& select)
1456 : m_conditionImpl(select.conditionMatrix()),
1457 m_thenImpl(select.thenMatrix()),
1458 m_elseImpl(select.elseMatrix())
1463 typedef typename XprType::CoeffReturnType CoeffReturnType;
1468 if (m_conditionImpl.coeff(
row,
col))
1469 return m_thenImpl.coeff(
row,
col);
1471 return m_elseImpl.coeff(
row,
col);
1475 CoeffReturnType coeff(
Index index)
const
1477 if (m_conditionImpl.coeff(index))
1478 return m_thenImpl.coeff(index);
1480 return m_elseImpl.coeff(index);
1484 evaluator<ConditionMatrixType> m_conditionImpl;
1485 evaluator<ThenMatrixType> m_thenImpl;
1486 evaluator<ElseMatrixType> m_elseImpl;
1492 template<
typename ArgType,
int RowFactor,
int ColFactor>
1493 struct unary_evaluator<Replicate<ArgType, RowFactor, ColFactor> >
1494 : evaluator_base<Replicate<ArgType, RowFactor, ColFactor> >
1496 typedef Replicate<ArgType, RowFactor, ColFactor> XprType;
1497 typedef typename XprType::CoeffReturnType CoeffReturnType;
1501 typedef typename internal::nested_eval<ArgType,Factor>::type ArgTypeNested;
1502 typedef internal::remove_all_t<ArgTypeNested> ArgTypeNestedCleaned;
1505 CoeffReadCost = evaluator<ArgTypeNestedCleaned>::CoeffReadCost,
1506 LinearAccessMask = XprType::IsVectorAtCompileTime ?
LinearAccessBit : 0,
1509 Alignment = evaluator<ArgTypeNestedCleaned>::Alignment
1513 explicit unary_evaluator(
const XprType& replicate)
1514 : m_arg(replicate.nestedExpression()),
1516 m_rows(replicate.nestedExpression().
rows()),
1517 m_cols(replicate.nestedExpression().
cols())
1524 const Index actual_row = internal::traits<XprType>::RowsAtCompileTime==1 ? 0
1525 : RowFactor==1 ?
row
1526 :
row % m_rows.value();
1527 const Index actual_col = internal::traits<XprType>::ColsAtCompileTime==1 ? 0
1528 : ColFactor==1 ?
col
1529 :
col % m_cols.value();
1531 return m_argImpl.coeff(actual_row, actual_col);
1535 CoeffReturnType coeff(
Index index)
const
1538 const Index actual_index = internal::traits<XprType>::RowsAtCompileTime==1
1539 ? (ColFactor==1 ? index : index%m_cols.value())
1540 : (RowFactor==1 ? index : index%m_rows.value());
1542 return m_argImpl.coeff(actual_index);
1545 template<
int LoadMode,
typename PacketType>
1549 const Index actual_row = internal::traits<XprType>::RowsAtCompileTime==1 ? 0
1550 : RowFactor==1 ?
row
1551 :
row % m_rows.value();
1552 const Index actual_col = internal::traits<XprType>::ColsAtCompileTime==1 ? 0
1553 : ColFactor==1 ?
col
1554 :
col % m_cols.value();
1556 return m_argImpl.template packet<LoadMode,PacketType>(actual_row, actual_col);
1559 template<
int LoadMode,
typename PacketType>
1561 PacketType packet(
Index index)
const
1563 const Index actual_index = internal::traits<XprType>::RowsAtCompileTime==1
1564 ? (ColFactor==1 ? index : index%m_cols.value())
1565 : (RowFactor==1 ? index : index%m_rows.value());
1567 return m_argImpl.template packet<LoadMode,PacketType>(actual_index);
1571 const ArgTypeNested m_arg;
1572 evaluator<ArgTypeNestedCleaned> m_argImpl;
1573 const variable_if_dynamic<Index, ArgType::RowsAtCompileTime> m_rows;
1574 const variable_if_dynamic<Index, ArgType::ColsAtCompileTime> m_cols;
1582 template<
typename XprType>
1583 struct evaluator_wrapper_base
1584 : evaluator_base<XprType>
1586 typedef remove_all_t<typename XprType::NestedExpressionType> ArgType;
1588 CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
1589 Flags = evaluator<ArgType>::Flags,
1590 Alignment = evaluator<ArgType>::Alignment
1594 explicit evaluator_wrapper_base(
const ArgType&
arg) : m_argImpl(
arg) {}
1596 typedef typename ArgType::Scalar Scalar;
1597 typedef typename ArgType::CoeffReturnType CoeffReturnType;
1602 return m_argImpl.coeff(
row,
col);
1606 CoeffReturnType coeff(
Index index)
const
1608 return m_argImpl.coeff(index);
1614 return m_argImpl.coeffRef(
row,
col);
1618 Scalar& coeffRef(
Index index)
1620 return m_argImpl.coeffRef(index);
1623 template<
int LoadMode,
typename PacketType>
1627 return m_argImpl.template packet<LoadMode,PacketType>(
row,
col);
1630 template<
int LoadMode,
typename PacketType>
1632 PacketType packet(
Index index)
const
1634 return m_argImpl.template packet<LoadMode,PacketType>(index);
1637 template<
int StoreMode,
typename PacketType>
1641 m_argImpl.template writePacket<StoreMode>(
row,
col,
x);
1644 template<
int StoreMode,
typename PacketType>
1646 void writePacket(
Index index,
const PacketType&
x)
1648 m_argImpl.template writePacket<StoreMode>(index,
x);
1652 evaluator<ArgType> m_argImpl;
1655 template<
typename TArgType>
1656 struct unary_evaluator<MatrixWrapper<TArgType> >
1657 : evaluator_wrapper_base<MatrixWrapper<TArgType> >
1659 typedef MatrixWrapper<TArgType> XprType;
1662 explicit unary_evaluator(
const XprType& wrapper)
1663 : evaluator_wrapper_base<MatrixWrapper<TArgType> >(wrapper.nestedExpression())
1667 template<
typename TArgType>
1668 struct unary_evaluator<ArrayWrapper<TArgType> >
1669 : evaluator_wrapper_base<ArrayWrapper<TArgType> >
1671 typedef ArrayWrapper<TArgType> XprType;
1674 explicit unary_evaluator(
const XprType& wrapper)
1675 : evaluator_wrapper_base<ArrayWrapper<TArgType> >(wrapper.nestedExpression())
1683 template<
typename PacketType,
bool ReversePacket>
struct reverse_packet_cond;
1685 template<
typename ArgType,
int Direction>
1686 struct unary_evaluator<Reverse<ArgType, Direction> >
1687 : evaluator_base<Reverse<ArgType, Direction> >
1689 typedef Reverse<ArgType, Direction> XprType;
1690 typedef typename XprType::Scalar Scalar;
1691 typedef typename XprType::CoeffReturnType CoeffReturnType;
1694 IsRowMajor = XprType::IsRowMajor,
1695 IsColMajor = !IsRowMajor,
1699 || ((Direction ==
Vertical) && IsColMajor)
1700 || ((Direction ==
Horizontal) && IsRowMajor),
1702 CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
1706 Flags0 = evaluator<ArgType>::Flags,
1708 || ((ReverseRow && XprType::ColsAtCompileTime==1) || (ReverseCol && XprType::RowsAtCompileTime==1))
1717 explicit unary_evaluator(
const XprType& reverse)
1718 : m_argImpl(reverse.nestedExpression()),
1719 m_rows(ReverseRow ? reverse.nestedExpression().
rows() : 1),
1720 m_cols(ReverseCol ? reverse.nestedExpression().
cols() : 1)
1726 return m_argImpl.coeff(ReverseRow ? m_rows.value() -
row - 1 :
row,
1727 ReverseCol ? m_cols.value() -
col - 1 :
col);
1731 CoeffReturnType coeff(
Index index)
const
1733 return m_argImpl.coeff(m_rows.value() * m_cols.value() - index - 1);
1739 return m_argImpl.coeffRef(ReverseRow ? m_rows.value() -
row - 1 :
row,
1740 ReverseCol ? m_cols.value() -
col - 1 :
col);
1744 Scalar& coeffRef(
Index index)
1746 return m_argImpl.coeffRef(m_rows.value() * m_cols.value() - index - 1);
1749 template<
int LoadMode,
typename PacketType>
1755 OffsetRow = ReverseRow && IsColMajor ? PacketSize : 1,
1756 OffsetCol = ReverseCol && IsRowMajor ? PacketSize : 1
1758 typedef internal::reverse_packet_cond<PacketType,ReversePacket> reverse_packet;
1759 return reverse_packet::run(m_argImpl.template packet<LoadMode,PacketType>(
1760 ReverseRow ? m_rows.value() -
row - OffsetRow :
row,
1761 ReverseCol ? m_cols.value() -
col - OffsetCol :
col));
1764 template<
int LoadMode,
typename PacketType>
1766 PacketType packet(
Index index)
const
1769 return preverse(m_argImpl.template packet<LoadMode,PacketType>(m_rows.value() * m_cols.value() - index - PacketSize));
1772 template<
int LoadMode,
typename PacketType>
1779 OffsetRow = ReverseRow && IsColMajor ? PacketSize : 1,
1780 OffsetCol = ReverseCol && IsRowMajor ? PacketSize : 1
1782 typedef internal::reverse_packet_cond<PacketType,ReversePacket> reverse_packet;
1783 m_argImpl.template writePacket<LoadMode>(
1784 ReverseRow ? m_rows.value() -
row - OffsetRow :
row,
1785 ReverseCol ? m_cols.value() -
col - OffsetCol :
col,
1786 reverse_packet::run(
x));
1789 template<
int LoadMode,
typename PacketType>
1791 void writePacket(
Index index,
const PacketType&
x)
1794 m_argImpl.template writePacket<LoadMode>
1795 (m_rows.value() * m_cols.value() - index - PacketSize,
preverse(
x));
1799 evaluator<ArgType> m_argImpl;
1803 const variable_if_dynamic<Index, ReverseRow ? ArgType::RowsAtCompileTime : 1> m_rows;
1804 const variable_if_dynamic<Index, ReverseCol ? ArgType::ColsAtCompileTime : 1> m_cols;
1810 template<
typename ArgType,
int DiagIndex>
1811 struct evaluator<Diagonal<ArgType, DiagIndex> >
1812 : evaluator_base<Diagonal<ArgType, DiagIndex> >
1814 typedef Diagonal<ArgType, DiagIndex> XprType;
1817 CoeffReadCost = evaluator<ArgType>::CoeffReadCost,
1825 explicit evaluator(
const XprType& diagonal)
1826 : m_argImpl(diagonal.nestedExpression()),
1827 m_index(diagonal.index())
1830 typedef typename XprType::Scalar Scalar;
1831 typedef typename XprType::CoeffReturnType CoeffReturnType;
1836 return m_argImpl.coeff(
row + rowOffset(),
row + colOffset());
1840 CoeffReturnType coeff(
Index index)
const
1842 return m_argImpl.coeff(index + rowOffset(), index + colOffset());
1848 return m_argImpl.coeffRef(
row + rowOffset(),
row + colOffset());
1852 Scalar& coeffRef(
Index index)
1854 return m_argImpl.coeffRef(index + rowOffset(), index + colOffset());
1858 evaluator<ArgType> m_argImpl;
1859 const internal::variable_if_dynamicindex<Index, XprType::DiagIndex> m_index;
1863 Index rowOffset()
const {
return m_index.value() > 0 ? 0 : -m_index.value(); }
1865 Index colOffset()
const {
return m_index.value() > 0 ? m_index.value() : 0; }
1877 template<
typename ArgType>
class EvalToTemp;
1879 template<
typename ArgType>
1880 struct traits<EvalToTemp<ArgType> >
1881 :
public traits<ArgType>
1884 template<
typename ArgType>
1886 :
public dense_xpr_base<EvalToTemp<ArgType> >::type
1890 typedef typename dense_xpr_base<EvalToTemp>::type Base;
1893 explicit EvalToTemp(
const ArgType&
arg)
1897 const ArgType&
arg()
const
1904 return m_arg.rows();
1909 return m_arg.cols();
1913 const ArgType& m_arg;
1916 template<
typename ArgType>
1917 struct evaluator<EvalToTemp<ArgType> >
1918 :
public evaluator<typename ArgType::PlainObject>
1920 typedef EvalToTemp<ArgType> XprType;
1921 typedef typename ArgType::PlainObject PlainObject;
1922 typedef evaluator<PlainObject> Base;
1925 : m_result(xpr.
arg())
1927 internal::construct_at<Base>(
this, m_result);
1934 internal::construct_at<Base>(
this, m_result);
1938 PlainObject m_result;
EIGEN_DOC_BLOCK_ADDONS_NOT_INNER_PANEL FixedBlockXpr<...,... >::Type block(Index startRow, Index startCol, NRowsType blockRows, NColsType blockCols)
RowXpr row(Index i)
This is the const version of row(). */.
ColXpr col(Index i)
This is the const version of col().
IndexedView_or_Block operator()(const RowIndices &rowIndices, const ColIndices &colIndices)
#define EIGEN_PREDICT_TRUE(x)
#define EIGEN_GENERIC_PUBLIC_INTERFACE(Derived)
#define eigen_internal_assert(x)
#define EIGEN_UNUSED_VARIABLE(var)
#define EIGEN_DEVICE_FUNC
#define EIGEN_STATIC_ASSERT(X, MSG)
#define EIGEN_INTERNAL_CHECK_COST_VALUE(C)
Eigen::Triplet< double > T
const unsigned int ActualPacketAccessBit
const unsigned int PacketAccessBit
const unsigned int LinearAccessBit
const unsigned int EvalBeforeNestingBit
const unsigned int DirectAccessBit
const unsigned int RowMajorBit
constexpr int plain_enum_min(A a, B b)
constexpr int plain_enum_max(A a, B b)
constexpr bool check_implication(bool a, bool b)
Packet2cf preverse(const Packet2cf &a)
constexpr bool is_constant_evaluated()
const unsigned int HereditaryBits
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
const Eigen::CwiseUnaryOp< Eigen::internal::scalar_arg_op< typename Derived::Scalar >, const Derived > arg(const Eigen::ArrayBase< Derived > &x)