source: pacpussensors/trunk/Vislab/lib3dv/eigen/Eigen/src/Core/ProductBase.h@ 136

Last change on this file since 136 was 136, checked in by ldecherf, 7 years ago

Doc

File size: 11.1 KB
Line 
1// This file is part of Eigen, a lightweight C++ template library
2// for linear algebra.
3//
4// Copyright (C) 2009-2010 Gael Guennebaud <gael.guennebaud@inria.fr>
5//
6// This Source Code Form is subject to the terms of the Mozilla
7// Public License v. 2.0. If a copy of the MPL was not distributed
8// with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
9
10#ifndef EIGEN_PRODUCTBASE_H
11#define EIGEN_PRODUCTBASE_H
12
13namespace Eigen {
14
15/** \class ProductBase
16 * \ingroup Core_Module
17 *
18 */
19
20namespace internal {
21template<typename Derived, typename _Lhs, typename _Rhs>
22struct traits<ProductBase<Derived,_Lhs,_Rhs> >
23{
24 typedef MatrixXpr XprKind;
25 typedef typename remove_all<_Lhs>::type Lhs;
26 typedef typename remove_all<_Rhs>::type Rhs;
27 typedef typename scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType Scalar;
28 typedef typename promote_storage_type<typename traits<Lhs>::StorageKind,
29 typename traits<Rhs>::StorageKind>::ret StorageKind;
30 typedef typename promote_index_type<typename traits<Lhs>::Index,
31 typename traits<Rhs>::Index>::type Index;
32 enum {
33 RowsAtCompileTime = traits<Lhs>::RowsAtCompileTime,
34 ColsAtCompileTime = traits<Rhs>::ColsAtCompileTime,
35 MaxRowsAtCompileTime = traits<Lhs>::MaxRowsAtCompileTime,
36 MaxColsAtCompileTime = traits<Rhs>::MaxColsAtCompileTime,
37 Flags = (MaxRowsAtCompileTime==1 ? RowMajorBit : 0)
38 | EvalBeforeNestingBit | EvalBeforeAssigningBit | NestByRefBit,
39 // Note that EvalBeforeNestingBit and NestByRefBit
40 // are not used in practice because nested is overloaded for products
41 CoeffReadCost = 0 // FIXME why is it needed ?
42 };
43};
44}
45
46#define EIGEN_PRODUCT_PUBLIC_INTERFACE(Derived) \
47 typedef ProductBase<Derived, Lhs, Rhs > Base; \
48 EIGEN_DENSE_PUBLIC_INTERFACE(Derived) \
49 typedef typename Base::LhsNested LhsNested; \
50 typedef typename Base::_LhsNested _LhsNested; \
51 typedef typename Base::LhsBlasTraits LhsBlasTraits; \
52 typedef typename Base::ActualLhsType ActualLhsType; \
53 typedef typename Base::_ActualLhsType _ActualLhsType; \
54 typedef typename Base::RhsNested RhsNested; \
55 typedef typename Base::_RhsNested _RhsNested; \
56 typedef typename Base::RhsBlasTraits RhsBlasTraits; \
57 typedef typename Base::ActualRhsType ActualRhsType; \
58 typedef typename Base::_ActualRhsType _ActualRhsType; \
59 using Base::m_lhs; \
60 using Base::m_rhs;
61
62template<typename Derived, typename Lhs, typename Rhs>
63class ProductBase : public MatrixBase<Derived>
64{
65 public:
66 typedef MatrixBase<Derived> Base;
67 EIGEN_DENSE_PUBLIC_INTERFACE(ProductBase)
68
69 typedef typename Lhs::Nested LhsNested;
70 typedef typename internal::remove_all<LhsNested>::type _LhsNested;
71 typedef internal::blas_traits<_LhsNested> LhsBlasTraits;
72 typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType;
73 typedef typename internal::remove_all<ActualLhsType>::type _ActualLhsType;
74 typedef typename internal::traits<Lhs>::Scalar LhsScalar;
75
76 typedef typename Rhs::Nested RhsNested;
77 typedef typename internal::remove_all<RhsNested>::type _RhsNested;
78 typedef internal::blas_traits<_RhsNested> RhsBlasTraits;
79 typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType;
80 typedef typename internal::remove_all<ActualRhsType>::type _ActualRhsType;
81 typedef typename internal::traits<Rhs>::Scalar RhsScalar;
82
83 // Diagonal of a product: no need to evaluate the arguments because they are going to be evaluated only once
84 typedef CoeffBasedProduct<LhsNested, RhsNested, 0> FullyLazyCoeffBaseProductType;
85
86 public:
87
88#ifndef EIGEN_NO_MALLOC
89 typedef typename Base::PlainObject BasePlainObject;
90 typedef Matrix<Scalar,RowsAtCompileTime==1?1:Dynamic,ColsAtCompileTime==1?1:Dynamic,BasePlainObject::Options> DynPlainObject;
91 typedef typename internal::conditional<(BasePlainObject::SizeAtCompileTime==Dynamic) || (BasePlainObject::SizeAtCompileTime*int(sizeof(Scalar)) < int(EIGEN_STACK_ALLOCATION_LIMIT)),
92 BasePlainObject, DynPlainObject>::type PlainObject;
93#else
94 typedef typename Base::PlainObject PlainObject;
95#endif
96
97 ProductBase(const Lhs& a_lhs, const Rhs& a_rhs)
98 : m_lhs(a_lhs), m_rhs(a_rhs)
99 {
100 eigen_assert(a_lhs.cols() == a_rhs.rows()
101 && "invalid matrix product"
102 && "if you wanted a coeff-wise or a dot product use the respective explicit functions");
103 }
104
105 inline Index rows() const { return m_lhs.rows(); }
106 inline Index cols() const { return m_rhs.cols(); }
107
108 template<typename Dest>
109 inline void evalTo(Dest& dst) const { dst.setZero(); scaleAndAddTo(dst,Scalar(1)); }
110
111 template<typename Dest>
112 inline void addTo(Dest& dst) const { scaleAndAddTo(dst,Scalar(1)); }
113
114 template<typename Dest>
115 inline void subTo(Dest& dst) const { scaleAndAddTo(dst,Scalar(-1)); }
116
117 template<typename Dest>
118 inline void scaleAndAddTo(Dest& dst, const Scalar& alpha) const { derived().scaleAndAddTo(dst,alpha); }
119
120 const _LhsNested& lhs() const { return m_lhs; }
121 const _RhsNested& rhs() const { return m_rhs; }
122
123 // Implicit conversion to the nested type (trigger the evaluation of the product)
124 operator const PlainObject& () const
125 {
126 m_result.resize(m_lhs.rows(), m_rhs.cols());
127 derived().evalTo(m_result);
128 return m_result;
129 }
130
131 const Diagonal<const FullyLazyCoeffBaseProductType,0> diagonal() const
132 { return FullyLazyCoeffBaseProductType(m_lhs, m_rhs); }
133
134 template<int Index>
135 const Diagonal<FullyLazyCoeffBaseProductType,Index> diagonal() const
136 { return FullyLazyCoeffBaseProductType(m_lhs, m_rhs); }
137
138 const Diagonal<FullyLazyCoeffBaseProductType,Dynamic> diagonal(Index index) const
139 { return FullyLazyCoeffBaseProductType(m_lhs, m_rhs).diagonal(index); }
140
141 // restrict coeff accessors to 1x1 expressions. No need to care about mutators here since this isnt a Lvalue expression
142 typename Base::CoeffReturnType coeff(Index row, Index col) const
143 {
144#ifdef EIGEN2_SUPPORT
145 return lhs().row(row).cwiseProduct(rhs().col(col).transpose()).sum();
146#else
147 EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
148 eigen_assert(this->rows() == 1 && this->cols() == 1);
149 Matrix<Scalar,1,1> result = *this;
150 return result.coeff(row,col);
151#endif
152 }
153
154 typename Base::CoeffReturnType coeff(Index i) const
155 {
156 EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
157 eigen_assert(this->rows() == 1 && this->cols() == 1);
158 Matrix<Scalar,1,1> result = *this;
159 return result.coeff(i);
160 }
161
162 const Scalar& coeffRef(Index row, Index col) const
163 {
164 EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
165 eigen_assert(this->rows() == 1 && this->cols() == 1);
166 return derived().coeffRef(row,col);
167 }
168
169 const Scalar& coeffRef(Index i) const
170 {
171 EIGEN_STATIC_ASSERT_SIZE_1x1(Derived)
172 eigen_assert(this->rows() == 1 && this->cols() == 1);
173 return derived().coeffRef(i);
174 }
175
176 protected:
177
178 LhsNested m_lhs;
179 RhsNested m_rhs;
180
181 mutable PlainObject m_result;
182};
183
184// here we need to overload the nested rule for products
185// such that the nested type is a const reference to a plain matrix
186namespace internal {
187template<typename Lhs, typename Rhs, int Mode, int N, typename PlainObject>
188struct nested<GeneralProduct<Lhs,Rhs,Mode>, N, PlainObject>
189{
190 typedef typename GeneralProduct<Lhs,Rhs,Mode>::PlainObject const& type;
191};
192template<typename Lhs, typename Rhs, int Mode, int N, typename PlainObject>
193struct nested<const GeneralProduct<Lhs,Rhs,Mode>, N, PlainObject>
194{
195 typedef typename GeneralProduct<Lhs,Rhs,Mode>::PlainObject const& type;
196};
197}
198
199template<typename NestedProduct>
200class ScaledProduct;
201
202// Note that these two operator* functions are not defined as member
203// functions of ProductBase, because, otherwise we would have to
204// define all overloads defined in MatrixBase. Furthermore, Using
205// "using Base::operator*" would not work with MSVC.
206//
207// Also note that here we accept any compatible scalar types
208template<typename Derived,typename Lhs,typename Rhs>
209const ScaledProduct<Derived>
210operator*(const ProductBase<Derived,Lhs,Rhs>& prod, const typename Derived::Scalar& x)
211{ return ScaledProduct<Derived>(prod.derived(), x); }
212
213template<typename Derived,typename Lhs,typename Rhs>
214typename internal::enable_if<!internal::is_same<typename Derived::Scalar,typename Derived::RealScalar>::value,
215 const ScaledProduct<Derived> >::type
216operator*(const ProductBase<Derived,Lhs,Rhs>& prod, const typename Derived::RealScalar& x)
217{ return ScaledProduct<Derived>(prod.derived(), x); }
218
219
220template<typename Derived,typename Lhs,typename Rhs>
221const ScaledProduct<Derived>
222operator*(const typename Derived::Scalar& x,const ProductBase<Derived,Lhs,Rhs>& prod)
223{ return ScaledProduct<Derived>(prod.derived(), x); }
224
225template<typename Derived,typename Lhs,typename Rhs>
226typename internal::enable_if<!internal::is_same<typename Derived::Scalar,typename Derived::RealScalar>::value,
227 const ScaledProduct<Derived> >::type
228operator*(const typename Derived::RealScalar& x,const ProductBase<Derived,Lhs,Rhs>& prod)
229{ return ScaledProduct<Derived>(prod.derived(), x); }
230
231namespace internal {
232template<typename NestedProduct>
233struct traits<ScaledProduct<NestedProduct> >
234 : traits<ProductBase<ScaledProduct<NestedProduct>,
235 typename NestedProduct::_LhsNested,
236 typename NestedProduct::_RhsNested> >
237{
238 typedef typename traits<NestedProduct>::StorageKind StorageKind;
239};
240}
241
242template<typename NestedProduct>
243class ScaledProduct
244 : public ProductBase<ScaledProduct<NestedProduct>,
245 typename NestedProduct::_LhsNested,
246 typename NestedProduct::_RhsNested>
247{
248 public:
249 typedef ProductBase<ScaledProduct<NestedProduct>,
250 typename NestedProduct::_LhsNested,
251 typename NestedProduct::_RhsNested> Base;
252 typedef typename Base::Scalar Scalar;
253 typedef typename Base::PlainObject PlainObject;
254// EIGEN_PRODUCT_PUBLIC_INTERFACE(ScaledProduct)
255
256 ScaledProduct(const NestedProduct& prod, const Scalar& x)
257 : Base(prod.lhs(),prod.rhs()), m_prod(prod), m_alpha(x) {}
258
259 template<typename Dest>
260 inline void evalTo(Dest& dst) const { dst.setZero(); scaleAndAddTo(dst, Scalar(1)); }
261
262 template<typename Dest>
263 inline void addTo(Dest& dst) const { scaleAndAddTo(dst, Scalar(1)); }
264
265 template<typename Dest>
266 inline void subTo(Dest& dst) const { scaleAndAddTo(dst, Scalar(-1)); }
267
268 template<typename Dest>
269 inline void scaleAndAddTo(Dest& dst, const Scalar& a_alpha) const { m_prod.derived().scaleAndAddTo(dst,a_alpha * m_alpha); }
270
271 const Scalar& alpha() const { return m_alpha; }
272
273 protected:
274 const NestedProduct& m_prod;
275 Scalar m_alpha;
276};
277
278/** \internal
279 * Overloaded to perform an efficient C = (A*B).lazy() */
280template<typename Derived>
281template<typename ProductDerived, typename Lhs, typename Rhs>
282Derived& MatrixBase<Derived>::lazyAssign(const ProductBase<ProductDerived, Lhs,Rhs>& other)
283{
284 other.derived().evalTo(derived());
285 return derived();
286}
287
288} // end namespace Eigen
289
290#endif // EIGEN_PRODUCTBASE_H
Note: See TracBrowser for help on using the repository browser.