11 #ifndef EIGEN_GENERAL_PRODUCT_H 12 #define EIGEN_GENERAL_PRODUCT_H 35 template<typename Lhs, typename Rhs, int ProductType = internal::product_type<Lhs,Rhs>::value>
49 enum { is_large = MaxSize ==
Dynamic ||
50 Size >= EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD,
51 value = is_large ? Large
62 MaxRows = _Lhs::MaxRowsAtCompileTime,
63 Rows = _Lhs::RowsAtCompileTime,
64 MaxCols = _Rhs::MaxColsAtCompileTime,
65 Cols = _Rhs::ColsAtCompileTime,
66 MaxDepth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::MaxColsAtCompileTime,
67 _Rhs::MaxRowsAtCompileTime),
68 Depth = EIGEN_SIZE_MIN_PREFER_FIXED(_Lhs::ColsAtCompileTime,
69 _Rhs::RowsAtCompileTime),
70 LargeThreshold = EIGEN_CACHEFRIENDLY_PRODUCT_THRESHOLD
87 #ifdef EIGEN_DEBUG_PRODUCT 90 EIGEN_DEBUG_VAR(Rows);
91 EIGEN_DEBUG_VAR(Cols);
92 EIGEN_DEBUG_VAR(Depth);
93 EIGEN_DEBUG_VAR(rows_select);
94 EIGEN_DEBUG_VAR(cols_select);
95 EIGEN_DEBUG_VAR(depth_select);
96 EIGEN_DEBUG_VAR(value);
148 template<
typename Lhs,
typename Rhs,
int ProductType>
158 template<
typename Lhs,
typename Rhs>
166 template<
typename Lhs,
typename Rhs>
175 template<
typename Lhs,
typename Rhs>
192 template<
typename Lhs,
typename Rhs>
194 :
traits<Matrix<typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType,1,1> >
199 template<
typename Lhs,
typename Rhs>
202 public Matrix<typename internal::scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType,1,1>
209 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
211 Base::coeffRef(0,0) = (lhs.transpose().cwiseProduct(rhs)).sum();
216 return Base::coeff(0,0);
227 template<
typename ProductType,
typename Dest,
typename Func>
228 EIGEN_DONT_INLINE
void outer_product_selector_run(
const ProductType& prod, Dest& dest,
const Func&
func,
const false_type&)
230 typedef typename Dest::Index Index;
233 const Index cols = dest.cols();
234 for (Index j=0; j<cols; ++j)
235 func(dest.col(j), prod.rhs().coeff(0,j) * prod.lhs());
239 template<
typename ProductType,
typename Dest,
typename Func>
240 EIGEN_DONT_INLINE
void outer_product_selector_run(
const ProductType& prod, Dest& dest,
const Func& func,
const true_type&) {
241 typedef typename Dest::Index Index;
244 const Index rows = dest.rows();
245 for (Index i=0; i<rows; ++i)
246 func(dest.row(i), prod.lhs().coeff(i,0) * prod.rhs());
249 template<
typename Lhs,
typename Rhs>
251 :
traits<ProductBase<GeneralProduct<Lhs,Rhs,OuterProduct>, Lhs, Rhs> >
256 template<
typename Lhs,
typename Rhs>
258 :
public ProductBase<GeneralProduct<Lhs,Rhs,OuterProduct>, Lhs, Rhs>
260 template<
typename T>
struct is_row_major :
internal::conditional<(int(T::Flags)&RowMajorBit), internal::true_type, internal::false_type>::type {};
268 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
271 struct set {
template<
typename Dst,
typename Src>
void operator()(
const Dst& dst,
const Src& src)
const { dst.const_cast_derived() = src; } };
272 struct add {
template<
typename Dst,
typename Src>
void operator()(
const Dst& dst,
const Src& src)
const { dst.const_cast_derived() += src; } };
273 struct sub {
template<
typename Dst,
typename Src>
void operator()(
const Dst& dst,
const Src& src)
const { dst.const_cast_derived() -= src; } };
276 adds(
const Scalar& s) : m_scale(s) {}
277 template<
typename Dst,
typename Src>
void operator()(
const Dst& dst,
const Src& src)
const {
278 dst.const_cast_derived() += m_scale * src;
282 template<
typename Dest>
283 inline void evalTo(Dest& dest)
const {
284 internal::outer_product_selector_run(*
this, dest,
set(), is_row_major<Dest>());
287 template<
typename Dest>
288 inline void addTo(Dest& dest)
const {
289 internal::outer_product_selector_run(*
this, dest, add(), is_row_major<Dest>());
292 template<
typename Dest>
293 inline void subTo(Dest& dest)
const {
294 internal::outer_product_selector_run(*
this, dest, sub(), is_row_major<Dest>());
297 template<
typename Dest>
void scaleAndAddTo(Dest& dest,
const Scalar& alpha)
const 299 internal::outer_product_selector_run(*
this, dest, adds(alpha), is_row_major<Dest>());
316 template<
typename Lhs,
typename Rhs>
318 :
traits<ProductBase<GeneralProduct<Lhs,Rhs,GemvProduct>, Lhs, Rhs> >
321 template<
int S
ide,
int StorageOrder,
bool BlasCompatible>
326 template<
typename Lhs,
typename Rhs>
328 :
public ProductBase<GeneralProduct<Lhs,Rhs,GemvProduct>, Lhs, Rhs>
345 template<
typename Dest>
void scaleAndAddTo(Dest& dst,
const Scalar& alpha)
const 347 eigen_assert(m_lhs.rows() == dst.rows() && m_rhs.cols() == dst.cols());
356 template<
int StorageOrder,
bool BlasCompatible>
359 template<
typename ProductType,
typename Dest>
360 static void run(
const ProductType& prod, Dest& dest,
const typename ProductType::Scalar& alpha)
366 (prod.rhs().transpose(), prod.lhs().transpose()), destT, alpha);
372 template<
typename Scalar,
int Size,
int MaxSize>
375 EIGEN_STRONG_INLINE Scalar* data() { eigen_internal_assert(
false &&
"should never be called");
return 0; }
378 template<
typename Scalar,
int Size>
381 EIGEN_STRONG_INLINE Scalar* data() {
return 0; }
384 template<
typename Scalar,
int Size,
int MaxSize>
387 #if EIGEN_ALIGN_STATICALLY 389 EIGEN_STRONG_INLINE Scalar* data() {
return m_data.array; }
398 EIGEN_STRONG_INLINE Scalar* data() {
399 return ForceAlignment
400 ?
reinterpret_cast<Scalar*
>((
reinterpret_cast<size_t>(m_data.array) & ~(
size_t(15))) + 16)
408 template<
typename ProductType,
typename Dest>
409 static inline void run(
const ProductType& prod, Dest& dest,
const typename ProductType::Scalar& alpha)
411 typedef typename ProductType::Index Index;
412 typedef typename ProductType::LhsScalar LhsScalar;
413 typedef typename ProductType::RhsScalar RhsScalar;
415 typedef typename ProductType::RealScalar RealScalar;
416 typedef typename ProductType::ActualLhsType ActualLhsType;
417 typedef typename ProductType::ActualRhsType ActualRhsType;
418 typedef typename ProductType::LhsBlasTraits LhsBlasTraits;
419 typedef typename ProductType::RhsBlasTraits RhsBlasTraits;
422 ActualLhsType actualLhs = LhsBlasTraits::extract(prod.lhs());
423 ActualRhsType actualRhs = RhsBlasTraits::extract(prod.rhs());
425 ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs())
426 * RhsBlasTraits::extractScalarFactor(prod.rhs());
434 EvalToDestAtCompileTime = (ActualDest::InnerStrideAtCompileTime==1),
436 MightCannotUseDest = (ActualDest::InnerStrideAtCompileTime!=1) || ComplexByReal
441 bool alphaIsCompatible = (!ComplexByReal) || (numext::imag(actualAlpha)==RealScalar(0));
442 bool evalToDest = EvalToDestAtCompileTime && alphaIsCompatible;
446 ei_declare_aligned_stack_constructed_variable(ResScalar,actualDestPtr,dest.size(),
447 evalToDest ? dest.data() : static_dest.data());
451 #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN 452 int size = dest.size();
453 EIGEN_DENSE_STORAGE_CTOR_PLUGIN
455 if(!alphaIsCompatible)
457 MappedDest(actualDestPtr, dest.size()).setZero();
458 compatibleAlpha = RhsScalar(1);
461 MappedDest(actualDestPtr, dest.size()) = dest;
465 <Index,LhsScalar,
ColMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsBlasTraits::NeedToConjugate>::run(
466 actualLhs.rows(), actualLhs.cols(),
467 actualLhs.data(), actualLhs.outerStride(),
468 actualRhs.data(), actualRhs.innerStride(),
474 if(!alphaIsCompatible)
475 dest += actualAlpha * MappedDest(actualDestPtr, dest.size());
477 dest = MappedDest(actualDestPtr, dest.size());
484 template<
typename ProductType,
typename Dest>
485 static void run(
const ProductType& prod, Dest& dest,
const typename ProductType::Scalar& alpha)
487 typedef typename ProductType::LhsScalar LhsScalar;
488 typedef typename ProductType::RhsScalar RhsScalar;
490 typedef typename ProductType::Index Index;
491 typedef typename ProductType::ActualLhsType ActualLhsType;
492 typedef typename ProductType::ActualRhsType ActualRhsType;
493 typedef typename ProductType::_ActualRhsType _ActualRhsType;
494 typedef typename ProductType::LhsBlasTraits LhsBlasTraits;
495 typedef typename ProductType::RhsBlasTraits RhsBlasTraits;
500 ResScalar actualAlpha = alpha * LhsBlasTraits::extractScalarFactor(prod.lhs())
501 * RhsBlasTraits::extractScalarFactor(prod.rhs());
506 DirectlyUseRhs = _ActualRhsType::InnerStrideAtCompileTime==1
511 ei_declare_aligned_stack_constructed_variable(RhsScalar,actualRhsPtr,actualRhs.size(),
512 DirectlyUseRhs ?
const_cast<RhsScalar*
>(actualRhs.data()) : static_rhs.data());
516 #ifdef EIGEN_DENSE_STORAGE_CTOR_PLUGIN 517 int size = actualRhs.size();
518 EIGEN_DENSE_STORAGE_CTOR_PLUGIN
524 <Index,LhsScalar,
RowMajor,LhsBlasTraits::NeedToConjugate,RhsScalar,RhsBlasTraits::NeedToConjugate>::run(
525 actualLhs.rows(), actualLhs.cols(),
526 actualLhs.data(), actualLhs.outerStride(),
528 dest.data(), dest.col(0).innerStride(),
535 template<
typename ProductType,
typename Dest>
536 static void run(
const ProductType& prod, Dest& dest,
const typename ProductType::Scalar& alpha)
538 typedef typename Dest::Index Index;
540 const Index
size = prod.rhs().rows();
541 for(Index k=0; k<
size; ++k)
542 dest += (alpha*prod.rhs().coeff(k)) * prod.lhs().col(k);
548 template<
typename ProductType,
typename Dest>
549 static void run(
const ProductType& prod, Dest& dest,
const typename ProductType::Scalar& alpha)
551 typedef typename Dest::Index Index;
553 const Index rows = prod.rows();
554 for(Index i=0; i<rows; ++i)
555 dest.coeffRef(i) += alpha * (prod.lhs().row(i).cwiseProduct(prod.rhs().transpose())).sum();
571 template<
typename Derived>
572 template<
typename OtherDerived>
581 ProductIsValid = Derived::ColsAtCompileTime==
Dynamic 582 || OtherDerived::RowsAtCompileTime==
Dynamic 583 || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime),
584 AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime,
585 SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived)
590 EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),
591 INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)
592 EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),
593 INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
594 EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
595 #ifdef EIGEN_DEBUG_PRODUCT 612 template<
typename Derived>
613 template<
typename OtherDerived>
618 ProductIsValid = Derived::ColsAtCompileTime==
Dynamic 619 || OtherDerived::RowsAtCompileTime==
Dynamic 620 || int(Derived::ColsAtCompileTime)==int(OtherDerived::RowsAtCompileTime),
621 AreVectors = Derived::IsVectorAtCompileTime && OtherDerived::IsVectorAtCompileTime,
622 SameSizes = EIGEN_PREDICATE_SAME_MATRIX_SIZE(Derived,OtherDerived)
627 EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes),
628 INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS)
629 EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors),
630 INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION)
631 EIGEN_STATIC_ASSERT(ProductIsValid || SameSizes, INVALID_MATRIX_PRODUCT)
638 #endif // EIGEN_PRODUCT_H Definition: GeneralProduct.h:322
const LazyProductReturnType< Derived, OtherDerived >::Type lazyProduct(const MatrixBase< OtherDerived > &other) const
Definition: GeneralProduct.h:615
Expression of the product of two general matrices or vectors.
Definition: GeneralProduct.h:36
Definition: GeneralProduct.h:176
Definition: BlasUtil.h:151
Apply transformation on the right.
Definition: Constants.h:279
Definition: GeneralProduct.h:47
A matrix or vector expression mapping an existing array of data.
Definition: Map.h:104
Definition: ProductBase.h:63
Expression of the transpose of a matrix.
Definition: Transpose.h:57
Definition: BlasUtil.h:111
Definition: GeneralProduct.h:45
iterative scaling algorithm to equilibrate rows and column norms in matrices
Definition: TestIMU_Common.h:87
Holds information about the various numeric (i.e.
Definition: NumTraits.h:88
const unsigned int RowMajorBit
for a matrix, this means that the storage order is row-major.
Definition: Constants.h:53
Object is aligned for vectorization.
Definition: Constants.h:194
Definition: XprHelper.h:32
Definition: GenericPacketMath.h:71
detail::size< coerce_list< Ts... >> size
Get the size of a list (number of elements.)
Definition: Size.h:56
Storage order is column major (see TopicStorageOrders).
Definition: Constants.h:264
Definition: GeneralProduct.h:57
Definition: XprHelper.h:371
Definition: CoeffBasedProduct.h:114
Definition: GeneralProduct.h:370
Definition: BlasUtil.h:38
Definition: benchGeometry.cpp:23
Definition: BandTriangularSolver.h:13
Storage order is row major (see TopicStorageOrders).
Definition: Constants.h:266
Definition: XprHelper.h:316
Helper class to get the correct and optimized returned type of operator*.
Definition: GeneralProduct.h:149
Definition: DenseStorage.h:43
const int Dynamic
This value means that a positive quantity (e.g., a size) is not known at compile-time, and that instead the value is stored in some runtime variable.
Definition: Constants.h:21
Base class for all dense matrices, vectors, and expressions.
Definition: MatrixBase.h:48
Definition: ForwardDeclarations.h:17
Apply transformation on the left.
Definition: Constants.h:277
double Scalar
Common scalar type.
Definition: FlexibleKalmanBase.h:48