Eigen  3.3.90 (mercurial changeset d63bd3cb7378)
 All Classes Namespaces Functions Variables Typedefs Enumerations Enumerator Friends Groups Pages
Visitor.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra.
3 //
4 // Copyright (C) 2008 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_VISITOR_H
11 #define EIGEN_VISITOR_H
12 
13 namespace Eigen {
14 
15 namespace internal {
16 
17 template<typename Visitor, typename Derived, int UnrollCount>
18 struct visitor_impl
19 {
20  enum {
21  col = (UnrollCount-1) / Derived::RowsAtCompileTime,
22  row = (UnrollCount-1) % Derived::RowsAtCompileTime
23  };
24 
25  EIGEN_DEVICE_FUNC
26  static inline void run(const Derived &mat, Visitor& visitor)
27  {
28  visitor_impl<Visitor, Derived, UnrollCount-1>::run(mat, visitor);
29  visitor(mat.coeff(row, col), row, col);
30  }
31 };
32 
33 template<typename Visitor, typename Derived>
34 struct visitor_impl<Visitor, Derived, 1>
35 {
36  EIGEN_DEVICE_FUNC
37  static inline void run(const Derived &mat, Visitor& visitor)
38  {
39  return visitor.init(mat.coeff(0, 0), 0, 0);
40  }
41 };
42 
43 template<typename Visitor, typename Derived>
44 struct visitor_impl<Visitor, Derived, Dynamic>
45 {
46  EIGEN_DEVICE_FUNC
47  static inline void run(const Derived& mat, Visitor& visitor)
48  {
49  visitor.init(mat.coeff(0,0), 0, 0);
50  for(Index i = 1; i < mat.rows(); ++i)
51  visitor(mat.coeff(i, 0), i, 0);
52  for(Index j = 1; j < mat.cols(); ++j)
53  for(Index i = 0; i < mat.rows(); ++i)
54  visitor(mat.coeff(i, j), i, j);
55  }
56 };
57 
58 // evaluator adaptor
59 template<typename XprType>
60 class visitor_evaluator
61 {
62 public:
63  EIGEN_DEVICE_FUNC
64  explicit visitor_evaluator(const XprType &xpr) : m_evaluator(xpr), m_xpr(xpr) {}
65 
66  typedef typename XprType::Scalar Scalar;
67  typedef typename XprType::CoeffReturnType CoeffReturnType;
68 
69  enum {
70  RowsAtCompileTime = XprType::RowsAtCompileTime,
71  CoeffReadCost = internal::evaluator<XprType>::CoeffReadCost
72  };
73 
74  EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.rows(); }
75  EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.cols(); }
76  EIGEN_DEVICE_FUNC Index size() const { return m_xpr.size(); }
77 
78  EIGEN_DEVICE_FUNC CoeffReturnType coeff(Index row, Index col) const
79  { return m_evaluator.coeff(row, col); }
80 
81 protected:
82  internal::evaluator<XprType> m_evaluator;
83  const XprType &m_xpr;
84 };
85 } // end namespace internal
86 
104 template<typename Derived>
105 template<typename Visitor>
106 EIGEN_DEVICE_FUNC
107 void DenseBase<Derived>::visit(Visitor& visitor) const
108 {
109  typedef typename internal::visitor_evaluator<Derived> ThisEvaluator;
110  ThisEvaluator thisEval(derived());
111 
112  enum {
113  unroll = SizeAtCompileTime != Dynamic
114  && SizeAtCompileTime * ThisEvaluator::CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost <= EIGEN_UNROLLING_LIMIT
115  };
116  return internal::visitor_impl<Visitor, ThisEvaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(thisEval, visitor);
117 }
118 
119 namespace internal {
120 
124 template <typename Derived>
125 struct coeff_visitor
126 {
127  typedef typename Derived::Scalar Scalar;
128  Index row, col;
129  Scalar res;
130  EIGEN_DEVICE_FUNC
131  inline void init(const Scalar& value, Index i, Index j)
132  {
133  res = value;
134  row = i;
135  col = j;
136  }
137 };
138 
144 template <typename Derived>
145 struct min_coeff_visitor : coeff_visitor<Derived>
146 {
147  typedef typename Derived::Scalar Scalar;
148  EIGEN_DEVICE_FUNC
149  void operator() (const Scalar& value, Index i, Index j)
150  {
151  if(value < this->res)
152  {
153  this->res = value;
154  this->row = i;
155  this->col = j;
156  }
157  }
158 };
159 
160 template<typename Scalar>
161 struct functor_traits<min_coeff_visitor<Scalar> > {
162  enum {
164  };
165 };
166 
172 template <typename Derived>
173 struct max_coeff_visitor : coeff_visitor<Derived>
174 {
175  typedef typename Derived::Scalar Scalar;
176  EIGEN_DEVICE_FUNC
177  void operator() (const Scalar& value, Index i, Index j)
178  {
179  if(value > this->res)
180  {
181  this->res = value;
182  this->row = i;
183  this->col = j;
184  }
185  }
186 };
187 
188 template<typename Scalar>
189 struct functor_traits<max_coeff_visitor<Scalar> > {
190  enum {
192  };
193 };
194 
195 } // end namespace internal
196 
203 template<typename Derived>
204 template<typename IndexType>
205 EIGEN_DEVICE_FUNC
206 typename internal::traits<Derived>::Scalar
207 DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
208 {
209  internal::min_coeff_visitor<Derived> minVisitor;
210  this->visit(minVisitor);
211  *rowId = minVisitor.row;
212  if (colId) *colId = minVisitor.col;
213  return minVisitor.res;
214 }
215 
221 template<typename Derived>
222 template<typename IndexType>
223 EIGEN_DEVICE_FUNC
224 typename internal::traits<Derived>::Scalar
225 DenseBase<Derived>::minCoeff(IndexType* index) const
226 {
227  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
228  internal::min_coeff_visitor<Derived> minVisitor;
229  this->visit(minVisitor);
230  *index = IndexType((RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row);
231  return minVisitor.res;
232 }
233 
240 template<typename Derived>
241 template<typename IndexType>
242 EIGEN_DEVICE_FUNC
243 typename internal::traits<Derived>::Scalar
244 DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
245 {
246  internal::max_coeff_visitor<Derived> maxVisitor;
247  this->visit(maxVisitor);
248  *rowPtr = maxVisitor.row;
249  if (colPtr) *colPtr = maxVisitor.col;
250  return maxVisitor.res;
251 }
252 
258 template<typename Derived>
259 template<typename IndexType>
260 EIGEN_DEVICE_FUNC
261 typename internal::traits<Derived>::Scalar
262 DenseBase<Derived>::maxCoeff(IndexType* index) const
263 {
264  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
265  internal::max_coeff_visitor<Derived> maxVisitor;
266  this->visit(maxVisitor);
267  *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
268  return maxVisitor.res;
269 }
270 
271 } // end namespace Eigen
272 
273 #endif // EIGEN_VISITOR_H
internal::traits< Derived >::Scalar Scalar
Definition: DenseBase.h:66
void visit(Visitor &func) const
Definition: Visitor.h:107
internal::traits< Derived >::Scalar maxCoeff() const
Definition: Redux.h:436
Holds information about the various numeric (i.e. scalar) types allowed by Eigen. ...
Definition: NumTraits.h:150
Eigen::Index Index
The interface type of indices.
Definition: EigenBase.h:38
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:33
internal::traits< Derived >::Scalar minCoeff() const
Definition: Redux.h:426
const int Dynamic
Definition: Constants.h:21