WPILibC++ 2023.4.3-108-ge5452e3
Visitor.h
Go to the documentation of this file.
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>
19{
20 enum {
21 col = (UnrollCount-1) / Derived::RowsAtCompileTime,
22 row = (UnrollCount-1) % Derived::RowsAtCompileTime
23 };
24
26 static inline void run(const Derived &mat, Visitor& visitor)
27 {
29 visitor(mat.coeff(row, col), row, col);
30 }
31};
32
33template<typename Visitor, typename Derived>
34struct visitor_impl<Visitor, Derived, 1>
35{
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
44template<typename Visitor, typename Derived>
45struct visitor_impl<Visitor, Derived, 0> {
47 static inline void run(const Derived &/*mat*/, Visitor& /*visitor*/)
48 {}
49};
50
51template<typename Visitor, typename Derived>
52struct visitor_impl<Visitor, Derived, Dynamic>
53{
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
67template<typename XprType>
69{
70public:
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,
80 };
81
85
87 { return m_evaluator.coeff(row, col); }
88
89protected:
91 const XprType &m_xpr;
92};
93} // end namespace internal
94
95/** Applies the visitor \a visitor to the whole coefficients of the matrix or vector.
96 *
97 * The template parameter \a Visitor is the type of the visitor and provides the following interface:
98 * \code
99 * struct MyVisitor {
100 * // called for the first coefficient
101 * void init(const Scalar& value, Index i, Index j);
102 * // called for all other coefficients
103 * void operator() (const Scalar& value, Index i, Index j);
104 * };
105 * \endcode
106 *
107 * \note compared to one or two \em for \em loops, visitors offer automatic
108 * unrolling for small fixed size matrix.
109 *
110 * \note if the matrix is empty, then the visitor is left unchanged.
111 *
112 * \sa minCoeff(Index*,Index*), maxCoeff(Index*,Index*), DenseBase::redux()
113 */
114template<typename Derived>
115template<typename Visitor>
117void 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 * int(ThisEvaluator::CoeffReadCost) + (SizeAtCompileTime-1) * int(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
132namespace internal {
133
134/** \internal
135 * \brief Base class to implement min and max visitors
136 */
137template <typename Derived>
139{
140 // default initialization to avoid countless invalid maybe-uninitialized warnings by gcc
142 coeff_visitor() : row(-1), col(-1), res(0) {}
143 typedef typename Derived::Scalar Scalar;
147 inline void init(const Scalar& value, Index i, Index j)
148 {
149 res = value;
150 row = i;
151 col = j;
152 }
153};
154
155/** \internal
156 * \brief Visitor computing the min coefficient with its value and coordinates
157 *
158 * \sa DenseBase::minCoeff(Index*, Index*)
159 */
160template <typename Derived, int NaNPropagation>
162{
163 typedef typename Derived::Scalar Scalar;
165 void operator() (const Scalar& value, Index i, Index j)
166 {
168 {
169 this->res = value;
170 this->row = i;
171 this->col = j;
172 }
173 }
174};
175
176template <typename Derived>
178{
179 typedef typename Derived::Scalar Scalar;
181 void operator() (const Scalar& value, Index i, Index j)
182 {
183 if((numext::isnan)(this->res) || (!(numext::isnan)(value) && value < this->res))
184 {
185 this->res = value;
186 this->row = i;
187 this->col = j;
188 }
189 }
190};
191
192template <typename Derived>
194{
195 typedef typename Derived::Scalar Scalar;
197 void operator() (const Scalar& value, Index i, Index j)
198 {
200 {
201 this->res = value;
202 this->row = i;
203 this->col = j;
204 }
205 }
206};
207
208template<typename Scalar, int NaNPropagation>
209 struct functor_traits<min_coeff_visitor<Scalar, NaNPropagation> > {
210 enum {
212 };
213};
214
215/** \internal
216 * \brief Visitor computing the max coefficient with its value and coordinates
217 *
218 * \sa DenseBase::maxCoeff(Index*, Index*)
219 */
220template <typename Derived, int NaNPropagation>
222{
223 typedef typename Derived::Scalar Scalar;
225 void operator() (const Scalar& value, Index i, Index j)
226 {
227 if(value > this->res)
228 {
229 this->res = value;
230 this->row = i;
231 this->col = j;
232 }
233 }
234};
235
236template <typename Derived>
238{
239 typedef typename Derived::Scalar Scalar;
241 void operator() (const Scalar& value, Index i, Index j)
242 {
243 if((numext::isnan)(this->res) || (!(numext::isnan)(value) && value > this->res))
244 {
245 this->res = value;
246 this->row = i;
247 this->col = j;
248 }
249 }
250};
251
252template <typename Derived>
254{
255 typedef typename Derived::Scalar Scalar;
257 void operator() (const Scalar& value, Index i, Index j)
258 {
259 if((numext::isnan)(value) || value > this->res)
260 {
261 this->res = value;
262 this->row = i;
263 this->col = j;
264 }
265 }
266};
267
268template<typename Scalar, int NaNPropagation>
269struct functor_traits<max_coeff_visitor<Scalar, NaNPropagation> > {
270 enum {
272 };
273};
274
275} // end namespace internal
276
277/** \fn DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
278 * \returns the minimum of all coefficients of *this and puts in *row and *col its location.
279 *
280 * In case \c *this contains NaN, NaNPropagation determines the behavior:
281 * NaNPropagation == PropagateFast : undefined
282 * NaNPropagation == PropagateNaN : result is NaN
283 * NaNPropagation == PropagateNumbers : result is maximum of elements that are not NaN
284 * \warning the matrix must be not empty, otherwise an assertion is triggered.
285 *
286 * \sa DenseBase::minCoeff(Index*), DenseBase::maxCoeff(Index*,Index*), DenseBase::visit(), DenseBase::minCoeff()
287 */
288template<typename Derived>
289template<int NaNPropagation, typename IndexType>
291typename internal::traits<Derived>::Scalar
292DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
293{
294 eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
295
297 this->visit(minVisitor);
298 *rowId = minVisitor.row;
299 if (colId) *colId = minVisitor.col;
300 return minVisitor.res;
301}
302
303/** \returns the minimum of all coefficients of *this and puts in *index its location.
304 *
305 * In case \c *this contains NaN, NaNPropagation determines the behavior:
306 * NaNPropagation == PropagateFast : undefined
307 * NaNPropagation == PropagateNaN : result is NaN
308 * NaNPropagation == PropagateNumbers : result is maximum of elements that are not NaN
309 * \warning the matrix must be not empty, otherwise an assertion is triggered.
310 *
311 * \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::visit(), DenseBase::minCoeff()
312 */
313template<typename Derived>
314template<int NaNPropagation, typename IndexType>
317DenseBase<Derived>::minCoeff(IndexType* index) const
318{
319 eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
320
323 this->visit(minVisitor);
324 *index = IndexType((RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row);
325 return minVisitor.res;
326}
327
328/** \fn DenseBase<Derived>::maxCoeff(IndexType* rowId, IndexType* colId) const
329 * \returns the maximum of all coefficients of *this and puts in *row and *col its location.
330 *
331 * In case \c *this contains NaN, NaNPropagation determines the behavior:
332 * NaNPropagation == PropagateFast : undefined
333 * NaNPropagation == PropagateNaN : result is NaN
334 * NaNPropagation == PropagateNumbers : result is maximum of elements that are not NaN
335 * \warning the matrix must be not empty, otherwise an assertion is triggered.
336 *
337 * \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visit(), DenseBase::maxCoeff()
338 */
339template<typename Derived>
340template<int NaNPropagation, typename IndexType>
343DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
344{
345 eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
346
348 this->visit(maxVisitor);
349 *rowPtr = maxVisitor.row;
350 if (colPtr) *colPtr = maxVisitor.col;
351 return maxVisitor.res;
352}
353
354/** \returns the maximum of all coefficients of *this and puts in *index its location.
355 *
356 * In case \c *this contains NaN, NaNPropagation determines the behavior:
357 * NaNPropagation == PropagateFast : undefined
358 * NaNPropagation == PropagateNaN : result is NaN
359 * NaNPropagation == PropagateNumbers : result is maximum of elements that are not NaN
360 * \warning the matrix must be not empty, otherwise an assertion is triggered.
361 *
362 * \sa DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::maxCoeff()
363 */
364template<typename Derived>
365template<int NaNPropagation, typename IndexType>
368DenseBase<Derived>::maxCoeff(IndexType* index) const
369{
370 eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
371
374 this->visit(maxVisitor);
375 *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
376 return maxVisitor.res;
377}
378
379} // end namespace Eigen
380
381#endif // EIGEN_VISITOR_H
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE ColXpr col(Index i)
This is the const version of col().
Definition: BlockMethods.h:1097
EIGEN_DEVICE_FUNC EIGEN_STRONG_INLINE RowXpr row(Index i)
This is the const version of row(). *‍/.
Definition: BlockMethods.h:1118
#define EIGEN_NOEXCEPT
Definition: Macros.h:1428
#define EIGEN_CONSTEXPR
Definition: Macros.h:797
#define EIGEN_DEVICE_FUNC
Definition: Macros.h:986
#define eigen_assert(x)
Definition: Macros.h:1047
#define EIGEN_UNROLLING_LIMIT
Defines the maximal loop size to enable meta unrolling of loops.
Definition: Settings.h:24
#define EIGEN_STATIC_ASSERT_VECTOR_ONLY(TYPE)
Definition: StaticAssert.h:142
EIGEN_DEVICE_FUNC internal::traits< Derived >::Scalar minCoeff() const
EIGEN_DEVICE_FUNC void visit(Visitor &func) const
Applies the visitor visitor to the whole coefficients of the matrix or vector.
Definition: Visitor.h:117
EIGEN_DEVICE_FUNC internal::traits< Derived >::Scalar maxCoeff() const
Definition: Visitor.h:69
@ CoeffReadCost
Definition: Visitor.h:79
@ RowsAtCompileTime
Definition: Visitor.h:78
XprType::Scalar Scalar
Definition: Visitor.h:74
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index size() const EIGEN_NOEXCEPT
Definition: Visitor.h:84
EIGEN_DEVICE_FUNC visitor_evaluator(const XprType &xpr)
Definition: Visitor.h:72
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT
Definition: Visitor.h:82
internal::evaluator< XprType > m_evaluator
Definition: Visitor.h:90
EIGEN_DEVICE_FUNC CoeffReturnType coeff(Index row, Index col) const
Definition: Visitor.h:86
const XprType & m_xpr
Definition: Visitor.h:91
EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT
Definition: Visitor.h:83
XprType::CoeffReturnType CoeffReturnType
Definition: Visitor.h:75
Definition: core.h:1240
@ PropagateNaN
Always propagate NaNs.
Definition: Constants.h:343
@ PropagateNumbers
Always propagate not-NaNs.
Definition: Constants.h:345
EIGEN_CONSTEXPR Index size(const T &x)
Definition: Meta.h:479
EIGEN_DEVICE_FUNC EIGEN_ALWAYS_INLINE bool() isnan(const Eigen::bfloat16 &h)
Definition: BFloat16.h:659
Namespace containing all symbols from the Eigen library.
Definition: Core:141
EIGEN_DEFAULT_DENSE_INDEX_TYPE Index
The Index type as used for the API.
Definition: Meta.h:74
const int Dynamic
This value means that a positive quantity (e.g., a size) is not known at compile-time,...
Definition: Constants.h:22
Definition: Eigen_Colamd.h:50
Holds information about the various numeric (i.e.
Definition: NumTraits.h:233
Definition: Visitor.h:139
EIGEN_DEVICE_FUNC void init(const Scalar &value, Index i, Index j)
Definition: Visitor.h:147
EIGEN_DEVICE_FUNC coeff_visitor()
Definition: Visitor.h:142
Scalar res
Definition: Visitor.h:145
Index col
Definition: Visitor.h:144
Index row
Definition: Visitor.h:144
Derived::Scalar Scalar
Definition: Visitor.h:143
Definition: CoreEvaluators.h:91
Definition: XprHelper.h:176
@ Cost
Definition: XprHelper.h:179
Derived::Scalar Scalar
Definition: Visitor.h:255
Definition: Visitor.h:222
Derived::Scalar Scalar
Definition: Visitor.h:223
EIGEN_DEVICE_FUNC void operator()(const Scalar &value, Index i, Index j)
Definition: Visitor.h:225
Derived::Scalar Scalar
Definition: Visitor.h:195
Definition: Visitor.h:162
Derived::Scalar Scalar
Definition: Visitor.h:163
EIGEN_DEVICE_FUNC void operator()(const Scalar &value, Index i, Index j)
Definition: Visitor.h:165
Definition: ForwardDeclarations.h:17
static EIGEN_DEVICE_FUNC void run(const Derived &, Visitor &)
Definition: Visitor.h:47
static EIGEN_DEVICE_FUNC void run(const Derived &mat, Visitor &visitor)
Definition: Visitor.h:37
static EIGEN_DEVICE_FUNC void run(const Derived &mat, Visitor &visitor)
Definition: Visitor.h:55
Definition: Visitor.h:19
static EIGEN_DEVICE_FUNC void run(const Derived &mat, Visitor &visitor)
Definition: Visitor.h:26
@ col
Definition: Visitor.h:21
@ row
Definition: Visitor.h:22