Eigen  3.2.7
 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 <[email protected]>
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  static inline void run(const Derived &mat, Visitor& visitor)
26  {
27  visitor_impl<Visitor, Derived, UnrollCount-1>::run(mat, visitor);
28  visitor(mat.coeff(row, col), row, col);
29  }
30 };
31 
32 template<typename Visitor, typename Derived>
33 struct visitor_impl<Visitor, Derived, 1>
34 {
35  static inline void run(const Derived &mat, Visitor& visitor)
36  {
37  return visitor.init(mat.coeff(0, 0), 0, 0);
38  }
39 };
40 
41 template<typename Visitor, typename Derived>
42 struct visitor_impl<Visitor, Derived, Dynamic>
43 {
44  typedef typename Derived::Index Index;
45  static inline void run(const Derived& mat, Visitor& visitor)
46  {
47  visitor.init(mat.coeff(0,0), 0, 0);
48  for(Index i = 1; i < mat.rows(); ++i)
49  visitor(mat.coeff(i, 0), i, 0);
50  for(Index j = 1; j < mat.cols(); ++j)
51  for(Index i = 0; i < mat.rows(); ++i)
52  visitor(mat.coeff(i, j), i, j);
53  }
54 };
55 
56 } // end namespace internal
57 
75 template<typename Derived>
76 template<typename Visitor>
77 void DenseBase<Derived>::visit(Visitor& visitor) const
78 {
79  typedef typename internal::remove_all<typename Derived::Nested>::type ThisNested;
80  typename Derived::Nested thisNested(derived());
81 
82  enum { unroll = SizeAtCompileTime != Dynamic
83  && CoeffReadCost != Dynamic
84  && (SizeAtCompileTime == 1 || internal::functor_traits<Visitor>::Cost != Dynamic)
85  && SizeAtCompileTime * CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost
86  <= EIGEN_UNROLLING_LIMIT };
87  return internal::visitor_impl<Visitor, ThisNested,
88  unroll ? int(SizeAtCompileTime) : Dynamic
89  >::run(thisNested, visitor);
90 }
91 
92 namespace internal {
93 
97 template <typename Derived>
98 struct coeff_visitor
99 {
100  typedef typename Derived::Index Index;
101  typedef typename Derived::Scalar Scalar;
102  Index row, col;
103  Scalar res;
104  inline void init(const Scalar& value, Index i, Index j)
105  {
106  res = value;
107  row = i;
108  col = j;
109  }
110 };
111 
117 template <typename Derived>
118 struct min_coeff_visitor : coeff_visitor<Derived>
119 {
120  typedef typename Derived::Index Index;
121  typedef typename Derived::Scalar Scalar;
122  void operator() (const Scalar& value, Index i, Index j)
123  {
124  if(value < this->res)
125  {
126  this->res = value;
127  this->row = i;
128  this->col = j;
129  }
130  }
131 };
132 
133 template<typename Scalar>
134 struct functor_traits<min_coeff_visitor<Scalar> > {
135  enum {
136  Cost = NumTraits<Scalar>::AddCost
137  };
138 };
139 
145 template <typename Derived>
146 struct max_coeff_visitor : coeff_visitor<Derived>
147 {
148  typedef typename Derived::Index Index;
149  typedef typename Derived::Scalar Scalar;
150  void operator() (const Scalar& value, Index i, Index j)
151  {
152  if(value > this->res)
153  {
154  this->res = value;
155  this->row = i;
156  this->col = j;
157  }
158  }
159 };
160 
161 template<typename Scalar>
162 struct functor_traits<max_coeff_visitor<Scalar> > {
163  enum {
164  Cost = NumTraits<Scalar>::AddCost
165  };
166 };
167 
168 } // end namespace internal
169 
175 template<typename Derived>
176 template<typename IndexType>
177 typename internal::traits<Derived>::Scalar
178 DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
179 {
180  internal::min_coeff_visitor<Derived> minVisitor;
181  this->visit(minVisitor);
182  *rowId = minVisitor.row;
183  if (colId) *colId = minVisitor.col;
184  return minVisitor.res;
185 }
186 
192 template<typename Derived>
193 template<typename IndexType>
194 typename internal::traits<Derived>::Scalar
195 DenseBase<Derived>::minCoeff(IndexType* index) const
196 {
197  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
198  internal::min_coeff_visitor<Derived> minVisitor;
199  this->visit(minVisitor);
200  *index = (RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row;
201  return minVisitor.res;
202 }
203 
209 template<typename Derived>
210 template<typename IndexType>
211 typename internal::traits<Derived>::Scalar
212 DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
213 {
214  internal::max_coeff_visitor<Derived> maxVisitor;
215  this->visit(maxVisitor);
216  *rowPtr = maxVisitor.row;
217  if (colPtr) *colPtr = maxVisitor.col;
218  return maxVisitor.res;
219 }
220 
226 template<typename Derived>
227 template<typename IndexType>
228 typename internal::traits<Derived>::Scalar
229 DenseBase<Derived>::maxCoeff(IndexType* index) const
230 {
231  EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
232  internal::max_coeff_visitor<Derived> maxVisitor;
233  this->visit(maxVisitor);
234  *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
235  return maxVisitor.res;
236 }
237 
238 } // end namespace Eigen
239 
240 #endif // EIGEN_VISITOR_H
internal::traits< Derived >::Scalar minCoeff() const
Definition: Redux.h:339
void visit(Visitor &func) const
Definition: Visitor.h:77
const int Dynamic
Definition: Constants.h:21
internal::traits< Derived >::Scalar maxCoeff() const
Definition: Redux.h:349