MOAB  4.9.3pre
Product.h
Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2008-2011 Gael Guennebaud <[email protected]>
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 // Determine the scalar of Product<Lhs, Rhs>. This is normally the same as Lhs::Scalar times
00020 // Rhs::Scalar, but product with permutation matrices inherit the scalar of the other factor.
00021 template<typename Lhs, typename Rhs, typename LhsShape = typename evaluator_traits<Lhs>::Shape, 
00022          typename RhsShape = typename evaluator_traits<Rhs>::Shape >
00023 struct product_result_scalar
00024 {
00025   typedef typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType Scalar;
00026 };
00027 
00028 template<typename Lhs, typename Rhs, typename RhsShape>
00029 struct product_result_scalar<Lhs, Rhs, PermutationShape, RhsShape>
00030 {
00031   typedef typename Rhs::Scalar Scalar;
00032 };
00033 
00034 template<typename Lhs, typename Rhs, typename LhsShape>
00035   struct product_result_scalar<Lhs, Rhs, LhsShape, PermutationShape>
00036 {
00037   typedef typename Lhs::Scalar Scalar;
00038 };
00039 
00040 template<typename Lhs, typename Rhs, typename RhsShape>
00041 struct product_result_scalar<Lhs, Rhs, TranspositionsShape, RhsShape>
00042 {
00043   typedef typename Rhs::Scalar Scalar;
00044 };
00045 
00046 template<typename Lhs, typename Rhs, typename LhsShape>
00047   struct product_result_scalar<Lhs, Rhs, LhsShape, TranspositionsShape>
00048 {
00049   typedef typename Lhs::Scalar Scalar;
00050 };
00051 
00052 template<typename Lhs, typename Rhs, int Option>
00053 struct traits<Product<Lhs, Rhs, Option> >
00054 {
00055   typedef typename remove_all<Lhs>::type LhsCleaned;
00056   typedef typename remove_all<Rhs>::type RhsCleaned;
00057   typedef traits<LhsCleaned> LhsTraits;
00058   typedef traits<RhsCleaned> RhsTraits;
00059   
00060   typedef MatrixXpr XprKind;
00061   
00062   typedef typename product_result_scalar<LhsCleaned,RhsCleaned>::Scalar Scalar;
00063   typedef typename product_promote_storage_type<typename LhsTraits::StorageKind,
00064                                                 typename RhsTraits::StorageKind,
00065                                                 internal::product_type<Lhs,Rhs>::ret>::ret StorageKind;
00066   typedef typename promote_index_type<typename LhsTraits::StorageIndex,
00067                                       typename RhsTraits::StorageIndex>::type StorageIndex;
00068   
00069   enum {
00070     RowsAtCompileTime    = LhsTraits::RowsAtCompileTime,
00071     ColsAtCompileTime    = RhsTraits::ColsAtCompileTime,
00072     MaxRowsAtCompileTime = LhsTraits::MaxRowsAtCompileTime,
00073     MaxColsAtCompileTime = RhsTraits::MaxColsAtCompileTime,
00074     
00075     // FIXME: only needed by GeneralMatrixMatrixTriangular
00076     InnerSize = EIGEN_SIZE_MIN_PREFER_FIXED(LhsTraits::ColsAtCompileTime, RhsTraits::RowsAtCompileTime),
00077     
00078     // The storage order is somewhat arbitrary here. The correct one will be determined through the evaluator.
00079     Flags = (MaxRowsAtCompileTime==1 && MaxColsAtCompileTime!=1) ? RowMajorBit
00080           : (MaxColsAtCompileTime==1 && MaxRowsAtCompileTime!=1) ? 0
00081           : (   ((LhsTraits::Flags&NoPreferredStorageOrderBit) && (RhsTraits::Flags&RowMajorBit))
00082              || ((RhsTraits::Flags&NoPreferredStorageOrderBit) && (LhsTraits::Flags&RowMajorBit)) ) ? RowMajorBit
00083           : NoPreferredStorageOrderBit
00084   };
00085 };
00086 
00087 } // end namespace internal
00088 
00103 template<typename _Lhs, typename _Rhs, int Option>
00104 class Product : public ProductImpl<_Lhs,_Rhs,Option,
00105                                    typename internal::product_promote_storage_type<typename internal::traits<_Lhs>::StorageKind,
00106                                                                                    typename internal::traits<_Rhs>::StorageKind,
00107                                                                                    internal::product_type<_Lhs,_Rhs>::ret>::ret>
00108 {
00109   public:
00110     
00111     typedef _Lhs Lhs;
00112     typedef _Rhs Rhs;
00113     
00114     typedef typename ProductImpl<
00115         Lhs, Rhs, Option,
00116         typename internal::product_promote_storage_type<typename internal::traits<Lhs>::StorageKind,
00117                                                         typename internal::traits<Rhs>::StorageKind,
00118                                                         internal::product_type<Lhs,Rhs>::ret>::ret>::Base Base;
00119     EIGEN_GENERIC_PUBLIC_INTERFACE(Product)
00120 
00121     typedef typename internal::ref_selector<Lhs>::type LhsNested;
00122     typedef typename internal::ref_selector<Rhs>::type RhsNested;
00123     typedef typename internal::remove_all<LhsNested>::type LhsNestedCleaned;
00124     typedef typename internal::remove_all<RhsNested>::type RhsNestedCleaned;
00125 
00126     EIGEN_DEVICE_FUNC Product(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs)
00127     {
00128       eigen_assert(lhs.cols() == rhs.rows()
00129         && "invalid matrix product"
00130         && "if you wanted a coeff-wise or a dot product use the respective explicit functions");
00131     }
00132 
00133     EIGEN_DEVICE_FUNC inline Index rows() const { return m_lhs.rows(); }
00134     EIGEN_DEVICE_FUNC inline Index cols() const { return m_rhs.cols(); }
00135 
00136     EIGEN_DEVICE_FUNC const LhsNestedCleaned& lhs() const { return m_lhs; }
00137     EIGEN_DEVICE_FUNC const RhsNestedCleaned& rhs() const { return m_rhs; }
00138 
00139   protected:
00140 
00141     LhsNested m_lhs;
00142     RhsNested m_rhs;
00143 };
00144 
00145 namespace internal {
00146   
00147 template<typename Lhs, typename Rhs, int Option, int ProductTag = internal::product_type<Lhs,Rhs>::ret>
00148 class dense_product_base
00149  : public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
00150 {};
00151 
00153 template<typename Lhs, typename Rhs, int Option>
00154 class dense_product_base<Lhs, Rhs, Option, InnerProduct>
00155  : public internal::dense_xpr_base<Product<Lhs,Rhs,Option> >::type
00156 {
00157   typedef Product<Lhs,Rhs,Option> ProductXpr;
00158   typedef typename internal::dense_xpr_base<ProductXpr>::type Base;
00159 public:
00160   using Base::derived;
00161   typedef typename Base::Scalar Scalar;
00162   
00163   operator const Scalar() const
00164   {
00165     return internal::evaluator<ProductXpr>(derived()).coeff(0,0);
00166   }
00167 };
00168 
00169 } // namespace internal
00170 
00171 // Generic API dispatcher
00172 template<typename Lhs, typename Rhs, int Option, typename StorageKind>
00173 class ProductImpl : public internal::generic_xpr_base<Product<Lhs,Rhs,Option>, MatrixXpr, StorageKind>::type
00174 {
00175   public:
00176     typedef typename internal::generic_xpr_base<Product<Lhs,Rhs,Option>, MatrixXpr, StorageKind>::type Base;
00177 };
00178 
00179 template<typename Lhs, typename Rhs, int Option>
00180 class ProductImpl<Lhs,Rhs,Option,Dense>
00181   : public internal::dense_product_base<Lhs,Rhs,Option>
00182 {
00183     typedef Product<Lhs, Rhs, Option> Derived;
00184     
00185   public:
00186     
00187     typedef typename internal::dense_product_base<Lhs, Rhs, Option> Base;
00188     EIGEN_DENSE_PUBLIC_INTERFACE(Derived)
00189   protected:
00190     enum {
00191       IsOneByOne = (RowsAtCompileTime == 1 || RowsAtCompileTime == Dynamic) && 
00192                    (ColsAtCompileTime == 1 || ColsAtCompileTime == Dynamic),
00193       EnableCoeff = IsOneByOne || Option==LazyProduct
00194     };
00195     
00196   public:
00197   
00198     EIGEN_DEVICE_FUNC Scalar coeff(Index row, Index col) const
00199     {
00200       EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
00201       eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) );
00202       
00203       return internal::evaluator<Derived>(derived()).coeff(row,col);
00204     }
00205 
00206     EIGEN_DEVICE_FUNC Scalar coeff(Index i) const
00207     {
00208       EIGEN_STATIC_ASSERT(EnableCoeff, THIS_METHOD_IS_ONLY_FOR_INNER_OR_LAZY_PRODUCTS);
00209       eigen_assert( (Option==LazyProduct) || (this->rows() == 1 && this->cols() == 1) );
00210       
00211       return internal::evaluator<Derived>(derived()).coeff(i);
00212     }
00213     
00214   
00215 };
00216 
00217 } // end namespace Eigen
00218 
00219 #endif // EIGEN_PRODUCT_H
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines