Eigen  3.3.3
Product.h
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2008-2011 Gael Guennebaud <gael.guennebaud@inria.fr>
00005 //
00006 // This Source Code Form is subject to the terms of the Mozilla
00007 // Public License v. 2.0. If a copy of the MPL was not distributed
00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
00009 
00010 #ifndef EIGEN_PRODUCT_H
00011 #define EIGEN_PRODUCT_H
00012 
00013 namespace Eigen {
00014 
00015 template<typename Lhs, typename Rhs, int Option, typename StorageKind> class ProductImpl;
00016 
00017 namespace internal {
00018 
00019 template<typename Lhs, typename Rhs, int Option>
00020 struct traits<Product<Lhs, Rhs, Option> >
00021 {
00022   typedef typename remove_all<Lhs>::type LhsCleaned;
00023   typedef typename remove_all<Rhs>::type RhsCleaned;
00024   typedef traits<LhsCleaned> LhsTraits;
00025   typedef traits<RhsCleaned> RhsTraits;
00026   
00027   typedef MatrixXpr XprKind;
00028   
00029   typedef typename ScalarBinaryOpTraits<typename traits<LhsCleaned>::Scalar, typename traits<RhsCleaned>::Scalar>::ReturnType Scalar;
00030   typedef typename product_promote_storage_type<typename LhsTraits::StorageKind,
00031                                                 typename RhsTraits::StorageKind,
00032                                                 internal::product_type<Lhs,Rhs>::ret>::ret StorageKind;
00033   typedef typename promote_index_type<typename LhsTraits::StorageIndex,
00034                                       typename RhsTraits::StorageIndex>::type StorageIndex;
00035   
00036   enum {
00037     RowsAtCompileTime    = LhsTraits::RowsAtCompileTime,
00038     ColsAtCompileTime    = RhsTraits::ColsAtCompileTime,
00039     MaxRowsAtCompileTime = LhsTraits::MaxRowsAtCompileTime,
00040     MaxColsAtCompileTime = RhsTraits::MaxColsAtCompileTime,
00041     
00042     // FIXME: only needed by GeneralMatrixMatrixTriangular
00043     InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(LhsTraits::ColsAtCompileTime, RhsTraits::RowsAtCompileTime),
00044     
00045     // The storage order is somewhat arbitrary here. The correct one will be determined through the evaluator.
00046     Flags = (MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1) ? RowMajorBit
00047           : (MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1) ? 0
00048           : (   ((LhsTraits::Flags&NoPreferredStorageOrderBit) && (RhsTraits::Flags&RowMajorBit))
00049              || ((RhsTraits::Flags&NoPreferredStorageOrderBit) && (LhsTraits::Flags&RowMajorBit)) ) ? RowMajorBit
00050           : NoPreferredStorageOrderBit
00051   };
00052 };
00053 
00054 } // end namespace internal
00055 
00070 template<typename _Lhs, typename _Rhs, int Option>
00071 class Product : public ProductImpl<_Lhs,_Rhs,Option,
00072                                    typename internal::product_promote_storage_type<typename internal::traits<_Lhs>::StorageKind,
00073                                                                                    typename internal::traits<_Rhs>::StorageKind,
00074                                                                                    internal::product_type<_Lhs,_Rhs>::ret>::ret>
00075 {
00076   public:
00077     
00078     typedef _Lhs Lhs;
00079     typedef _Rhs Rhs;
00080     
00081     typedef typename ProductImpl<
00082         Lhs, Rhs, Option,
00083         typename internal::product_promote_storage_type<typename internal::traits<Lhs>::StorageKind,
00084                                                         typename internal::traits<Rhs>::StorageKind,
00085                                                         internal::product_type<Lhs,Rhs>::ret>::ret>::Base Base;
00086     EIGEN_GENERIC_PUBLIC_INTERFACE(Product)
00087 
00088     typedef typename internal::ref_selector<Lhs>::type LhsNested;
00089     typedef typename internal::ref_selector<Rhs>::type RhsNested;
00090     typedef typename internal::remove_all<LhsNested>::type LhsNestedCleaned;
00091     typedef typename internal::remove_all<RhsNested>::type RhsNestedCleaned;
00092 
00093     EIGEN_DEVICE_FUNC Product(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs)
00094     {
00095       eigen_assert(lhs.cols() == rhs.rows()
00096         && "invalid matrix product"
00097         && "if you wanted a coeff-wise or a dot product use the respective explicit functions");
00098     }
00099 
00100     EIGEN_DEVICE_FUNC inline Index rows() const { return m_lhs.rows(); }
00101     EIGEN_DEVICE_FUNC inline Index cols() const { return m_rhs.cols(); }
00102 
00103     EIGEN_DEVICE_FUNC const LhsNestedCleaned& lhs() const { return m_lhs; }
00104     EIGEN_DEVICE_FUNC const RhsNestedCleaned& rhs() const { return m_rhs; }
00105 
00106   protected:
00107 
00108     LhsNested m_lhs;
00109     RhsNested m_rhs;
00110 };
00111 
00112 namespace internal {
00113   
00114 template<typename Lhs, typename Rhs, int Option, int ProductTag = internal::product_type<Lhs,Rhs>::ret>
00115 class dense_product_base
00116  : public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
00117 {};
00118 
00120 template<typename Lhs, typename Rhs, int Option>
00121 class dense_product_base<Lhs, Rhs, Option, InnerProduct>
00122  : public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
00123 {
00124   typedef Product<Lhs,Rhs,Option> ProductXpr;
00125   typedef typename internal::dense_xpr_base<ProductXpr>::type Base;
00126 public:
00127   using Base::derived;
00128   typedef typename Base::Scalar Scalar;
00129   
00130   operator const Scalar() const
00131   {
00132     return internal::evaluator<ProductXpr>(derived()).coeff(0,0);
00133   }
00134 };
00135 
00136 } // namespace internal
00137 
00138 // Generic API dispatcher
00139 template<typename Lhs, typename Rhs, int Option, typename StorageKind>
00140 class ProductImpl : public internal::generic_xpr_base<Product<Lhs,Rhs,Option>, MatrixXpr, StorageKind>::type
00141 {
00142   public:
00143     typedef typename internal::generic_xpr_base<Product<Lhs,Rhs,Option>, MatrixXpr, StorageKind>::type Base;
00144 };
00145 
00146 template<typename Lhs, typename Rhs, int Option>
00147 class ProductImpl<Lhs,Rhs,Option,Dense>
00148   : public internal::dense_product_base<Lhs,Rhs,Option>
00149 {
00150     typedef Product<Lhs, Rhs, Option> Derived;
00151     
00152   public:
00153     
00154     typedef typename internal::dense_product_base<Lhs, Rhs, Option> Base;
00155     EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
00156   protected:
00157     enum {
00158       IsOneByOne = (RowsAtCompileTime == 1 || RowsAtCompileTime == Dynamic) && 
00159                    (ColsAtCompileTime == 1 || ColsAtCompileTime == Dynamic),
00160       EnableCoeff = IsOneByOne || Option==LazyProduct
00161     };
00162     
00163   public:
00164   
00165     EIGEN_DEVICE_FUNC Scalar coeff(Index row, Index col) const
00166     {
00167       EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
00168       eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) );
00169       
00170       return internal::evaluator<Derived>(derived()).coeff(row,col);
00171     }
00172 
00173     EIGEN_DEVICE_FUNC Scalar coeff(Index i) const
00174     {
00175       EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
00176       eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) );
00177       
00178       return internal::evaluator<Derived>(derived()).coeff(i);
00179     }
00180     
00181   
00182 };
00183 
00184 } // end namespace Eigen
00185 
00186 #endif // EIGEN_PRODUCT_H
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends