Eigen  3.2.91
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 { unroll = SizeAtCompileTime != Dynamic
113  && ThisEvaluator::CoeffReadCost != Dynamic
114  && (SizeAtCompileTime == 1 || internal::functor_traits<Visitor>::Cost != Dynamic)
115  && SizeAtCompileTime * ThisEvaluator::CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost
116  <= EIGEN_UNROLLING_LIMIT };
117  return internal::visitor_impl<Visitor, ThisEvaluator,
118  unroll ? int(SizeAtCompileTime) : Dynamic
119  >::run(thisEval, visitor);
120 }
121 
122 namespace internal {
123 
127 template <typename Derived>
128 struct coeff_visitor
129 {
130  typedef typename Derived::Scalar Scalar;
131  Index row, col;
132  Scalar res;
133  EIGEN_DEVICE_FUNC
134  inline void init(const Scalar& value, Index i, Index j)
135  {
136  res = value;
137  row = i;
138  col = j;
139  }
140 };
141 
147 template <typename Derived>
148 struct min_coeff_visitor : coeff_visitor<Derived>
149 {
150  typedef typename Derived::Scalar Scalar;
151  EIGEN_DEVICE_FUNC
152  void operator() (const Scalar& value, Index i, Index j)
153  {
154  if(value < this->res)
155  {
156  this->res = value;
157  this->row = i;
158  this->col = j;
159  }
160  }
161 };
162 
163 template<typename Scalar>
164 struct functor_traits<min_coeff_visitor<Scalar> > {
165  enum {
166  Cost = NumTraits<Scalar>::AddCost
167  };
168 };
169 
175 template <typename Derived>
176 struct max_coeff_visitor : coeff_visitor<Derived>
177 {
178  typedef typename Derived::Scalar Scalar;
179  EIGEN_DEVICE_FUNC
180  void operator() (const Scalar& value, Index i, Index j)
181  {
182  if(value > this->res)
183  {
184  this->res = value;
185  this->row = i;
186  this->col = j;
187  }
188  }
189 };
190 
191 template<typename Scalar>
192 struct functor_traits<max_coeff_visitor<Scalar> > {
193  enum {
194  Cost = NumTraits<Scalar>::AddCost
195  };
196 };
197 
198 } // end namespace internal
199 
205 template<typename Derived>
206 template<typename IndexType>
207 EIGEN_DEVICE_FUNC
208 typename internal::traits<Derived>::Scalar
209 DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
210 {
211  internal::min_coeff_visitor<Derived> minVisitor;
212  this->visit(minVisitor);
213  *rowId = minVisitor.row;
214  if (colId) *colId = minVisitor.col;
215  return minVisitor.res;
216 }
217 
223 template<typename Derived>
224 template<typename IndexType>
225 EIGEN_DEVICE_FUNC
226 typename internal::traits<Derived>::Scalar
227 DenseBase<Derived>::minCoeff(IndexType* index) const
228 {
229  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
230  internal::min_coeff_visitor<Derived> minVisitor;
231  this->visit(minVisitor);
232  *index = IndexType((RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row);
233  return minVisitor.res;
234 }
235 
241 template<typename Derived>
242 template<typename IndexType>
243 EIGEN_DEVICE_FUNC
244 typename internal::traits<Derived>::Scalar
245 DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
246 {
247  internal::max_coeff_visitor<Derived> maxVisitor;
248  this->visit(maxVisitor);
249  *rowPtr = maxVisitor.row;
250  if (colPtr) *colPtr = maxVisitor.col;
251  return maxVisitor.res;
252 }
253 
259 template<typename Derived>
260 template<typename IndexType>
261 EIGEN_DEVICE_FUNC
262 typename internal::traits<Derived>::Scalar
263 DenseBase<Derived>::maxCoeff(IndexType* index) const
264 {
265  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
266  internal::max_coeff_visitor<Derived> maxVisitor;
267  this->visit(maxVisitor);
268  *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
269  return maxVisitor.res;
270 }
271 
272 } // end namespace Eigen
273 
274 #endif // EIGEN_VISITOR_H
Definition: LDLT.h:16
void visit(Visitor &func) const
Definition: Visitor.h:107
internal::traits< Derived >::Scalar maxCoeff() const
Definition: Redux.h:449
internal::traits< Derived >::Scalar minCoeff() const
Definition: Redux.h:439
Definition: Eigen_Colamd.h:54