13 #ifndef EIGEN_PRODUCTEVALUATORS_H
14 #define EIGEN_PRODUCTEVALUATORS_H
30 template<
typename Lhs,
typename Rhs,
int Options>
31 struct evaluator<Product<Lhs, Rhs, Options> >
32 :
public product_evaluator<Product<Lhs, Rhs, Options> >
34 typedef Product<Lhs, Rhs, Options> XprType;
35 typedef product_evaluator<XprType> Base;
37 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
explicit evaluator(
const XprType& xpr) : Base(xpr) {}
42 template<
typename Lhs,
typename Rhs,
typename Scalar1,
typename Scalar2,
typename Plain1>
43 struct evaluator_assume_aliasing<CwiseBinaryOp<
internal::scalar_product_op<Scalar1,Scalar2>,
44 const CwiseNullaryOp<internal::scalar_constant_op<Scalar1>, Plain1>,
45 const Product<Lhs, Rhs, DefaultProduct> > >
47 static const bool value =
true;
49 template<
typename Lhs,
typename Rhs,
typename Scalar1,
typename Scalar2,
typename Plain1>
50 struct evaluator<CwiseBinaryOp<
internal::scalar_product_op<Scalar1,Scalar2>,
51 const CwiseNullaryOp<internal::scalar_constant_op<Scalar1>, Plain1>,
52 const Product<Lhs, Rhs, DefaultProduct> > >
53 :
public evaluator<Product<EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(Scalar1,Lhs,product), Rhs, DefaultProduct> >
55 typedef CwiseBinaryOp<internal::scalar_product_op<Scalar1,Scalar2>,
56 const CwiseNullaryOp<internal::scalar_constant_op<Scalar1>, Plain1>,
57 const Product<Lhs, Rhs, DefaultProduct> > XprType;
61 : Base(xpr.lhs().functor().m_other * xpr.rhs().lhs() * xpr.rhs().rhs())
66 template<
typename Lhs,
typename Rhs,
int DiagIndex>
67 struct evaluator<Diagonal<const Product<Lhs, Rhs,
DefaultProduct>, DiagIndex> >
68 :
public evaluator<Diagonal<const Product<Lhs, Rhs, LazyProduct>, DiagIndex> >
70 typedef Diagonal<const Product<Lhs, Rhs, DefaultProduct>, DiagIndex> XprType;
71 typedef evaluator<Diagonal<const Product<Lhs, Rhs, LazyProduct>, DiagIndex> > Base;
74 : Base(Diagonal<const Product<Lhs, Rhs,
LazyProduct>, DiagIndex>(
75 Product<Lhs, Rhs,
LazyProduct>(xpr.nestedExpression().lhs(), xpr.nestedExpression().rhs()),
84 template<
typename Lhs,
typename Rhs,
85 typename LhsShape =
typename evaluator_traits<Lhs>::Shape,
86 typename RhsShape =
typename evaluator_traits<Rhs>::Shape,
87 int ProductType = internal::product_type<Lhs,Rhs>::value>
88 struct generic_product_impl;
90 template<
typename Lhs,
typename Rhs>
91 struct evaluator_assume_aliasing<Product<Lhs, Rhs,
DefaultProduct> > {
92 static const bool value =
true;
97 template<
typename Lhs,
typename Rhs,
int Options,
int ProductTag,
typename LhsShape,
typename RhsShape>
98 struct product_evaluator<Product<Lhs, Rhs, Options>, ProductTag, LhsShape, RhsShape>
99 :
public evaluator<typename Product<Lhs, Rhs, Options>::PlainObject>
101 typedef Product<Lhs, Rhs, Options> XprType;
102 typedef typename XprType::PlainObject PlainObject;
103 typedef evaluator<PlainObject> Base;
109 explicit product_evaluator(
const XprType& xpr)
112 internal::construct_at<Base>(
this, m_result);
126 generic_product_impl<Lhs, Rhs, LhsShape, RhsShape, ProductTag>::evalTo(m_result, xpr.lhs(), xpr.rhs());
130 PlainObject m_result;
137 template<
typename DstXprType,
typename Lhs,
typename Rhs,
int Options,
typename Scalar>
138 struct Assignment<DstXprType, Product<Lhs,Rhs,Options>,
internal::assign_op<Scalar,Scalar>, Dense2Dense,
139 std::enable_if_t<(Options==DefaultProduct || Options==AliasFreeProduct)>>
141 typedef Product<Lhs,Rhs,Options> SrcXprType;
143 void run(DstXprType &dst,
const SrcXprType &src,
const internal::assign_op<Scalar,Scalar> &)
145 Index dstRows = src.rows();
146 Index dstCols = src.cols();
147 if((dst.rows()!=dstRows) || (dst.cols()!=dstCols))
148 dst.resize(dstRows, dstCols);
150 generic_product_impl<Lhs, Rhs>::evalTo(dst, src.lhs(), src.rhs());
155 template<
typename DstXprType,
typename Lhs,
typename Rhs,
int Options,
typename Scalar>
156 struct Assignment<DstXprType, Product<Lhs,Rhs,Options>,
internal::add_assign_op<Scalar,Scalar>, Dense2Dense,
157 std::enable_if_t<(Options==DefaultProduct || Options==AliasFreeProduct)>>
159 typedef Product<Lhs,Rhs,Options> SrcXprType;
161 void run(DstXprType &dst,
const SrcXprType &src,
const internal::add_assign_op<Scalar,Scalar> &)
163 eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
165 generic_product_impl<Lhs, Rhs>::addTo(dst, src.lhs(), src.rhs());
170 template<
typename DstXprType,
typename Lhs,
typename Rhs,
int Options,
typename Scalar>
171 struct Assignment<DstXprType, Product<Lhs,Rhs,Options>,
internal::sub_assign_op<Scalar,Scalar>, Dense2Dense,
172 std::enable_if_t<(Options==DefaultProduct || Options==AliasFreeProduct)>>
174 typedef Product<Lhs,Rhs,Options> SrcXprType;
176 void run(DstXprType &dst,
const SrcXprType &src,
const internal::sub_assign_op<Scalar,Scalar> &)
178 eigen_assert(dst.rows() == src.rows() && dst.cols() == src.cols());
180 generic_product_impl<Lhs, Rhs>::subTo(dst, src.lhs(), src.rhs());
188 template<
typename DstXprType,
typename Lhs,
typename Rhs,
typename AssignFunc,
typename Scalar,
typename ScalarBis,
typename Plain>
189 struct Assignment<DstXprType, CwiseBinaryOp<
internal::scalar_product_op<ScalarBis,Scalar>, const CwiseNullaryOp<internal::scalar_constant_op<ScalarBis>,Plain>,
190 const Product<Lhs,Rhs,DefaultProduct> >, AssignFunc, Dense2Dense>
192 typedef CwiseBinaryOp<internal::scalar_product_op<ScalarBis,Scalar>,
193 const CwiseNullaryOp<internal::scalar_constant_op<ScalarBis>,Plain>,
194 const Product<Lhs,Rhs,DefaultProduct> > SrcXprType;
196 void run(DstXprType &dst,
const SrcXprType &src,
const AssignFunc& func)
206 template<
typename OtherXpr,
typename Lhs,
typename Rhs>
207 struct evaluator_assume_aliasing<CwiseBinaryOp<
internal::scalar_sum_op<typename OtherXpr::Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, const OtherXpr,
208 const Product<Lhs,Rhs,DefaultProduct> >, DenseShape > {
209 static const bool value =
true;
212 template<
typename OtherXpr,
typename Lhs,
typename Rhs>
213 struct evaluator_assume_aliasing<CwiseBinaryOp<
internal::scalar_difference_op<typename OtherXpr::Scalar,typename Product<Lhs,Rhs,DefaultProduct>::Scalar>, const OtherXpr,
214 const Product<Lhs,Rhs,DefaultProduct> >, DenseShape > {
215 static const bool value =
true;
218 template<
typename DstXprType,
typename OtherXpr,
typename ProductType,
typename Func1,
typename Func2>
219 struct assignment_from_xpr_op_product
221 template<
typename SrcXprType,
typename InitialFunc>
223 void run(DstXprType &dst,
const SrcXprType &src,
const InitialFunc& )
230 #define EIGEN_CATCH_ASSIGN_XPR_OP_PRODUCT(ASSIGN_OP,BINOP,ASSIGN_OP2) \
231 template< typename DstXprType, typename OtherXpr, typename Lhs, typename Rhs, typename DstScalar, typename SrcScalar, typename OtherScalar,typename ProdScalar> \
232 struct Assignment<DstXprType, CwiseBinaryOp<internal::BINOP<OtherScalar,ProdScalar>, const OtherXpr, \
233 const Product<Lhs,Rhs,DefaultProduct> >, internal::ASSIGN_OP<DstScalar,SrcScalar>, Dense2Dense> \
234 : assignment_from_xpr_op_product<DstXprType, OtherXpr, Product<Lhs,Rhs,DefaultProduct>, internal::ASSIGN_OP<DstScalar,OtherScalar>, internal::ASSIGN_OP2<DstScalar,ProdScalar> > \
247 template<
typename Lhs,
typename Rhs>
250 template<
typename Dst>
251 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void evalTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
253 dst.coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum();
256 template<
typename Dst>
257 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void addTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
259 dst.coeffRef(0,0) += (lhs.transpose().cwiseProduct(rhs)).sum();
262 template<
typename Dst>
263 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void subTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
264 { dst.coeffRef(0,0) -= (lhs.transpose().cwiseProduct(rhs)).sum(); }
273 template<
typename Dst,
typename Lhs,
typename Rhs,
typename Func>
276 evaluator<Rhs> rhsEval(rhs);
282 func(dst.col(
j), rhsEval.coeff(
Index(0),
j) * actual_lhs);
286 template<
typename Dst,
typename Lhs,
typename Rhs,
typename Func>
289 evaluator<Lhs> lhsEval(lhs);
295 func(dst.row(
i), lhsEval.coeff(
i,
Index(0)) * actual_rhs);
298 template<
typename Lhs,
typename Rhs>
301 template<
typename T>
struct is_row_major : std::conditional_t<(int(T::Flags)&RowMajorBit), internal::true_type, internal::false_type> {};
302 typedef typename Product<Lhs,Rhs>::Scalar Scalar;
305 struct set {
template<
typename Dst,
typename Src>
EIGEN_DEVICE_FUNC void operator()(
const Dst& dst,
const Src& src)
const { dst.const_cast_derived() = src; } };
306 struct add {
template<
typename Dst,
typename Src>
EIGEN_DEVICE_FUNC void operator()(
const Dst& dst,
const Src& src)
const { dst.const_cast_derived() += src; } };
307 struct sub {
template<
typename Dst,
typename Src>
EIGEN_DEVICE_FUNC void operator()(
const Dst& dst,
const Src& src)
const { dst.const_cast_derived() -= src; } };
310 explicit adds(
const Scalar& s) : m_scale(s) {}
312 dst.const_cast_derived() += m_scale * src;
316 template<
typename Dst>
317 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void evalTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
322 template<
typename Dst>
323 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void addTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
328 template<
typename Dst>
329 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void subTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
334 template<
typename Dst>
335 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void scaleAndAddTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs,
const Scalar& alpha)
344 template<
typename Lhs,
typename Rhs,
typename Derived>
345 struct generic_product_impl_base
347 typedef typename Product<Lhs,Rhs>::Scalar Scalar;
349 template<
typename Dst>
350 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void evalTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
351 { dst.setZero(); scaleAndAddTo(dst, lhs, rhs, Scalar(1)); }
353 template<
typename Dst>
354 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void addTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
355 { scaleAndAddTo(dst,lhs, rhs, Scalar(1)); }
357 template<
typename Dst>
358 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void subTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
359 { scaleAndAddTo(dst, lhs, rhs, Scalar(-1)); }
361 template<
typename Dst>
362 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void scaleAndAddTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs,
const Scalar& alpha)
363 { Derived::scaleAndAddTo(dst,lhs,rhs,alpha); }
367 template<
typename Lhs,
typename Rhs>
368 struct generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,
GemvProduct>
369 : generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,GemvProduct> >
371 typedef typename nested_eval<Lhs,1>::type LhsNested;
372 typedef typename nested_eval<Rhs,1>::type RhsNested;
373 typedef typename Product<Lhs,Rhs>::Scalar Scalar;
377 template<
typename Dest>
378 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void scaleAndAddTo(Dest& dst,
const Lhs& lhs,
const Rhs& rhs,
const Scalar& alpha)
381 if (lhs.rows() == 1 && rhs.cols() == 1) {
382 dst.coeffRef(0,0) += alpha * lhs.row(0).conjugate().dot(rhs.col(0));
385 LhsNested actual_lhs(lhs);
386 RhsNested actual_rhs(rhs);
387 internal::gemv_dense_selector<Side,
389 bool(internal::blas_traits<MatrixType>::HasUsableDirectAccess)
390 >::run(actual_lhs, actual_rhs, dst, alpha);
394 template<
typename Lhs,
typename Rhs>
397 typedef typename Product<Lhs,Rhs>::Scalar Scalar;
399 template<
typename Dst>
400 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void evalTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
407 template<
typename Dst>
408 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void addTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
414 template<
typename Dst>
415 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void subTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
435 template<
typename Dst,
typename Func>
437 void eval_dynamic(Dst& dst,
const Lhs& lhs,
const Rhs& rhs,
const Func &func)
440 HasScalarFactor = blas_traits<Lhs>::HasScalarFactor || blas_traits<Rhs>::HasScalarFactor,
441 ConjLhs = blas_traits<Lhs>::NeedToConjugate,
442 ConjRhs = blas_traits<Rhs>::NeedToConjugate
446 Scalar actualAlpha = combine_scalar_factors<Scalar>(lhs, rhs);
448 eval_dynamic_impl(dst,
449 blas_traits<Lhs>::extract(lhs).
template conjugateIf<ConjLhs>(),
450 blas_traits<Rhs>::extract(rhs).
template conjugateIf<ConjRhs>(),
453 std::conditional_t<HasScalarFactor,true_type,false_type>());
458 template<
typename Dst,
typename LhsT,
typename RhsT,
typename Func,
typename Scalar>
460 void eval_dynamic_impl(Dst& dst,
const LhsT& lhs,
const RhsT& rhs,
const Func &func,
const Scalar& s , false_type)
467 template<
typename Dst,
typename LhsT,
typename RhsT,
typename Func,
typename Scalar>
469 void eval_dynamic_impl(Dst& dst,
const LhsT& lhs,
const RhsT& rhs,
const Func &func,
const Scalar& s, true_type)
476 template<
typename Lhs,
typename Rhs>
478 : generic_product_impl<Lhs,Rhs,DenseShape,DenseShape,CoeffBasedProductMode> {};
486 template<
int Traversal,
int UnrollingIndex,
typename Lhs,
typename Rhs,
typename RetScalar>
487 struct etor_product_coeff_impl;
489 template<
int StorageOrder,
int UnrollingIndex,
typename Lhs,
typename Rhs,
typename Packet,
int LoadMode>
490 struct etor_product_packet_impl;
492 template<
typename Lhs,
typename Rhs,
int ProductTag>
493 struct product_evaluator<Product<Lhs, Rhs,
LazyProduct>, ProductTag, DenseShape, DenseShape>
494 : evaluator_base<Product<Lhs, Rhs, LazyProduct> >
496 typedef Product<Lhs, Rhs, LazyProduct> XprType;
497 typedef typename XprType::Scalar Scalar;
498 typedef typename XprType::CoeffReturnType CoeffReturnType;
501 explicit product_evaluator(
const XprType& xpr)
507 m_innerDim(xpr.lhs().
cols())
513 std::cerr <<
"LhsOuterStrideBytes= " << LhsOuterStrideBytes <<
"\n";
514 std::cerr <<
"RhsOuterStrideBytes= " << RhsOuterStrideBytes <<
"\n";
515 std::cerr <<
"LhsAlignment= " << LhsAlignment <<
"\n";
516 std::cerr <<
"RhsAlignment= " << RhsAlignment <<
"\n";
517 std::cerr <<
"CanVectorizeLhs= " << CanVectorizeLhs <<
"\n";
518 std::cerr <<
"CanVectorizeRhs= " << CanVectorizeRhs <<
"\n";
519 std::cerr <<
"CanVectorizeInner= " << CanVectorizeInner <<
"\n";
520 std::cerr <<
"EvalToRowMajor= " << EvalToRowMajor <<
"\n";
521 std::cerr <<
"Alignment= " << Alignment <<
"\n";
522 std::cerr <<
"Flags= " << Flags <<
"\n";
528 typedef typename internal::nested_eval<Lhs,Rhs::ColsAtCompileTime>::type LhsNested;
529 typedef typename internal::nested_eval<Rhs,Lhs::RowsAtCompileTime>::type RhsNested;
531 typedef internal::remove_all_t<LhsNested> LhsNestedCleaned;
532 typedef internal::remove_all_t<RhsNested> RhsNestedCleaned;
534 typedef evaluator<LhsNestedCleaned> LhsEtorType;
535 typedef evaluator<RhsNestedCleaned> RhsEtorType;
538 RowsAtCompileTime = LhsNestedCleaned::RowsAtCompileTime,
539 ColsAtCompileTime = RhsNestedCleaned::ColsAtCompileTime,
540 InnerSize =
min_size_prefer_fixed(LhsNestedCleaned::ColsAtCompileTime, RhsNestedCleaned::RowsAtCompileTime),
541 MaxRowsAtCompileTime = LhsNestedCleaned::MaxRowsAtCompileTime,
542 MaxColsAtCompileTime = RhsNestedCleaned::MaxColsAtCompileTime
545 typedef typename find_best_packet<Scalar,RowsAtCompileTime>::type LhsVecPacketType;
546 typedef typename find_best_packet<Scalar,ColsAtCompileTime>::type RhsVecPacketType;
550 LhsCoeffReadCost = LhsEtorType::CoeffReadCost,
551 RhsCoeffReadCost = RhsEtorType::CoeffReadCost,
559 LhsFlags = LhsEtorType::Flags,
560 RhsFlags = RhsEtorType::Flags,
569 LhsAlignment =
plain_enum_min(LhsEtorType::Alignment, LhsVecPacketSize*
int(
sizeof(
typename LhsNestedCleaned::Scalar))),
570 RhsAlignment =
plain_enum_min(RhsEtorType::Alignment, RhsVecPacketSize*
int(
sizeof(
typename RhsNestedCleaned::Scalar))),
572 SameType = is_same<typename LhsNestedCleaned::Scalar,typename RhsNestedCleaned::Scalar>::value,
574 CanVectorizeRhs =
bool(RhsRowMajor) && (RhsFlags &
PacketAccessBit) && (ColsAtCompileTime!=1),
575 CanVectorizeLhs = (!LhsRowMajor) && (LhsFlags &
PacketAccessBit) && (RowsAtCompileTime!=1),
577 EvalToRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
578 : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
579 : (
bool(RhsRowMajor) && !CanVectorizeLhs),
584 | (SameType && (CanVectorizeLhs || CanVectorizeRhs) ?
PacketAccessBit : 0)
587 LhsOuterStrideBytes = int(LhsNestedCleaned::OuterStrideAtCompileTime) * int(
sizeof(
typename LhsNestedCleaned::Scalar)),
588 RhsOuterStrideBytes = int(RhsNestedCleaned::OuterStrideAtCompileTime) * int(
sizeof(
typename RhsNestedCleaned::Scalar)),
590 Alignment =
bool(CanVectorizeLhs) ? (LhsOuterStrideBytes<=0 || (int(LhsOuterStrideBytes) %
plain_enum_max(1, LhsAlignment))!=0 ? 0 : LhsAlignment)
591 :
bool(CanVectorizeRhs) ? (RhsOuterStrideBytes<=0 || (int(RhsOuterStrideBytes) %
plain_enum_max(1, RhsAlignment))!=0 ? 0 : RhsAlignment)
599 CanVectorizeInner = SameType
608 return (m_lhs.row(
row).transpose().cwiseProduct( m_rhs.col(
col) )).sum();
616 const CoeffReturnType coeff(
Index index)
const
618 const Index row = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? 0 : index;
619 const Index col = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? index : 0;
620 return (m_lhs.row(
row).transpose().cwiseProduct( m_rhs.col(
col) )).sum();
623 template<
int LoadMode,
typename PacketType>
629 Unroll ? int(InnerSize) :
Dynamic,
630 LhsEtorType, RhsEtorType, PacketType, LoadMode> PacketImpl;
631 PacketImpl::run(
row,
col, m_lhsImpl, m_rhsImpl, m_innerDim,
res);
635 template<
int LoadMode,
typename PacketType>
637 const PacketType packet(
Index index)
const
639 const Index row = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? 0 : index;
640 const Index col = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? index : 0;
641 return packet<LoadMode,PacketType>(
row,
col);
645 add_const_on_value_type_t<LhsNested> m_lhs;
646 add_const_on_value_type_t<RhsNested> m_rhs;
648 LhsEtorType m_lhsImpl;
649 RhsEtorType m_rhsImpl;
655 template<
typename Lhs,
typename Rhs>
657 : product_evaluator<Product<Lhs, Rhs, LazyProduct>, CoeffBasedProductMode, DenseShape, DenseShape>
659 typedef Product<Lhs, Rhs, DefaultProduct> XprType;
660 typedef Product<Lhs, Rhs, LazyProduct> BaseProduct;
661 typedef product_evaluator<BaseProduct, CoeffBasedProductMode, DenseShape, DenseShape> Base;
666 explicit product_evaluator(
const XprType& xpr)
667 : Base(BaseProduct(xpr.lhs(),xpr.rhs()))
675 template<
int UnrollingIndex,
typename Lhs,
typename Rhs,
typename Packet,
int LoadMode>
676 struct etor_product_packet_impl<
RowMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
680 etor_product_packet_impl<RowMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(
row,
col, lhs, rhs, innerDim,
res);
681 res =
pmadd(pset1<Packet>(lhs.coeff(
row,
Index(UnrollingIndex-1))), rhs.template packet<LoadMode,Packet>(
Index(UnrollingIndex-1),
col),
res);
685 template<
int UnrollingIndex,
typename Lhs,
typename Rhs,
typename Packet,
int LoadMode>
686 struct etor_product_packet_impl<
ColMajor, UnrollingIndex, Lhs, Rhs, Packet, LoadMode>
690 etor_product_packet_impl<ColMajor, UnrollingIndex-1, Lhs, Rhs, Packet, LoadMode>::run(
row,
col, lhs, rhs, innerDim,
res);
691 res =
pmadd(lhs.template packet<LoadMode,Packet>(
row,
Index(UnrollingIndex-1)), pset1<Packet>(rhs.coeff(
Index(UnrollingIndex-1),
col)),
res);
695 template<
typename Lhs,
typename Rhs,
typename Packet,
int LoadMode>
696 struct etor_product_packet_impl<
RowMajor, 1, Lhs, Rhs, Packet, LoadMode>
704 template<
typename Lhs,
typename Rhs,
typename Packet,
int LoadMode>
705 struct etor_product_packet_impl<
ColMajor, 1, Lhs, Rhs, Packet, LoadMode>
713 template<
typename Lhs,
typename Rhs,
typename Packet,
int LoadMode>
714 struct etor_product_packet_impl<
RowMajor, 0, Lhs, Rhs, Packet, LoadMode>
718 res = pset1<Packet>(
typename unpacket_traits<Packet>::type(0));
722 template<
typename Lhs,
typename Rhs,
typename Packet,
int LoadMode>
723 struct etor_product_packet_impl<
ColMajor, 0, Lhs, Rhs, Packet, LoadMode>
727 res = pset1<Packet>(
typename unpacket_traits<Packet>::type(0));
731 template<
typename Lhs,
typename Rhs,
typename Packet,
int LoadMode>
732 struct etor_product_packet_impl<
RowMajor,
Dynamic, Lhs, Rhs, Packet, LoadMode>
736 res = pset1<Packet>(
typename unpacket_traits<Packet>::type(0));
738 res =
pmadd(pset1<Packet>(lhs.coeff(
row,
i)), rhs.template packet<LoadMode,Packet>(
i,
col),
res);
742 template<
typename Lhs,
typename Rhs,
typename Packet,
int LoadMode>
743 struct etor_product_packet_impl<
ColMajor,
Dynamic, Lhs, Rhs, Packet, LoadMode>
747 res = pset1<Packet>(
typename unpacket_traits<Packet>::type(0));
749 res =
pmadd(lhs.template packet<LoadMode,Packet>(
row,
i), pset1<Packet>(rhs.coeff(
i,
col)),
res);
757 template<
int Mode,
bool LhsIsTriangular,
758 typename Lhs,
bool LhsIsVector,
759 typename Rhs,
bool RhsIsVector>
760 struct triangular_product_impl;
762 template<
typename Lhs,
typename Rhs,
int ProductTag>
763 struct generic_product_impl<Lhs,Rhs,TriangularShape,DenseShape,ProductTag>
764 : generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,TriangularShape,DenseShape,ProductTag> >
766 typedef typename Product<Lhs,Rhs>::Scalar Scalar;
768 template<
typename Dest>
769 static void scaleAndAddTo(Dest& dst,
const Lhs& lhs,
const Rhs& rhs,
const Scalar& alpha)
771 triangular_product_impl<Lhs::Mode,true,typename Lhs::MatrixType,false,Rhs, Rhs::ColsAtCompileTime==1>
772 ::run(dst, lhs.nestedExpression(), rhs, alpha);
776 template<
typename Lhs,
typename Rhs,
int ProductTag>
777 struct generic_product_impl<Lhs,Rhs,DenseShape,TriangularShape,ProductTag>
778 : generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,DenseShape,TriangularShape,ProductTag> >
780 typedef typename Product<Lhs,Rhs>::Scalar Scalar;
782 template<
typename Dest>
783 static void scaleAndAddTo(Dest& dst,
const Lhs& lhs,
const Rhs& rhs,
const Scalar& alpha)
785 triangular_product_impl<Rhs::Mode,false,Lhs,Lhs::RowsAtCompileTime==1, typename Rhs::MatrixType, false>::run(dst, lhs, rhs.nestedExpression(), alpha);
793 template <
typename Lhs,
int LhsMode,
bool LhsIsVector,
794 typename Rhs,
int RhsMode,
bool RhsIsVector>
795 struct selfadjoint_product_impl;
797 template<
typename Lhs,
typename Rhs,
int ProductTag>
798 struct generic_product_impl<Lhs,Rhs,SelfAdjointShape,DenseShape,ProductTag>
799 : generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,SelfAdjointShape,DenseShape,ProductTag> >
801 typedef typename Product<Lhs,Rhs>::Scalar Scalar;
803 template<
typename Dest>
805 void scaleAndAddTo(Dest& dst,
const Lhs& lhs,
const Rhs& rhs,
const Scalar& alpha)
807 selfadjoint_product_impl<typename Lhs::MatrixType,Lhs::Mode,false,Rhs,0,Rhs::IsVectorAtCompileTime>::run(dst, lhs.nestedExpression(), rhs, alpha);
811 template<
typename Lhs,
typename Rhs,
int ProductTag>
812 struct generic_product_impl<Lhs,Rhs,DenseShape,SelfAdjointShape,ProductTag>
813 : generic_product_impl_base<Lhs,Rhs,generic_product_impl<Lhs,Rhs,DenseShape,SelfAdjointShape,ProductTag> >
815 typedef typename Product<Lhs,Rhs>::Scalar Scalar;
817 template<
typename Dest>
818 static void scaleAndAddTo(Dest& dst,
const Lhs& lhs,
const Rhs& rhs,
const Scalar& alpha)
820 selfadjoint_product_impl<Lhs,0,Lhs::IsVectorAtCompileTime,typename Rhs::MatrixType,Rhs::Mode,false>::run(dst, lhs, rhs.nestedExpression(), alpha);
829 template<
typename MatrixType,
typename DiagonalType,
typename Derived,
int ProductOrder>
830 struct diagonal_product_evaluator_base
831 : evaluator_base<Derived>
833 typedef typename ScalarBinaryOpTraits<typename MatrixType::Scalar, typename DiagonalType::Scalar>::ReturnType Scalar;
836 CoeffReadCost = int(
NumTraits<Scalar>::MulCost) + int(evaluator<MatrixType>::CoeffReadCost) + int(evaluator<DiagonalType>::CoeffReadCost),
838 MatrixFlags = evaluator<MatrixType>::Flags,
839 DiagFlags = evaluator<DiagonalType>::Flags,
841 StorageOrder_ = (Derived::MaxRowsAtCompileTime==1 && Derived::MaxColsAtCompileTime!=1) ?
RowMajor
842 : (Derived::MaxColsAtCompileTime==1 && Derived::MaxRowsAtCompileTime!=1) ?
ColMajor
846 ScalarAccessOnDiag_ = !((
int(StorageOrder_) ==
ColMajor && int(ProductOrder) ==
OnTheLeft)
848 SameTypes_ = is_same<typename MatrixType::Scalar, typename DiagonalType::Scalar>::value,
855 LinearAccessMask_ = (MatrixType::RowsAtCompileTime==1 || MatrixType::ColsAtCompileTime==1) ?
LinearAccessBit : 0,
857 Alignment = evaluator<MatrixType>::Alignment,
859 AsScalarProduct = (DiagonalType::SizeAtCompileTime==1)
860 || (DiagonalType::SizeAtCompileTime==
Dynamic && MatrixType::RowsAtCompileTime==1 && ProductOrder==
OnTheLeft)
861 || (DiagonalType::SizeAtCompileTime==
Dynamic && MatrixType::ColsAtCompileTime==1 && ProductOrder==
OnTheRight)
865 : m_diagImpl(diag), m_matImpl(
mat)
874 return m_diagImpl.coeff(0) * m_matImpl.coeff(idx);
876 return m_diagImpl.coeff(idx) * m_matImpl.coeff(idx);
880 template<
int LoadMode,
typename PacketType>
881 EIGEN_STRONG_INLINE PacketType packet_impl(
Index row,
Index col,
Index id, internal::true_type)
const
884 internal::pset1<PacketType>(m_diagImpl.coeff(
id)));
887 template<
int LoadMode,
typename PacketType>
888 EIGEN_STRONG_INLINE PacketType packet_impl(
Index row,
Index col,
Index id, internal::false_type)
const
891 InnerSize = (MatrixType::Flags &
RowMajorBit) ? MatrixType::ColsAtCompileTime : MatrixType::RowsAtCompileTime,
892 DiagonalPacketLoadMode =
plain_enum_min(LoadMode,((InnerSize%16) == 0) ? int(
Aligned16) : int(evaluator<DiagonalType>::Alignment))
895 m_diagImpl.template packet<DiagonalPacketLoadMode,PacketType>(
id));
898 evaluator<DiagonalType> m_diagImpl;
899 evaluator<MatrixType> m_matImpl;
903 template<
typename Lhs,
typename Rhs,
int ProductKind,
int ProductTag>
904 struct product_evaluator<Product<Lhs, Rhs, ProductKind>, ProductTag, DiagonalShape, DenseShape>
905 : diagonal_product_evaluator_base<Rhs, typename Lhs::DiagonalVectorType, Product<Lhs, Rhs, LazyProduct>, OnTheLeft>
907 typedef diagonal_product_evaluator_base<Rhs, typename Lhs::DiagonalVectorType, Product<Lhs, Rhs, LazyProduct>,
OnTheLeft> Base;
908 using Base::m_diagImpl;
909 using Base::m_matImpl;
911 typedef typename Base::Scalar Scalar;
913 typedef Product<Lhs, Rhs, ProductKind> XprType;
914 typedef typename XprType::PlainObject PlainObject;
915 typedef typename Lhs::DiagonalVectorType DiagonalType;
918 enum { StorageOrder = Base::StorageOrder_ };
921 : Base(xpr.rhs(), xpr.lhs().diagonal())
927 return m_diagImpl.coeff(
row) * m_matImpl.coeff(
row,
col);
931 template<
int LoadMode,
typename PacketType>
936 return this->
template packet_impl<LoadMode,PacketType>(
row,
col,
row,
937 std::conditional_t<
int(StorageOrder)==
RowMajor, internal::true_type, internal::false_type>());
940 template<
int LoadMode,
typename PacketType>
941 EIGEN_STRONG_INLINE PacketType packet(
Index idx)
const
943 return packet<LoadMode,PacketType>(
int(StorageOrder)==
ColMajor?idx:0,
int(StorageOrder)==
ColMajor?0:idx);
949 template<
typename Lhs,
typename Rhs,
int ProductKind,
int ProductTag>
950 struct product_evaluator<Product<Lhs, Rhs, ProductKind>, ProductTag, DenseShape, DiagonalShape>
951 : diagonal_product_evaluator_base<Lhs, typename Rhs::DiagonalVectorType, Product<Lhs, Rhs, LazyProduct>,
OnTheRight>
953 typedef diagonal_product_evaluator_base<Lhs, typename Rhs::DiagonalVectorType, Product<Lhs, Rhs, LazyProduct>,
OnTheRight> Base;
954 using Base::m_diagImpl;
955 using Base::m_matImpl;
957 typedef typename Base::Scalar Scalar;
959 typedef Product<Lhs, Rhs, ProductKind> XprType;
960 typedef typename XprType::PlainObject PlainObject;
962 enum { StorageOrder = Base::StorageOrder_ };
965 : Base(xpr.lhs(), xpr.rhs().diagonal())
971 return m_matImpl.coeff(
row,
col) * m_diagImpl.coeff(
col);
975 template<
int LoadMode,
typename PacketType>
978 return this->
template packet_impl<LoadMode,PacketType>(
row,
col,
col,
979 std::conditional_t<
int(StorageOrder)==
ColMajor, internal::true_type, internal::false_type>());
982 template<
int LoadMode,
typename PacketType>
983 EIGEN_STRONG_INLINE PacketType packet(
Index idx)
const
985 return packet<LoadMode,PacketType>(
int(StorageOrder)==
ColMajor?idx:0,
int(StorageOrder)==
ColMajor?0:idx);
999 template<
typename ExpressionType,
int S
ide,
bool Transposed,
typename ExpressionShape>
1000 struct permutation_matrix_product;
1002 template<
typename ExpressionType,
int S
ide,
bool Transposed>
1003 struct permutation_matrix_product<ExpressionType, Side, Transposed, DenseShape>
1005 typedef typename nested_eval<ExpressionType, 1>::type
MatrixType;
1006 typedef remove_all_t<MatrixType> MatrixTypeCleaned;
1008 template<
typename Dest,
typename PermutationType>
1009 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(Dest& dst,
const PermutationType& perm,
const ExpressionType& xpr)
1019 Matrix<bool,PermutationType::RowsAtCompileTime,1,0,PermutationType::MaxRowsAtCompileTime> mask(perm.size());
1022 while(r < perm.size())
1025 while(r<perm.size() && mask[r]) r++;
1031 mask.coeffRef(k0) =
true;
1032 for(
Index k=perm.indices().coeff(k0); k!=k0; k=perm.indices().coeff(k))
1034 Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>(dst, k)
1035 .swap(Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>
1036 (dst,((Side==
OnTheLeft) ^ Transposed) ? k0 : kPrev));
1038 mask.coeffRef(k) =
true;
1047 Block<Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime>
1048 (dst, ((Side==
OnTheLeft) ^ Transposed) ? perm.indices().coeff(
i) :
i)
1052 Block<const MatrixTypeCleaned,Side==OnTheLeft ? 1 : MatrixTypeCleaned::RowsAtCompileTime,Side==OnTheRight ? 1 : MatrixTypeCleaned::ColsAtCompileTime>
1053 (
mat, ((Side==
OnTheRight) ^ Transposed) ? perm.indices().coeff(
i) :
i);
1059 template<
typename Lhs,
typename Rhs,
int ProductTag,
typename MatrixShape>
1060 struct generic_product_impl<Lhs, Rhs, PermutationShape, MatrixShape, ProductTag>
1062 template<
typename Dest>
1063 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void evalTo(Dest& dst,
const Lhs& lhs,
const Rhs& rhs)
1065 permutation_matrix_product<Rhs, OnTheLeft, false, MatrixShape>::run(dst, lhs, rhs);
1069 template<
typename Lhs,
typename Rhs,
int ProductTag,
typename MatrixShape>
1070 struct generic_product_impl<Lhs, Rhs, MatrixShape, PermutationShape, ProductTag>
1072 template<
typename Dest>
1073 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void evalTo(Dest& dst,
const Lhs& lhs,
const Rhs& rhs)
1075 permutation_matrix_product<Lhs, OnTheRight, false, MatrixShape>::run(dst, rhs, lhs);
1079 template<
typename Lhs,
typename Rhs,
int ProductTag,
typename MatrixShape>
1080 struct generic_product_impl<Inverse<Lhs>, Rhs, PermutationShape, MatrixShape, ProductTag>
1082 template<
typename Dest>
1083 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void evalTo(Dest& dst,
const Inverse<Lhs>& lhs,
const Rhs& rhs)
1085 permutation_matrix_product<Rhs, OnTheLeft, true, MatrixShape>::run(dst, lhs.nestedExpression(), rhs);
1089 template<
typename Lhs,
typename Rhs,
int ProductTag,
typename MatrixShape>
1090 struct generic_product_impl<Lhs, Inverse<Rhs>, MatrixShape, PermutationShape, ProductTag>
1092 template<
typename Dest>
1093 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void evalTo(Dest& dst,
const Lhs& lhs,
const Inverse<Rhs>& rhs)
1095 permutation_matrix_product<Lhs, OnTheRight, true, MatrixShape>::run(dst, rhs.nestedExpression(), lhs);
1110 template<
typename ExpressionType,
int S
ide,
bool Transposed,
typename ExpressionShape>
1111 struct transposition_matrix_product
1113 typedef typename nested_eval<ExpressionType, 1>::type
MatrixType;
1114 typedef remove_all_t<MatrixType> MatrixTypeCleaned;
1116 template<
typename Dest,
typename TranspositionType>
1117 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void run(Dest& dst,
const TranspositionType& tr,
const ExpressionType& xpr)
1120 typedef typename TranspositionType::StorageIndex StorageIndex;
1127 for(
Index k=(Transposed?
size-1:0) ; Transposed?k>=0:k<
size ; Transposed?--k:++k)
1128 if(
Index(
j=tr.coeff(k))!=k)
1130 if(Side==
OnTheLeft) dst.row(k).swap(dst.row(
j));
1131 else if(Side==
OnTheRight) dst.col(k).swap(dst.col(
j));
1136 template<
typename Lhs,
typename Rhs,
int ProductTag,
typename MatrixShape>
1137 struct generic_product_impl<Lhs, Rhs, TranspositionsShape, MatrixShape, ProductTag>
1139 template<
typename Dest>
1140 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void evalTo(Dest& dst,
const Lhs& lhs,
const Rhs& rhs)
1142 transposition_matrix_product<Rhs, OnTheLeft, false, MatrixShape>::run(dst, lhs, rhs);
1146 template<
typename Lhs,
typename Rhs,
int ProductTag,
typename MatrixShape>
1147 struct generic_product_impl<Lhs, Rhs, MatrixShape, TranspositionsShape, ProductTag>
1149 template<
typename Dest>
1150 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void evalTo(Dest& dst,
const Lhs& lhs,
const Rhs& rhs)
1152 transposition_matrix_product<Lhs, OnTheRight, false, MatrixShape>::run(dst, rhs, lhs);
1157 template<
typename Lhs,
typename Rhs,
int ProductTag,
typename MatrixShape>
1158 struct generic_product_impl<Transpose<Lhs>, Rhs, TranspositionsShape, MatrixShape, ProductTag>
1160 template<
typename Dest>
1161 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void evalTo(Dest& dst,
const Transpose<Lhs>& lhs,
const Rhs& rhs)
1163 transposition_matrix_product<Rhs, OnTheLeft, true, MatrixShape>::run(dst, lhs.nestedExpression(), rhs);
1167 template<
typename Lhs,
typename Rhs,
int ProductTag,
typename MatrixShape>
1168 struct generic_product_impl<Lhs, Transpose<Rhs>, MatrixShape, TranspositionsShape, ProductTag>
1170 template<
typename Dest>
1171 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void evalTo(Dest& dst,
const Lhs& lhs,
const Transpose<Rhs>& rhs)
1173 transposition_matrix_product<Lhs, OnTheRight, true, MatrixShape>::run(dst, rhs.nestedExpression(), lhs);
1181 template<
typename Lhs,
typename Rhs,
int ProductTag,
typename MatrixShape>
1182 struct generic_product_impl<Lhs, Rhs, SkewSymmetricShape, MatrixShape, ProductTag>
1184 template<
typename Dest>
1185 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void evalTo(Dest& dst,
const Lhs& lhs,
const Rhs& rhs)
1187 generic_product_impl<typename Lhs::DenseMatrixType , Rhs, DenseShape, MatrixShape, ProductTag>::evalTo(dst, lhs, rhs);
1191 template<
typename Lhs,
typename Rhs,
int ProductTag,
typename MatrixShape>
1192 struct generic_product_impl<Lhs, Rhs, MatrixShape, SkewSymmetricShape, ProductTag>
1194 template<
typename Dest>
1195 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void evalTo(Dest& dst,
const Lhs& lhs,
const Rhs& rhs)
1197 generic_product_impl<Lhs, typename Rhs::DenseMatrixType, MatrixShape, DenseShape, ProductTag>::evalTo(dst, lhs, rhs);
1201 template<
typename Lhs,
typename Rhs,
int ProductTag>
1202 struct generic_product_impl<Lhs, Rhs, SkewSymmetricShape, SkewSymmetricShape, ProductTag>
1204 template<
typename Dest>
1205 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void evalTo(Dest& dst,
const Lhs& lhs,
const Rhs& rhs)
1207 generic_product_impl<typename Lhs::DenseMatrixType, typename Rhs::DenseMatrixType, DenseShape, DenseShape, ProductTag>::evalTo(dst, lhs, rhs);
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_internal_assert(x)
#define EIGEN_UNUSED_VARIABLE(var)
#define EIGEN_DEVICE_FUNC
#define EIGEN_SCALAR_BINARYOP_EXPR_RETURN_TYPE(SCALAR, EXPR, OPNAME)
#define ei_declare_local_nested_eval(XPR_T, XPR, N, NAME)
cout<< "Here is the matrix m:"<< endl<< m<< endl;Matrix< ptrdiff_t, 3, 1 > res
#define EIGEN_UNROLLING_LIMIT
#define EIGEN_INTERNAL_CHECK_COST_VALUE(C)
Matrix< float, 1, Dynamic > MatrixType
const unsigned int ActualPacketAccessBit
const unsigned int PacketAccessBit
const unsigned int LinearAccessBit
const unsigned int EvalBeforeNestingBit
const unsigned int RowMajorBit
constexpr int plain_enum_min(A a, B b)
constexpr int plain_enum_max(A a, B b)
void call_restricted_packet_assignment_no_alias(Dst &dst, const Src &src, const Func &func)
EIGEN_CATCH_ASSIGN_XPR_OP_PRODUCT(assign_op, scalar_sum_op, add_assign_op)
Packet4f pmadd(const Packet4f &a, const Packet4f &b, const Packet4f &c)
Packet pmul(const Packet &a, const Packet &b)
constexpr int min_size_prefer_fixed(A a, B b)
EIGEN_CONSTEXPR void call_assignment_no_alias(Dst &dst, const Src &src, const Func &func)
void outer_product_selector_run(Dst &dst, const Lhs &lhs, const Rhs &rhs, const Func &func, const false_type &)
typename remove_all< T >::type remove_all_t
bool is_same_dense(const T1 &mat1, const T2 &mat2, std::enable_if_t< possibly_same_dense< T1, T2 >::value > *=0)
bool is_exactly_one(const X &x)
@ LazyCoeffBasedProductMode
const unsigned int HereditaryBits
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.