Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2025-01-18 09:56:16

0001 // This file is part of Eigen, a lightweight C++ template library
0002 // for linear algebra.
0003 //
0004 // Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
0005 //
0006 // This Source Code Form is subject to the terms of the Mozilla
0007 // Public License v. 2.0. If a copy of the MPL was not distributed
0008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
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     // FIXME: only needed by GeneralMatrixMatrixTriangular
0043     InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(LhsTraits::ColsAtCompileTime, RhsTraits::RowsAtCompileTime),
0044 
0045     // The storage order is somewhat arbitrary here. The correct one will be determined through the evaluator.
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 } // end namespace internal
0055 
0056 /** \class Product
0057   * \ingroup Core_Module
0058   *
0059   * \brief Expression of the product of two arbitrary matrices or vectors
0060   *
0061   * \tparam _Lhs the type of the left-hand side expression
0062   * \tparam _Rhs the type of the right-hand side expression
0063   *
0064   * This class represents an expression of the product of two arbitrary matrices.
0065   *
0066   * The other template parameters are:
0067   * \tparam Option     can be DefaultProduct, AliasFreeProduct, or LazyProduct
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 /** Conversion to scalar for inner-products */
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 } // namespace internal
0142 
0143 // Generic API dispatcher
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 } // end namespace Eigen
0190 
0191 #endif // EIGEN_PRODUCT_H