299 template<
typename T>
struct is_row_major :
internal::conditional<(int(T::Flags)&RowMajorBit), internal::true_type, internal::false_type>::type {};
303 struct set {
template<
typename Dst,
typename Src> EIGEN_DEVICE_FUNC
void operator()(
const Dst& dst,
const Src& src)
const { dst.const_cast_derived() = src; } };
304 struct add {
template<
typename Dst,
typename Src> EIGEN_DEVICE_FUNC
void operator()(
const Dst& dst,
const Src& src)
const { dst.const_cast_derived() += src; } };
305 struct sub {
template<
typename Dst,
typename Src> EIGEN_DEVICE_FUNC
void operator()(
const Dst& dst,
const Src& src)
const { dst.const_cast_derived() -= src; } };
308 explicit adds(
const Scalar& s) : m_scale(s) {}
309 template<
typename Dst,
typename Src>
void EIGEN_DEVICE_FUNC operator()(
const Dst& dst,
const Src& src)
const {
310 dst.const_cast_derived() += m_scale * src;
314 template<
typename Dst>
315 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void evalTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
317 internal::outer_product_selector_run(dst, lhs, rhs, set(), is_row_major<Dst>());
320 template<
typename Dst>
321 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void addTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
323 internal::outer_product_selector_run(dst, lhs, rhs, add(), is_row_major<Dst>());
326 template<
typename Dst>
327 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void subTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
329 internal::outer_product_selector_run(dst, lhs, rhs, sub(), is_row_major<Dst>());
332 template<
typename Dst>
333 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void scaleAndAddTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs,
const Scalar& alpha)
335 internal::outer_product_selector_run(dst, lhs, rhs, adds(alpha), is_row_major<Dst>());
347 template<
typename Dst>
348 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void evalTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
349 { dst.setZero(); scaleAndAddTo(dst, lhs, rhs, Scalar(1)); }
351 template<
typename Dst>
352 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void addTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
353 { scaleAndAddTo(dst,lhs, rhs, Scalar(1)); }
355 template<
typename Dst>
356 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void subTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
357 { scaleAndAddTo(dst, lhs, rhs, Scalar(-1)); }
359 template<
typename Dst>
360 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void scaleAndAddTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs,
const Scalar& alpha)
361 { Derived::scaleAndAddTo(dst,lhs,rhs,alpha); }
397 template<
typename Dst>
398 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void evalTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
405 template<
typename Dst>
406 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void addTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
412 template<
typename Dst>
413 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
void subTo(Dst& dst,
const Lhs& lhs,
const Rhs& rhs)
433 template<
typename Dst,
typename Func>
434 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
435 void eval_dynamic(Dst& dst,
const Lhs& lhs,
const Rhs& rhs,
const Func &func)
444 Scalar actualAlpha = combine_scalar_factors<Scalar>(lhs, rhs);
446 eval_dynamic_impl(dst,
456 template<
typename Dst,
typename LhsT,
typename RhsT,
typename Func,
typename Scalar>
457 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
458 void eval_dynamic_impl(Dst& dst,
const LhsT& lhs,
const RhsT& rhs,
const Func &func,
const Scalar& s ,
false_type)
460 EIGEN_UNUSED_VARIABLE(s);
461 eigen_internal_assert(s==Scalar(1));
462 call_restricted_packet_assignment_no_alias(dst, lhs.lazyProduct(rhs), func);
465 template<
typename Dst,
typename LhsT,
typename RhsT,
typename Func,
typename Scalar>
466 static EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
467 void eval_dynamic_impl(Dst& dst,
const LhsT& lhs,
const RhsT& rhs,
const Func &func,
const Scalar& s,
true_type)
469 call_restricted_packet_assignment_no_alias(dst, s * lhs.lazyProduct(rhs), func);
495 typedef typename XprType::Scalar Scalar;
496 typedef typename XprType::CoeffReturnType CoeffReturnType;
498 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
505 m_innerDim(xpr.lhs().cols())
509 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
511 std::cerr <<
"LhsOuterStrideBytes= " << LhsOuterStrideBytes <<
"\n";
512 std::cerr <<
"RhsOuterStrideBytes= " << RhsOuterStrideBytes <<
"\n";
513 std::cerr <<
"LhsAlignment= " << LhsAlignment <<
"\n";
514 std::cerr <<
"RhsAlignment= " << RhsAlignment <<
"\n";
515 std::cerr <<
"CanVectorizeLhs= " << CanVectorizeLhs <<
"\n";
516 std::cerr <<
"CanVectorizeRhs= " << CanVectorizeRhs <<
"\n";
517 std::cerr <<
"CanVectorizeInner= " << CanVectorizeInner <<
"\n";
518 std::cerr <<
"EvalToRowMajor= " << EvalToRowMajor <<
"\n";
519 std::cerr <<
"Alignment= " << Alignment <<
"\n";
520 std::cerr <<
"Flags= " << Flags <<
"\n";
529 typedef typename internal::remove_all<LhsNested>::type LhsNestedCleaned;
530 typedef typename internal::remove_all<RhsNested>::type RhsNestedCleaned;
536 RowsAtCompileTime = LhsNestedCleaned::RowsAtCompileTime,
537 ColsAtCompileTime = RhsNestedCleaned::ColsAtCompileTime,
538 InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(LhsNestedCleaned::ColsAtCompileTime, RhsNestedCleaned::RowsAtCompileTime),
539 MaxRowsAtCompileTime = LhsNestedCleaned::MaxRowsAtCompileTime,
540 MaxColsAtCompileTime = RhsNestedCleaned::MaxColsAtCompileTime
543 typedef typename find_best_packet<Scalar,RowsAtCompileTime>::type LhsVecPacketType;
544 typedef typename find_best_packet<Scalar,ColsAtCompileTime>::type RhsVecPacketType;
548 LhsCoeffReadCost = LhsEtorType::CoeffReadCost,
549 RhsCoeffReadCost = RhsEtorType::CoeffReadCost,
555 Unroll = CoeffReadCost <= EIGEN_UNROLLING_LIMIT,
557 LhsFlags = LhsEtorType::Flags,
558 RhsFlags = RhsEtorType::Flags,
567 LhsAlignment = EIGEN_PLAIN_ENUM_MIN(LhsEtorType::Alignment,LhsVecPacketSize*
int(
sizeof(
typename LhsNestedCleaned::Scalar))),
568 RhsAlignment = EIGEN_PLAIN_ENUM_MIN(RhsEtorType::Alignment,RhsVecPacketSize*
int(
sizeof(
typename RhsNestedCleaned::Scalar))),
572 CanVectorizeRhs = bool(RhsRowMajor) && (RhsFlags &
PacketAccessBit) && (ColsAtCompileTime!=1),
573 CanVectorizeLhs = (!LhsRowMajor) && (LhsFlags &
PacketAccessBit) && (RowsAtCompileTime!=1),
575 EvalToRowMajor = (MaxRowsAtCompileTime==1&&MaxColsAtCompileTime!=1) ? 1
576 : (MaxColsAtCompileTime==1&&MaxRowsAtCompileTime!=1) ? 0
577 : (bool(RhsRowMajor) && !CanVectorizeLhs),
579 Flags = ((
int(LhsFlags) |
int(RhsFlags)) & HereditaryBits & ~RowMajorBit)
582 | (SameType && (CanVectorizeLhs || CanVectorizeRhs) ?
PacketAccessBit : 0)
585 LhsOuterStrideBytes =
int(LhsNestedCleaned::OuterStrideAtCompileTime) * int(
sizeof(
typename LhsNestedCleaned::Scalar)),
586 RhsOuterStrideBytes = int(RhsNestedCleaned::OuterStrideAtCompileTime) * int(
sizeof(
typename RhsNestedCleaned::Scalar)),
588 Alignment = bool(CanVectorizeLhs) ? (LhsOuterStrideBytes<=0 || (int(LhsOuterStrideBytes) % EIGEN_PLAIN_ENUM_MAX(1,LhsAlignment))!=0 ? 0 : LhsAlignment)
589 : bool(CanVectorizeRhs) ? (RhsOuterStrideBytes<=0 || (int(RhsOuterStrideBytes) % EIGEN_PLAIN_ENUM_MAX(1,RhsAlignment))!=0 ? 0 : RhsAlignment)
597 CanVectorizeInner = SameType
600 && (
int(LhsFlags) & int(RhsFlags) & ActualPacketAccessBit)
604 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const CoeffReturnType coeff(
Index row,
Index col)
const
606 return (m_lhs.row(row).transpose().cwiseProduct( m_rhs.col(col) )).sum();
613 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
614 const CoeffReturnType coeff(
Index index)
const
616 const Index row = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? 0 : index;
617 const Index col = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? index : 0;
618 return (m_lhs.row(row).transpose().cwiseProduct( m_rhs.col(col) )).sum();
621 template<
int LoadMode,
typename PacketType>
622 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
623 const PacketType packet(
Index row,
Index col)
const
627 Unroll ? int(InnerSize) :
Dynamic,
629 PacketImpl::run(row, col, m_lhsImpl, m_rhsImpl, m_innerDim, res);
633 template<
int LoadMode,
typename PacketType>
634 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
635 const PacketType packet(
Index index)
const
637 const Index row = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? 0 : index;
638 const Index col = (RowsAtCompileTime == 1 || MaxRowsAtCompileTime==1) ? index : 0;
639 return packet<LoadMode,PacketType>(row,col);
643 typename internal::add_const_on_value_type<LhsNested>::type m_lhs;
644 typename internal::add_const_on_value_type<RhsNested>::type m_rhs;
839 _StorageOrder = (Derived::MaxRowsAtCompileTime==1 && Derived::MaxColsAtCompileTime!=1) ?
RowMajor
840 : (Derived::MaxColsAtCompileTime==1 && Derived::MaxRowsAtCompileTime!=1) ?
ColMajor
844 _ScalarAccessOnDiag = !((
int(_StorageOrder) ==
ColMajor &&
int(ProductOrder) ==
OnTheLeft)
853 _LinearAccessMask = (MatrixType::RowsAtCompileTime==1 || MatrixType::ColsAtCompileTime==1) ?
LinearAccessBit : 0,
854 Flags = ((HereditaryBits|_LinearAccessMask) & (
unsigned int)(MatrixFlags)) | (_Vectorizable ?
PacketAccessBit : 0),
857 AsScalarProduct = (DiagonalType::SizeAtCompileTime==1)
858 || (DiagonalType::SizeAtCompileTime==
Dynamic && MatrixType::RowsAtCompileTime==1 && ProductOrder==
OnTheLeft)
859 || (DiagonalType::SizeAtCompileTime==
Dynamic && MatrixType::ColsAtCompileTime==1 && ProductOrder==
OnTheRight)
863 : m_diagImpl(diag), m_matImpl(mat)
866 EIGEN_INTERNAL_CHECK_COST_VALUE(CoeffReadCost);
869 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar coeff(
Index idx)
const
872 return m_diagImpl.coeff(0) * m_matImpl.coeff(idx);
874 return m_diagImpl.coeff(idx) * m_matImpl.coeff(idx);
878 template<
int LoadMode,
typename PacketType>
881 return internal::pmul(m_matImpl.template packet<LoadMode,PacketType>(row, col),
882 internal::pset1<PacketType>(m_diagImpl.coeff(
id)));
885 template<
int LoadMode,
typename PacketType>
889 InnerSize = (MatrixType::Flags &
RowMajorBit) ? MatrixType::ColsAtCompileTime : MatrixType::RowsAtCompileTime,
892 return internal::pmul(m_matImpl.template packet<LoadMode,PacketType>(row, col),
893 m_diagImpl.template packet<DiagonalPacketLoadMode,PacketType>(
id));
906 using Base::m_diagImpl;
907 using Base::m_matImpl;
909 typedef typename Base::Scalar Scalar;
912 typedef typename XprType::PlainObject PlainObject;
913 typedef typename Lhs::DiagonalVectorType DiagonalType;
916 enum { StorageOrder = Base::_StorageOrder };
919 :
Base(xpr.rhs(), xpr.lhs().diagonal())
923 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
const Scalar coeff(
Index row,
Index col)
const
925 return m_diagImpl.coeff(row) * m_matImpl.coeff(row, col);
929 template<
int LoadMode,
typename PacketType>
930 EIGEN_STRONG_INLINE PacketType packet(
Index row,
Index col)
const
934 return this->
template packet_impl<LoadMode,PacketType>(row,col, row,
938 template<
int LoadMode,
typename PacketType>
939 EIGEN_STRONG_INLINE PacketType packet(
Index idx)
const
941 return packet<LoadMode,PacketType>(
int(StorageOrder)==
ColMajor?idx:0,int(StorageOrder)==
ColMajor?0:idx);