File indexing completed on 2025-01-18 09:56:19
0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #ifndef EIGEN_VISITOR_H
0011 #define EIGEN_VISITOR_H
0012
0013 namespace Eigen {
0014
0015 namespace internal {
0016
0017 template<typename Visitor, typename Derived, int UnrollCount>
0018 struct visitor_impl
0019 {
0020 enum {
0021 col = (UnrollCount-1) / Derived::RowsAtCompileTime,
0022 row = (UnrollCount-1) % Derived::RowsAtCompileTime
0023 };
0024
0025 EIGEN_DEVICE_FUNC
0026 static inline void run(const Derived &mat, Visitor& visitor)
0027 {
0028 visitor_impl<Visitor, Derived, UnrollCount-1>::run(mat, visitor);
0029 visitor(mat.coeff(row, col), row, col);
0030 }
0031 };
0032
0033 template<typename Visitor, typename Derived>
0034 struct visitor_impl<Visitor, Derived, 1>
0035 {
0036 EIGEN_DEVICE_FUNC
0037 static inline void run(const Derived &mat, Visitor& visitor)
0038 {
0039 return visitor.init(mat.coeff(0, 0), 0, 0);
0040 }
0041 };
0042
0043
0044 template<typename Visitor, typename Derived>
0045 struct visitor_impl<Visitor, Derived, 0> {
0046 EIGEN_DEVICE_FUNC
0047 static inline void run(const Derived &, Visitor& )
0048 {}
0049 };
0050
0051 template<typename Visitor, typename Derived>
0052 struct visitor_impl<Visitor, Derived, Dynamic>
0053 {
0054 EIGEN_DEVICE_FUNC
0055 static inline void run(const Derived& mat, Visitor& visitor)
0056 {
0057 visitor.init(mat.coeff(0,0), 0, 0);
0058 for(Index i = 1; i < mat.rows(); ++i)
0059 visitor(mat.coeff(i, 0), i, 0);
0060 for(Index j = 1; j < mat.cols(); ++j)
0061 for(Index i = 0; i < mat.rows(); ++i)
0062 visitor(mat.coeff(i, j), i, j);
0063 }
0064 };
0065
0066
0067 template<typename XprType>
0068 class visitor_evaluator
0069 {
0070 public:
0071 EIGEN_DEVICE_FUNC
0072 explicit visitor_evaluator(const XprType &xpr) : m_evaluator(xpr), m_xpr(xpr) {}
0073
0074 typedef typename XprType::Scalar Scalar;
0075 typedef typename XprType::CoeffReturnType CoeffReturnType;
0076
0077 enum {
0078 RowsAtCompileTime = XprType::RowsAtCompileTime,
0079 CoeffReadCost = internal::evaluator<XprType>::CoeffReadCost
0080 };
0081
0082 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index rows() const EIGEN_NOEXCEPT { return m_xpr.rows(); }
0083 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index cols() const EIGEN_NOEXCEPT { return m_xpr.cols(); }
0084 EIGEN_DEVICE_FUNC EIGEN_CONSTEXPR Index size() const EIGEN_NOEXCEPT { return m_xpr.size(); }
0085
0086 EIGEN_DEVICE_FUNC CoeffReturnType coeff(Index row, Index col) const
0087 { return m_evaluator.coeff(row, col); }
0088
0089 protected:
0090 internal::evaluator<XprType> m_evaluator;
0091 const XprType &m_xpr;
0092 };
0093 }
0094
0095
0096
0097
0098
0099
0100
0101
0102
0103
0104
0105
0106
0107
0108
0109
0110
0111
0112
0113
0114 template<typename Derived>
0115 template<typename Visitor>
0116 EIGEN_DEVICE_FUNC
0117 void DenseBase<Derived>::visit(Visitor& visitor) const
0118 {
0119 if(size()==0)
0120 return;
0121
0122 typedef typename internal::visitor_evaluator<Derived> ThisEvaluator;
0123 ThisEvaluator thisEval(derived());
0124
0125 enum {
0126 unroll = SizeAtCompileTime != Dynamic
0127 && SizeAtCompileTime * int(ThisEvaluator::CoeffReadCost) + (SizeAtCompileTime-1) * int(internal::functor_traits<Visitor>::Cost) <= EIGEN_UNROLLING_LIMIT
0128 };
0129 return internal::visitor_impl<Visitor, ThisEvaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(thisEval, visitor);
0130 }
0131
0132 namespace internal {
0133
0134
0135
0136
0137 template <typename Derived>
0138 struct coeff_visitor
0139 {
0140
0141 EIGEN_DEVICE_FUNC
0142 coeff_visitor() : row(-1), col(-1), res(0) {}
0143 typedef typename Derived::Scalar Scalar;
0144 Index row, col;
0145 Scalar res;
0146 EIGEN_DEVICE_FUNC
0147 inline void init(const Scalar& value, Index i, Index j)
0148 {
0149 res = value;
0150 row = i;
0151 col = j;
0152 }
0153 };
0154
0155
0156
0157
0158
0159
0160 template <typename Derived, int NaNPropagation>
0161 struct min_coeff_visitor : coeff_visitor<Derived>
0162 {
0163 typedef typename Derived::Scalar Scalar;
0164 EIGEN_DEVICE_FUNC
0165 void operator() (const Scalar& value, Index i, Index j)
0166 {
0167 if(value < this->res)
0168 {
0169 this->res = value;
0170 this->row = i;
0171 this->col = j;
0172 }
0173 }
0174 };
0175
0176 template <typename Derived>
0177 struct min_coeff_visitor<Derived, PropagateNumbers> : coeff_visitor<Derived>
0178 {
0179 typedef typename Derived::Scalar Scalar;
0180 EIGEN_DEVICE_FUNC
0181 void operator() (const Scalar& value, Index i, Index j)
0182 {
0183 if((numext::isnan)(this->res) || (!(numext::isnan)(value) && value < this->res))
0184 {
0185 this->res = value;
0186 this->row = i;
0187 this->col = j;
0188 }
0189 }
0190 };
0191
0192 template <typename Derived>
0193 struct min_coeff_visitor<Derived, PropagateNaN> : coeff_visitor<Derived>
0194 {
0195 typedef typename Derived::Scalar Scalar;
0196 EIGEN_DEVICE_FUNC
0197 void operator() (const Scalar& value, Index i, Index j)
0198 {
0199 if((numext::isnan)(value) || value < this->res)
0200 {
0201 this->res = value;
0202 this->row = i;
0203 this->col = j;
0204 }
0205 }
0206 };
0207
0208 template<typename Scalar, int NaNPropagation>
0209 struct functor_traits<min_coeff_visitor<Scalar, NaNPropagation> > {
0210 enum {
0211 Cost = NumTraits<Scalar>::AddCost
0212 };
0213 };
0214
0215
0216
0217
0218
0219
0220 template <typename Derived, int NaNPropagation>
0221 struct max_coeff_visitor : coeff_visitor<Derived>
0222 {
0223 typedef typename Derived::Scalar Scalar;
0224 EIGEN_DEVICE_FUNC
0225 void operator() (const Scalar& value, Index i, Index j)
0226 {
0227 if(value > this->res)
0228 {
0229 this->res = value;
0230 this->row = i;
0231 this->col = j;
0232 }
0233 }
0234 };
0235
0236 template <typename Derived>
0237 struct max_coeff_visitor<Derived, PropagateNumbers> : coeff_visitor<Derived>
0238 {
0239 typedef typename Derived::Scalar Scalar;
0240 EIGEN_DEVICE_FUNC
0241 void operator() (const Scalar& value, Index i, Index j)
0242 {
0243 if((numext::isnan)(this->res) || (!(numext::isnan)(value) && value > this->res))
0244 {
0245 this->res = value;
0246 this->row = i;
0247 this->col = j;
0248 }
0249 }
0250 };
0251
0252 template <typename Derived>
0253 struct max_coeff_visitor<Derived, PropagateNaN> : coeff_visitor<Derived>
0254 {
0255 typedef typename Derived::Scalar Scalar;
0256 EIGEN_DEVICE_FUNC
0257 void operator() (const Scalar& value, Index i, Index j)
0258 {
0259 if((numext::isnan)(value) || value > this->res)
0260 {
0261 this->res = value;
0262 this->row = i;
0263 this->col = j;
0264 }
0265 }
0266 };
0267
0268 template<typename Scalar, int NaNPropagation>
0269 struct functor_traits<max_coeff_visitor<Scalar, NaNPropagation> > {
0270 enum {
0271 Cost = NumTraits<Scalar>::AddCost
0272 };
0273 };
0274
0275 }
0276
0277
0278
0279
0280
0281
0282
0283
0284
0285
0286
0287
0288 template<typename Derived>
0289 template<int NaNPropagation, typename IndexType>
0290 EIGEN_DEVICE_FUNC
0291 typename internal::traits<Derived>::Scalar
0292 DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
0293 {
0294 eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
0295
0296 internal::min_coeff_visitor<Derived, NaNPropagation> minVisitor;
0297 this->visit(minVisitor);
0298 *rowId = minVisitor.row;
0299 if (colId) *colId = minVisitor.col;
0300 return minVisitor.res;
0301 }
0302
0303
0304
0305
0306
0307
0308
0309
0310
0311
0312
0313 template<typename Derived>
0314 template<int NaNPropagation, typename IndexType>
0315 EIGEN_DEVICE_FUNC
0316 typename internal::traits<Derived>::Scalar
0317 DenseBase<Derived>::minCoeff(IndexType* index) const
0318 {
0319 eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
0320
0321 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
0322 internal::min_coeff_visitor<Derived, NaNPropagation> minVisitor;
0323 this->visit(minVisitor);
0324 *index = IndexType((RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row);
0325 return minVisitor.res;
0326 }
0327
0328
0329
0330
0331
0332
0333
0334
0335
0336
0337
0338
0339 template<typename Derived>
0340 template<int NaNPropagation, typename IndexType>
0341 EIGEN_DEVICE_FUNC
0342 typename internal::traits<Derived>::Scalar
0343 DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
0344 {
0345 eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
0346
0347 internal::max_coeff_visitor<Derived, NaNPropagation> maxVisitor;
0348 this->visit(maxVisitor);
0349 *rowPtr = maxVisitor.row;
0350 if (colPtr) *colPtr = maxVisitor.col;
0351 return maxVisitor.res;
0352 }
0353
0354
0355
0356
0357
0358
0359
0360
0361
0362
0363
0364 template<typename Derived>
0365 template<int NaNPropagation, typename IndexType>
0366 EIGEN_DEVICE_FUNC
0367 typename internal::traits<Derived>::Scalar
0368 DenseBase<Derived>::maxCoeff(IndexType* index) const
0369 {
0370 eigen_assert(this->rows()>0 && this->cols()>0 && "you are using an empty matrix");
0371
0372 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
0373 internal::max_coeff_visitor<Derived, NaNPropagation> maxVisitor;
0374 this->visit(maxVisitor);
0375 *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
0376 return maxVisitor.res;
0377 }
0378
0379 }
0380
0381 #endif