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

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

Doc

File size: 7.1 KB
Line 
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
13namespace Eigen {
14
15namespace internal {
16
17template<typename Visitor, typename Derived, int UnrollCount>
18struct 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
32template<typename Visitor, typename Derived>
33struct 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
41template<typename Visitor, typename Derived>
42struct 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
58/** Applies the visitor \a visitor to the whole coefficients of the matrix or vector.
59 *
60 * The template parameter \a Visitor is the type of the visitor and provides the following interface:
61 * \code
62 * struct MyVisitor {
63 * // called for the first coefficient
64 * void init(const Scalar& value, Index i, Index j);
65 * // called for all other coefficients
66 * void operator() (const Scalar& value, Index i, Index j);
67 * };
68 * \endcode
69 *
70 * \note compared to one or two \em for \em loops, visitors offer automatic
71 * unrolling for small fixed size matrix.
72 *
73 * \sa minCoeff(Index*,Index*), maxCoeff(Index*,Index*), DenseBase::redux()
74 */
75template<typename Derived>
76template<typename Visitor>
77void 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
92namespace internal {
93
94/** \internal
95 * \brief Base class to implement min and max visitors
96 */
97template <typename Derived>
98struct 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
112/** \internal
113 * \brief Visitor computing the min coefficient with its value and coordinates
114 *
115 * \sa DenseBase::minCoeff(Index*, Index*)
116 */
117template <typename Derived>
118struct 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
133template<typename Scalar>
134struct functor_traits<min_coeff_visitor<Scalar> > {
135 enum {
136 Cost = NumTraits<Scalar>::AddCost
137 };
138};
139
140/** \internal
141 * \brief Visitor computing the max coefficient with its value and coordinates
142 *
143 * \sa DenseBase::maxCoeff(Index*, Index*)
144 */
145template <typename Derived>
146struct 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
161template<typename Scalar>
162struct functor_traits<max_coeff_visitor<Scalar> > {
163 enum {
164 Cost = NumTraits<Scalar>::AddCost
165 };
166};
167
168} // end namespace internal
169
170/** \returns the minimum of all coefficients of *this and puts in *row and *col its location.
171 * \warning the result is undefined if \c *this contains NaN.
172 *
173 * \sa DenseBase::minCoeff(Index*), DenseBase::maxCoeff(Index*,Index*), DenseBase::visitor(), DenseBase::minCoeff()
174 */
175template<typename Derived>
176template<typename IndexType>
177typename internal::traits<Derived>::Scalar
178DenseBase<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
187/** \returns the minimum of all coefficients of *this and puts in *index its location.
188 * \warning the result is undefined if \c *this contains NaN.
189 *
190 * \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::minCoeff()
191 */
192template<typename Derived>
193template<typename IndexType>
194typename internal::traits<Derived>::Scalar
195DenseBase<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
204/** \returns the maximum of all coefficients of *this and puts in *row and *col its location.
205 * \warning the result is undefined if \c *this contains NaN.
206 *
207 * \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::maxCoeff()
208 */
209template<typename Derived>
210template<typename IndexType>
211typename internal::traits<Derived>::Scalar
212DenseBase<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
221/** \returns the maximum of all coefficients of *this and puts in *index its location.
222 * \warning the result is undefined if \c *this contains NaN.
223 *
224 * \sa DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::maxCoeff()
225 */
226template<typename Derived>
227template<typename IndexType>
228typename internal::traits<Derived>::Scalar
229DenseBase<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
Note: See TracBrowser for help on using the repository browser.