Please, help us to better know about our user community by answering the following short survey: https://forms.gle/wpyrxWi18ox9Z5ae9
Eigen  3.4.99 (git rev 199c5f2b47eb1f8e5a2d20e60f07e97cd95a6ba6)
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 // This specialization enables visitors on empty matrices at compile-time
44 template<typename Visitor, typename Derived>
45 struct visitor_impl<Visitor, Derived, 0> {
46  EIGEN_DEVICE_FUNC
47  static inline void run(const Derived &/*mat*/, Visitor& /*visitor*/)
48  {}
49 };
50 
51 template<typename Visitor, typename Derived>
52 struct visitor_impl<Visitor, Derived, Dynamic>
53 {
54  EIGEN_DEVICE_FUNC
55  static inline void run(const Derived& mat, Visitor& visitor)
56  {
57  visitor.init(mat.coeff(0,0), 0, 0);
58  for(Index i = 1; i < mat.rows(); ++i)
59  visitor(mat.coeff(i, 0), i, 0);
60  for(Index j = 1; j < mat.cols(); ++j)
61  for(Index i = 0; i < mat.rows(); ++i)
62  visitor(mat.coeff(i, j), i, j);
63  }
64 };
65 
66 // evaluator adaptor
67 template<typename XprType>
68 class visitor_evaluator
69 {
70 public:
71  EIGEN_DEVICE_FUNC
72  explicit visitor_evaluator(const XprType &xpr) : m_evaluator(xpr), m_xpr(xpr) {}
73 
74  typedef typename XprType::Scalar Scalar;
75  typedef typename XprType::CoeffReturnType CoeffReturnType;
76 
77  enum {
78  RowsAtCompileTime = XprType::RowsAtCompileTime,
79  CoeffReadCost = internal::evaluator<XprType>::CoeffReadCost
80  };
81 
82  EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.rows(); }
83  EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.cols(); }
84  EIGEN_DEVICE_FUNC Index size() const { return m_xpr.size(); }
85 
86  EIGEN_DEVICE_FUNC CoeffReturnType coeff(Index row, Index col) const
87  { return m_evaluator.coeff(row, col); }
88 
89 protected:
90  internal::evaluator<XprType> m_evaluator;
91  const XprType &m_xpr;
92 };
93 } // end namespace internal
94 
114 template<typename Derived>
115 template<typename Visitor>
116 EIGEN_DEVICE_FUNC
117 void DenseBase<Derived>::visit(Visitor& visitor) const
118 {
119  if(size()==0)
120  return;
121 
122  typedef typename internal::visitor_evaluator<Derived> ThisEvaluator;
123  ThisEvaluator thisEval(derived());
124 
125  enum {
126  unroll = SizeAtCompileTime != Dynamic
127  && SizeAtCompileTime * ThisEvaluator::CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost <= EIGEN_UNROLLING_LIMIT
128  };
129  return internal::visitor_impl<Visitor, ThisEvaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(thisEval, visitor);
130 }
131 
132 namespace internal {
133 
137 template <typename Derived>
138 struct coeff_visitor
139 {
140  // default initialization to avoid countless invalid maybe-uninitialized warnings by gcc
141  EIGEN_DEVICE_FUNC
142  coeff_visitor() : row(-1), col(-1), res(0) {}
143  typedef typename Derived::Scalar Scalar;
144  Index row, col;
145  Scalar res;
146  EIGEN_DEVICE_FUNC
147  inline void init(const Scalar& value, Index i, Index j)
148  {
149  res = value;
150  row = i;
151  col = j;
152  }
153 };
154 
160 template <typename Derived>
161 struct min_coeff_visitor : coeff_visitor<Derived>
162 {
163  typedef typename Derived::Scalar Scalar;
164  EIGEN_DEVICE_FUNC
165  void operator() (const Scalar& value, Index i, Index j)
166  {
167  if(value < this->res)
168  {
169  this->res = value;
170  this->row = i;
171  this->col = j;
172  }
173  }
174 };
175 
176 template<typename Scalar>
177 struct functor_traits<min_coeff_visitor<Scalar> > {
178  enum {
179  Cost = NumTraits<Scalar>::AddCost
180  };
181 };
182 
188 template <typename Derived>
189 struct max_coeff_visitor : coeff_visitor<Derived>
190 {
191  typedef typename Derived::Scalar Scalar;
192  EIGEN_DEVICE_FUNC
193  void operator() (const Scalar& value, Index i, Index j)
194  {
195  if(value > this->res)
196  {
197  this->res = value;
198  this->row = i;
199  this->col = j;
200  }
201  }
202 };
203 
204 template<typename Scalar>
205 struct functor_traits<max_coeff_visitor<Scalar> > {
206  enum {
207  Cost = NumTraits<Scalar>::AddCost
208  };
209 };
210 
211 } // end namespace internal
212 
222 template<typename Derived>
223 template<typename IndexType>
224 EIGEN_DEVICE_FUNC
225 typename internal::traits<Derived>::Scalar
226 DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
227 {
228  eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
229 
230  internal::min_coeff_visitor<Derived> minVisitor;
231  this->visit(minVisitor);
232  *rowId = minVisitor.row;
233  if (colId) *colId = minVisitor.col;
234  return minVisitor.res;
235 }
236 
245 template<typename Derived>
246 template<typename IndexType>
247 EIGEN_DEVICE_FUNC
248 typename internal::traits<Derived>::Scalar
249 DenseBase<Derived>::minCoeff(IndexType* index) const
250 {
251  eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
252 
253  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
254  internal::min_coeff_visitor<Derived> minVisitor;
255  this->visit(minVisitor);
256  *index = IndexType((RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row);
257  return minVisitor.res;
258 }
259 
269 template<typename Derived>
270 template<typename IndexType>
271 EIGEN_DEVICE_FUNC
272 typename internal::traits<Derived>::Scalar
273 DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
274 {
275  eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
276 
277  internal::max_coeff_visitor<Derived> maxVisitor;
278  this->visit(maxVisitor);
279  *rowPtr = maxVisitor.row;
280  if (colPtr) *colPtr = maxVisitor.col;
281  return maxVisitor.res;
282 }
283 
292 template<typename Derived>
293 template<typename IndexType>
294 EIGEN_DEVICE_FUNC
295 typename internal::traits<Derived>::Scalar
296 DenseBase<Derived>::maxCoeff(IndexType* index) const
297 {
298  eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
299 
300  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
301  internal::max_coeff_visitor<Derived> maxVisitor;
302  this->visit(maxVisitor);
303  *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
304  return maxVisitor.res;
305 }
306 
307 } // end namespace Eigen
308 
309 #endif // EIGEN_VISITOR_H
internal::traits< Derived >::Scalar minCoeff() const
Definition: Redux.h:431
void visit(Visitor &func) const
Definition: Visitor.h:117
internal::traits< Derived >::Scalar maxCoeff() const
Definition: Redux.h:446
Namespace containing all symbols from the Eigen library.
Definition: Core:134
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74
const int Dynamic
Definition: Constants.h:22