Eigen  3.3.3
Visitor.h
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr>
00005 //
00006 // This Source Code Form is subject to the terms of the Mozilla
00007 // Public License v. 2.0. If a copy of the MPL was not distributed
00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/.
00009 
00010 #ifndef EIGEN_VISITOR_H
00011 #define EIGEN_VISITOR_H
00012 
00013 namespace Eigen { 
00014 
00015 namespace internal {
00016 
00017 template<typename Visitor, typename Derived, int UnrollCount>
00018 struct visitor_impl
00019 {
00020   enum {
00021     col = (UnrollCount-1) / Derived::RowsAtCompileTime,
00022     row = (UnrollCount-1) % Derived::RowsAtCompileTime
00023   };
00024 
00025   EIGEN_DEVICE_FUNC
00026   static inline void run(const Derived &mat, Visitor& visitor)
00027   {
00028     visitor_impl<Visitor, Derived, UnrollCount-1>::run(mat, visitor);
00029     visitor(mat.coeff(row, col), row, col);
00030   }
00031 };
00032 
00033 template<typename Visitor, typename Derived>
00034 struct visitor_impl<Visitor, Derived, 1>
00035 {
00036   EIGEN_DEVICE_FUNC
00037   static inline void run(const Derived &mat, Visitor& visitor)
00038   {
00039     return visitor.init(mat.coeff(0, 0), 0, 0);
00040   }
00041 };
00042 
00043 template<typename Visitor, typename Derived>
00044 struct visitor_impl<Visitor, Derived, Dynamic>
00045 {
00046   EIGEN_DEVICE_FUNC
00047   static inline void run(const Derived& mat, Visitor& visitor)
00048   {
00049     visitor.init(mat.coeff(0,0), 0, 0);
00050     for(Index i = 1; i < mat.rows(); ++i)
00051       visitor(mat.coeff(i, 0), i, 0);
00052     for(Index j = 1; j < mat.cols(); ++j)
00053       for(Index i = 0; i < mat.rows(); ++i)
00054         visitor(mat.coeff(i, j), i, j);
00055   }
00056 };
00057 
00058 // evaluator adaptor
00059 template<typename XprType>
00060 class visitor_evaluator
00061 {
00062 public:
00063   EIGEN_DEVICE_FUNC
00064   explicit visitor_evaluator(const XprType &xpr) : m_evaluator(xpr), m_xpr(xpr) {}
00065   
00066   typedef typename XprType::Scalar Scalar;
00067   typedef typename XprType::CoeffReturnType CoeffReturnType;
00068   
00069   enum {
00070     RowsAtCompileTime = XprType::RowsAtCompileTime,
00071     CoeffReadCost = internal::evaluator<XprType>::CoeffReadCost
00072   };
00073   
00074   EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.rows(); }
00075   EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.cols(); }
00076   EIGEN_DEVICE_FUNC Index size() const { return m_xpr.size(); }
00077 
00078   EIGEN_DEVICE_FUNC CoeffReturnType coeff(Index row, Index col) const
00079   { return m_evaluator.coeff(row, col); }
00080   
00081 protected:
00082   internal::evaluator<XprType> m_evaluator;
00083   const XprType &m_xpr;
00084 };
00085 } // end namespace internal
00086 
00104 template<typename Derived>
00105 template<typename Visitor>
00106 EIGEN_DEVICE_FUNC
00107 void DenseBase<Derived>::visit(Visitor& visitor) const
00108 {
00109   typedef typename internal::visitor_evaluator<Derived> ThisEvaluator;
00110   ThisEvaluator thisEval(derived());
00111   
00112   enum {
00113     unroll =  SizeAtCompileTime != Dynamic
00114            && SizeAtCompileTime * ThisEvaluator::CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost <= EIGEN_UNROLLING_LIMIT
00115   };
00116   return internal::visitor_impl<Visitor, ThisEvaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(thisEval, visitor);
00117 }
00118 
00119 namespace internal {
00120 
00124 template <typename Derived>
00125 struct coeff_visitor
00126 {
00127   typedef typename Derived::Scalar Scalar;
00128   Index row, col;
00129   Scalar res;
00130   EIGEN_DEVICE_FUNC
00131   inline void init(const Scalar& value, Index i, Index j)
00132   {
00133     res = value;
00134     row = i;
00135     col = j;
00136   }
00137 };
00138 
00144 template <typename Derived>
00145 struct min_coeff_visitor : coeff_visitor<Derived>
00146 {
00147   typedef typename Derived::Scalar Scalar;
00148   EIGEN_DEVICE_FUNC
00149   void operator() (const Scalar& value, Index i, Index j)
00150   {
00151     if(value < this->res)
00152     {
00153       this->res = value;
00154       this->row = i;
00155       this->col = j;
00156     }
00157   }
00158 };
00159 
00160 template<typename Scalar>
00161 struct functor_traits<min_coeff_visitor<Scalar> > {
00162   enum {
00163     Cost = NumTraits<Scalar>::AddCost
00164   };
00165 };
00166 
00172 template <typename Derived>
00173 struct max_coeff_visitor : coeff_visitor<Derived>
00174 {
00175   typedef typename Derived::Scalar Scalar; 
00176   EIGEN_DEVICE_FUNC
00177   void operator() (const Scalar& value, Index i, Index j)
00178   {
00179     if(value > this->res)
00180     {
00181       this->res = value;
00182       this->row = i;
00183       this->col = j;
00184     }
00185   }
00186 };
00187 
00188 template<typename Scalar>
00189 struct functor_traits<max_coeff_visitor<Scalar> > {
00190   enum {
00191     Cost = NumTraits<Scalar>::AddCost
00192   };
00193 };
00194 
00195 } // end namespace internal
00196 
00203 template<typename Derived>
00204 template<typename IndexType>
00205 EIGEN_DEVICE_FUNC
00206 typename internal::traits<Derived>::Scalar
00207 DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
00208 {
00209   internal::min_coeff_visitor<Derived> minVisitor;
00210   this->visit(minVisitor);
00211   *rowId = minVisitor.row;
00212   if (colId) *colId = minVisitor.col;
00213   return minVisitor.res;
00214 }
00215 
00221 template<typename Derived>
00222 template<typename IndexType>
00223 EIGEN_DEVICE_FUNC
00224 typename internal::traits<Derived>::Scalar
00225 DenseBase<Derived>::minCoeff(IndexType* index) const
00226 {
00227   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00228   internal::min_coeff_visitor<Derived> minVisitor;
00229   this->visit(minVisitor);
00230   *index = IndexType((RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row);
00231   return minVisitor.res;
00232 }
00233 
00240 template<typename Derived>
00241 template<typename IndexType>
00242 EIGEN_DEVICE_FUNC
00243 typename internal::traits<Derived>::Scalar
00244 DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
00245 {
00246   internal::max_coeff_visitor<Derived> maxVisitor;
00247   this->visit(maxVisitor);
00248   *rowPtr = maxVisitor.row;
00249   if (colPtr) *colPtr = maxVisitor.col;
00250   return maxVisitor.res;
00251 }
00252 
00258 template<typename Derived>
00259 template<typename IndexType>
00260 EIGEN_DEVICE_FUNC
00261 typename internal::traits<Derived>::Scalar
00262 DenseBase<Derived>::maxCoeff(IndexType* index) const
00263 {
00264   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00265   internal::max_coeff_visitor<Derived> maxVisitor;
00266   this->visit(maxVisitor);
00267   *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
00268   return maxVisitor.res;
00269 }
00270 
00271 } // end namespace Eigen
00272 
00273 #endif // EIGEN_VISITOR_H
 All Classes Functions Variables Typedefs Enumerations Enumerator Friends