File indexing completed on 2025-01-18 09:56:16
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef EIGEN_PRODUCT_H
0011 #define EIGEN_PRODUCT_H
0012
0013 namespace Eigen {
0014
0015 template<typename Lhs, typename Rhs, int Option, typename StorageKind> class ProductImpl;
0016
0017 namespace internal {
0018
0019 template<typename Lhs, typename Rhs, int Option>
0020 struct traits<Product<Lhs, Rhs, Option> >
0021 {
0022 typedef typename remove_all<Lhs>::type LhsCleaned;
0023 typedef typename remove_all<Rhs>::type RhsCleaned;
0024 typedef traits<LhsCleaned> LhsTraits;
0025 typedef traits<RhsCleaned> RhsTraits;
0026
0027 typedef MatrixXpr XprKind;
0028
0029 typedef typename ScalarBinaryOpTraits<typename traits<LhsCleaned>::Scalar, typename traits<RhsCleaned>::Scalar>::ReturnType Scalar;
0030 typedef typename product_promote_storage_type<typename LhsTraits::StorageKind,
0031 typename RhsTraits::StorageKind,
0032 internal::product_type<Lhs,Rhs>::ret>::ret StorageKind;
0033 typedef typename promote_index_type<typename LhsTraits::StorageIndex,
0034 typename RhsTraits::StorageIndex>::type StorageIndex;
0035
0036 enum {
0037 RowsAtCompileTime = LhsTraits::RowsAtCompileTime,
0038 ColsAtCompileTime = RhsTraits::ColsAtCompileTime,
0039 MaxRowsAtCompileTime = LhsTraits::MaxRowsAtCompileTime,
0040 MaxColsAtCompileTime = RhsTraits::MaxColsAtCompileTime,
0041
0042
0043 InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(LhsTraits::ColsAtCompileTime, RhsTraits::RowsAtCompileTime),
0044
0045
0046 Flags = (MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1) ? RowMajorBit
0047 : (MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1) ? 0
0048 : ( ((LhsTraits::Flags&NoPreferredStorageOrderBit) && (RhsTraits::Flags&RowMajorBit))
0049 || ((RhsTraits::Flags&NoPreferredStorageOrderBit) && (LhsTraits::Flags&RowMajorBit)) ) ? RowMajorBit
0050 : NoPreferredStorageOrderBit
0051 };
0052 };
0053
0054 }
0055
0056
0057
0058
0059
0060
0061
0062
0063
0064
0065
0066
0067
0068
0069
0070 template<typename _Lhs, typename _Rhs, int Option>
0071 class Product : public ProductImpl<_Lhs,_Rhs,Option,
0072 typename internal::product_promote_storage_type<typename internal::traits<_Lhs>::StorageKind,
0073 typename internal::traits<_Rhs>::StorageKind,
0074 internal::product_type<_Lhs,_Rhs>::ret>::ret>
0075 {
0076 public:
0077
0078 typedef _Lhs Lhs;
0079 typedef _Rhs Rhs;
0080
0081 typedef typename ProductImpl<
0082 Lhs, Rhs, Option,
0083 typename internal::product_promote_storage_type<typename internal::traits<Lhs>::StorageKind,
0084 typename internal::traits<Rhs>::StorageKind,
0085 internal::product_type<Lhs,Rhs>::ret>::ret>::Base Base;
0086 EIGEN_GENERIC_PUBLIC_INTERFACE(Product)
0087
0088 typedef typename internal::ref_selector<Lhs>::type LhsNested;
0089 typedef typename internal::ref_selector<Rhs>::type RhsNested;
0090 typedef typename internal::remove_all<LhsNested>::type LhsNestedCleaned;
0091 typedef typename internal::remove_all<RhsNested>::type RhsNestedCleaned;
0092
0093 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0094 Product(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs)
0095 {
0096 eigen_assert(lhs.cols() == rhs.rows()
0097 && "invalid matrix product"
0098 && "if you wanted a coeff-wise or a dot product use the respective explicit functions");
0099 }
0100
0101 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
0102 Index rows() const EIGEN_NOEXCEPT { return m_lhs.rows(); }
0103 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE EIGEN_CONSTEXPR
0104 Index cols() const EIGEN_NOEXCEPT { return m_rhs.cols(); }
0105
0106 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0107 const LhsNestedCleaned& lhs() const { return m_lhs; }
0108 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE
0109 const RhsNestedCleaned& rhs() const { return m_rhs; }
0110
0111 protected:
0112
0113 LhsNested m_lhs;
0114 RhsNested m_rhs;
0115 };
0116
0117 namespace internal {
0118
0119 template<typename Lhs, typename Rhs, int Option, int ProductTag = internal::product_type<Lhs,Rhs>::ret>
0120 class dense_product_base
0121 : public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
0122 {};
0123
0124
0125 template<typename Lhs, typename Rhs, int Option>
0126 class dense_product_base<Lhs, Rhs, Option, InnerProduct>
0127 : public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
0128 {
0129 typedef Product<Lhs,Rhs,Option> ProductXpr;
0130 typedef typename internal::dense_xpr_base<ProductXpr>::type Base;
0131 public:
0132 using Base::derived;
0133 typedef typename Base::Scalar Scalar;
0134
0135 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE operator const Scalar() const
0136 {
0137 return internal::evaluator<ProductXpr>(derived()).coeff(0,0);
0138 }
0139 };
0140
0141 }
0142
0143
0144 template<typename Lhs, typename Rhs, int Option, typename StorageKind>
0145 class ProductImpl : public internal::generic_xpr_base<Product<Lhs,Rhs,Option>, MatrixXpr, StorageKind>::type
0146 {
0147 public:
0148 typedef typename internal::generic_xpr_base<Product<Lhs,Rhs,Option>, MatrixXpr, StorageKind>::type Base;
0149 };
0150
0151 template<typename Lhs, typename Rhs, int Option>
0152 class ProductImpl<Lhs,Rhs,Option,Dense>
0153 : public internal::dense_product_base<Lhs,Rhs,Option>
0154 {
0155 typedef Product<Lhs, Rhs, Option> Derived;
0156
0157 public:
0158
0159 typedef typename internal::dense_product_base<Lhs, Rhs, Option> Base;
0160 EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
0161 protected:
0162 enum {
0163 IsOneByOne = (RowsAtCompileTime == 1 || RowsAtCompileTime == Dynamic) &&
0164 (ColsAtCompileTime == 1 || ColsAtCompileTime == Dynamic),
0165 EnableCoeff = IsOneByOne || Option==LazyProduct
0166 };
0167
0168 public:
0169
0170 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index row, Index col) const
0171 {
0172 EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
0173 eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) );
0174
0175 return internal::evaluator<Derived>(derived()).coeff(row,col);
0176 }
0177
0178 EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE Scalar coeff(Index i) const
0179 {
0180 EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
0181 eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) );
0182
0183 return internal::evaluator<Derived>(derived()).coeff(i);
0184 }
0185
0186
0187 };
0188
0189 }
0190
0191 #endif