00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef EIGEN_PRODUCTBASE_H
00026 #define EIGEN_PRODUCTBASE_H
00027
00033 namespace internal {
00034 template<typename Derived, typename _Lhs, typename _Rhs>
00035 struct traits<ProductBase<Derived,_Lhs,_Rhs> >
00036 {
00037 typedef MatrixXpr XprKind;
00038 typedef typename remove_all<_Lhs>::type Lhs;
00039 typedef typename remove_all<_Rhs>::type Rhs;
00040 typedef typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType Scalar;
00041 typedef typename promote_storage_type<typename traits<Lhs>::StorageKind,
00042 typename traits<Rhs>::StorageKind>::ret StorageKind;
00043 typedef typename promote_index_type<typename traits<Lhs>::Index,
00044 typename traits<Rhs>::Index>::type Index;
00045 enum {
00046 RowsAtCompileTime = traits<Lhs>::RowsAtCompileTime,
00047 ColsAtCompileTime = traits<Rhs>::ColsAtCompileTime,
00048 MaxRowsAtCompileTime = traits<Lhs>::MaxRowsAtCompileTime,
00049 MaxColsAtCompileTime = traits<Rhs>::MaxColsAtCompileTime,
00050 Flags = (MaxRowsAtCompileTime==1 ? RowMajorBit : 0)
00051 | EvalBeforeNestingBit | EvalBeforeAssigningBit | NestByRefBit,
00052
00053
00054 CoeffReadCost = 0
00055 };
00056 };
00057 }
00058
00059 #define EIGEN_PRODUCT_PUBLIC_INTERFACE(Derived) \
00060 typedef ProductBase<Derived, Lhs, Rhs > Base; \
00061 EIGEN_DENSE_PUBLIC_INTERFACE(Derived) \
00062 typedef typename Base::LhsNested LhsNested; \
00063 typedef typename Base::_LhsNested _LhsNested; \
00064 typedef typename Base::LhsBlasTraits LhsBlasTraits; \
00065 typedef typename Base::ActualLhsType ActualLhsType; \
00066 typedef typename Base::_ActualLhsType _ActualLhsType; \
00067 typedef typename Base::RhsNested RhsNested; \
00068 typedef typename Base::_RhsNested _RhsNested; \
00069 typedef typename Base::RhsBlasTraits RhsBlasTraits; \
00070 typedef typename Base::ActualRhsType ActualRhsType; \
00071 typedef typename Base::_ActualRhsType _ActualRhsType; \
00072 using Base::m_lhs; \
00073 using Base::m_rhs;
00074
00075 template<typename Derived, typename Lhs, typename Rhs>
00076 class ProductBase : public MatrixBase<Derived>
00077 {
00078 public:
00079 typedef MatrixBase<Derived> Base;
00080 EIGEN_DENSE_PUBLIC_INTERFACE(ProductBase)
00081
00082 typedef typename Lhs::Nested LhsNested;
00083 typedef typename internal::remove_all<LhsNested>::type _LhsNested;
00084 typedef internal::blas_traits<_LhsNested> LhsBlasTraits;
00085 typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType;
00086 typedef typename internal::remove_all<ActualLhsType>::type _ActualLhsType;
00087 typedef typename internal::traits<Lhs>::Scalar LhsScalar;
00088
00089 typedef typename Rhs::Nested RhsNested;
00090 typedef typename internal::remove_all<RhsNested>::type _RhsNested;
00091 typedef internal::blas_traits<_RhsNested> RhsBlasTraits;
00092 typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType;
00093 typedef typename internal::remove_all<ActualRhsType>::type _ActualRhsType;
00094 typedef typename internal::traits<Rhs>::Scalar RhsScalar;
00095
00096
00097 typedef CoeffBasedProduct<LhsNested, RhsNested, 0> FullyLazyCoeffBaseProductType;
00098
00099 public:
00100
00101 typedef typename Base::PlainObject PlainObject;
00102
00103 ProductBase(const Lhs& lhs, const Rhs& rhs)
00104 : m_lhs(lhs), m_rhs(rhs)
00105 {
00106 eigen_assert(lhs.cols() == rhs.rows()
00107 && "invalid matrix product"
00108 && "if you wanted a coeff-wise or a dot product use the respective explicit functions");
00109 }
00110
00111 inline Index rows() const { return m_lhs.rows(); }
00112 inline Index cols() const { return m_rhs.cols(); }
00113
00114 template<typename Dest>
00115 inline void evalTo(Dest& dst) const { dst.setZero(); scaleAndAddTo(dst,Scalar(1)); }
00116
00117 template<typename Dest>
00118 inline void addTo(Dest& dst) const { scaleAndAddTo(dst,1); }
00119
00120 template<typename Dest>
00121 inline void subTo(Dest& dst) const { scaleAndAddTo(dst,-1); }
00122
00123 template<typename Dest>
00124 inline void scaleAndAddTo(Dest& dst,Scalar alpha) const { derived().scaleAndAddTo(dst,alpha); }
00125
00126 const _LhsNested& lhs() const { return m_lhs; }
00127 const _RhsNested& rhs() const { return m_rhs; }
00128
00129
00130 operator const PlainObject& () const
00131 {
00132 m_result.resize(m_lhs.rows(), m_rhs.cols());
00133 derived().evalTo(m_result);
00134 return m_result;
00135 }
00136
00137 const Diagonal<const FullyLazyCoeffBaseProductType,0> diagonal() const
00138 { return FullyLazyCoeffBaseProductType(m_lhs, m_rhs); }
00139
00140 template<int Index>
00141 const Diagonal<FullyLazyCoeffBaseProductType,Index> diagonal() const
00142 { return FullyLazyCoeffBaseProductType(m_lhs, m_rhs); }
00143
00144 const Diagonal<FullyLazyCoeffBaseProductType,Dynamic> diagonal(Index index) const
00145 { return FullyLazyCoeffBaseProductType(m_lhs, m_rhs).diagonal(index); }
00146
00147
00148 typename Base::CoeffReturnType coeff(Index row, Index col) const
00149 {
00150 #ifdef EIGEN2_SUPPORT
00151 return lhs().row(row).cwiseProduct(rhs().col(col).transpose()).sum();
00152 #else
00153 EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
00154 eigen_assert(this->rows() == 1 && this->cols() == 1);
00155 return derived().coeff(row,col);
00156 #endif
00157 }
00158
00159 typename Base::CoeffReturnType coeff(Index i) const
00160 {
00161 EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
00162 eigen_assert(this->rows() == 1 && this->cols() == 1);
00163 return derived().coeff(i);
00164 }
00165
00166 const Scalar& coeffRef(Index row, Index col) const
00167 {
00168 EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
00169 eigen_assert(this->rows() == 1 && this->cols() == 1);
00170 return derived().coeffRef(row,col);
00171 }
00172
00173 const Scalar& coeffRef(Index i) const
00174 {
00175 EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
00176 eigen_assert(this->rows() == 1 && this->cols() == 1);
00177 return derived().coeffRef(i);
00178 }
00179
00180 protected:
00181
00182 const LhsNested m_lhs;
00183 const RhsNested m_rhs;
00184
00185 mutable PlainObject m_result;
00186 };
00187
00188
00189
00190 namespace internal {
00191 template<typename Lhs, typename Rhs, int Mode, int N, typename PlainObject>
00192 struct nested<GeneralProduct<Lhs,Rhs,Mode>, N, PlainObject>
00193 {
00194 typedef PlainObject const& type;
00195 };
00196 }
00197
00198 template<typename NestedProduct>
00199 class ScaledProduct;
00200
00201
00202
00203
00204
00205
00206
00207 template<typename Derived,typename Lhs,typename Rhs>
00208 const ScaledProduct<Derived>
00209 operator*(const ProductBase<Derived,Lhs,Rhs>& prod, typename Derived::Scalar x)
00210 { return ScaledProduct<Derived>(prod.derived(), x); }
00211
00212 template<typename Derived,typename Lhs,typename Rhs>
00213 typename internal::enable_if<!internal::is_same<typename Derived::Scalar,typename Derived::RealScalar>::value,
00214 const ScaledProduct<Derived> >::type
00215 operator*(const ProductBase<Derived,Lhs,Rhs>& prod, typename Derived::RealScalar x)
00216 { return ScaledProduct<Derived>(prod.derived(), x); }
00217
00218
00219 template<typename Derived,typename Lhs,typename Rhs>
00220 const ScaledProduct<Derived>
00221 operator*(typename Derived::Scalar x,const ProductBase<Derived,Lhs,Rhs>& prod)
00222 { return ScaledProduct<Derived>(prod.derived(), x); }
00223
00224 template<typename Derived,typename Lhs,typename Rhs>
00225 typename internal::enable_if<!internal::is_same<typename Derived::Scalar,typename Derived::RealScalar>::value,
00226 const ScaledProduct<Derived> >::type
00227 operator*(typename Derived::RealScalar x,const ProductBase<Derived,Lhs,Rhs>& prod)
00228 { return ScaledProduct<Derived>(prod.derived(), x); }
00229
00230 namespace internal {
00231 template<typename NestedProduct>
00232 struct traits<ScaledProduct<NestedProduct> >
00233 : traits<ProductBase<ScaledProduct<NestedProduct>,
00234 typename NestedProduct::_LhsNested,
00235 typename NestedProduct::_RhsNested> >
00236 {
00237 typedef typename traits<NestedProduct>::StorageKind StorageKind;
00238 };
00239 }
00240
00241 template<typename NestedProduct>
00242 class ScaledProduct
00243 : public ProductBase<ScaledProduct<NestedProduct>,
00244 typename NestedProduct::_LhsNested,
00245 typename NestedProduct::_RhsNested>
00246 {
00247 public:
00248 typedef ProductBase<ScaledProduct<NestedProduct>,
00249 typename NestedProduct::_LhsNested,
00250 typename NestedProduct::_RhsNested> Base;
00251 typedef typename Base::Scalar Scalar;
00252 typedef typename Base::PlainObject PlainObject;
00253
00254
00255 ScaledProduct(const NestedProduct& prod, Scalar x)
00256 : Base(prod.lhs(),prod.rhs()), m_prod(prod), m_alpha(x) {}
00257
00258 template<typename Dest>
00259 inline void evalTo(Dest& dst) const { dst.setZero(); scaleAndAddTo(dst,m_alpha); }
00260
00261 template<typename Dest>
00262 inline void addTo(Dest& dst) const { scaleAndAddTo(dst,m_alpha); }
00263
00264 template<typename Dest>
00265 inline void subTo(Dest& dst) const { scaleAndAddTo(dst,-m_alpha); }
00266
00267 template<typename Dest>
00268 inline void scaleAndAddTo(Dest& dst,Scalar alpha) const { m_prod.derived().scaleAndAddTo(dst,alpha); }
00269
00270 const Scalar& alpha() const { return m_alpha; }
00271
00272 protected:
00273 const NestedProduct& m_prod;
00274 Scalar m_alpha;
00275 };
00276
00279 template<typename Derived>
00280 template<typename ProductDerived, typename Lhs, typename Rhs>
00281 Derived& MatrixBase<Derived>::lazyAssign(const ProductBase<ProductDerived, Lhs,Rhs>& other)
00282 {
00283 other.derived().evalTo(derived());
00284 return derived();
00285 }
00286
00287
00288 #endif // EIGEN_PRODUCTBASE_H