Eigne Matrix Class Library

Dependents:   Eigen_test Odometry_test AttitudeEstimation_usingTicker MPU9250_Quaternion_Binary_Serial ... more

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers Visitor.h Source File

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   static inline void run(const Derived &mat, Visitor& visitor)
00026   {
00027     visitor_impl<Visitor, Derived, UnrollCount-1>::run(mat, visitor);
00028     visitor(mat.coeff(row, col), row, col);
00029   }
00030 };
00031 
00032 template<typename Visitor, typename Derived>
00033 struct visitor_impl<Visitor, Derived, 1>
00034 {
00035   static inline void run(const Derived &mat, Visitor& visitor)
00036   {
00037     return visitor.init(mat.coeff(0, 0), 0, 0);
00038   }
00039 };
00040 
00041 template<typename Visitor, typename Derived>
00042 struct visitor_impl<Visitor, Derived, Dynamic>
00043 {
00044   typedef typename Derived::Index Index;
00045   static inline void run(const Derived& mat, Visitor& visitor)
00046   {
00047     visitor.init(mat.coeff(0,0), 0, 0);
00048     for(Index i = 1; i < mat.rows(); ++i)
00049       visitor(mat.coeff(i, 0), i, 0);
00050     for(Index j = 1; j < mat.cols(); ++j)
00051       for(Index i = 0; i < mat.rows(); ++i)
00052         visitor(mat.coeff(i, j), i, j);
00053   }
00054 };
00055 
00056 } // end namespace internal
00057 
00058 /** Applies the visitor \a visitor to the whole coefficients of the matrix or vector.
00059   *
00060   * The template parameter \a Visitor is the type of the visitor and provides the following interface:
00061   * \code
00062   * struct MyVisitor {
00063   *   // called for the first coefficient
00064   *   void init(const Scalar& value, Index i, Index j);
00065   *   // called for all other coefficients
00066   *   void operator() (const Scalar& value, Index i, Index j);
00067   * };
00068   * \endcode
00069   *
00070   * \note compared to one or two \em for \em loops, visitors offer automatic
00071   * unrolling for small fixed size matrix.
00072   *
00073   * \sa minCoeff(Index*,Index*), maxCoeff(Index*,Index*), DenseBase::redux()
00074   */
00075 template<typename Derived>
00076 template<typename Visitor>
00077 void DenseBase<Derived>::visit(Visitor& visitor) const
00078 {
00079   typedef typename internal::remove_all<typename Derived::Nested>::type ThisNested;
00080   typename Derived::Nested thisNested(derived());
00081 
00082   enum { unroll = SizeAtCompileTime != Dynamic
00083                    && CoeffReadCost != Dynamic
00084                    && (SizeAtCompileTime == 1 || internal::functor_traits<Visitor>::Cost != Dynamic)
00085                    && SizeAtCompileTime * CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost
00086                       <= EIGEN_UNROLLING_LIMIT };
00087   return internal::visitor_impl<Visitor, ThisNested,
00088       unroll ? int(SizeAtCompileTime) : Dynamic
00089     >::run(thisNested, visitor);
00090 }
00091 
00092 namespace internal {
00093 
00094 /** \internal
00095   * \brief Base class to implement min and max visitors
00096   */
00097 template <typename Derived>
00098 struct coeff_visitor
00099 {
00100   typedef typename Derived::Index Index;
00101   typedef typename Derived::Scalar Scalar;
00102   Index row, col;
00103   Scalar res;
00104   inline void init(const Scalar& value, Index i, Index j)
00105   {
00106     res = value;
00107     row = i;
00108     col = j;
00109   }
00110 };
00111 
00112 /** \internal
00113   * \brief Visitor computing the min coefficient with its value and coordinates
00114   *
00115   * \sa DenseBase::minCoeff(Index*, Index*)
00116   */
00117 template <typename Derived>
00118 struct min_coeff_visitor : coeff_visitor<Derived>
00119 {
00120   typedef typename Derived::Index Index;
00121   typedef typename Derived::Scalar Scalar;
00122   void operator() (const Scalar& value, Index i, Index j)
00123   {
00124     if(value < this->res)
00125     {
00126       this->res = value;
00127       this->row = i;
00128       this->col = j;
00129     }
00130   }
00131 };
00132 
00133 template<typename Scalar>
00134 struct functor_traits<min_coeff_visitor<Scalar> > {
00135   enum {
00136     Cost = NumTraits<Scalar>::AddCost
00137   };
00138 };
00139 
00140 /** \internal
00141   * \brief Visitor computing the max coefficient with its value and coordinates
00142   *
00143   * \sa DenseBase::maxCoeff(Index*, Index*)
00144   */
00145 template <typename Derived>
00146 struct max_coeff_visitor : coeff_visitor<Derived>
00147 {
00148   typedef typename Derived::Index Index;
00149   typedef typename Derived::Scalar Scalar;
00150   void operator() (const Scalar& value, Index i, Index j)
00151   {
00152     if(value > this->res)
00153     {
00154       this->res = value;
00155       this->row = i;
00156       this->col = j;
00157     }
00158   }
00159 };
00160 
00161 template<typename Scalar>
00162 struct functor_traits<max_coeff_visitor<Scalar> > {
00163   enum {
00164     Cost = NumTraits<Scalar>::AddCost
00165   };
00166 };
00167 
00168 } // end namespace internal
00169 
00170 /** \returns the minimum of all coefficients of *this and puts in *row and *col its location.
00171   * \warning the result is undefined if \c *this contains NaN.
00172   *
00173   * \sa DenseBase::minCoeff(Index*), DenseBase::maxCoeff(Index*,Index*), DenseBase::visitor(), DenseBase::minCoeff()
00174   */
00175 template<typename Derived>
00176 template<typename IndexType>
00177 typename internal::traits<Derived>::Scalar
00178 DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
00179 {
00180   internal::min_coeff_visitor<Derived> minVisitor;
00181   this->visit(minVisitor);
00182   *rowId = minVisitor.row;
00183   if (colId) *colId = minVisitor.col;
00184   return minVisitor.res;
00185 }
00186 
00187 /** \returns the minimum of all coefficients of *this and puts in *index its location.
00188   * \warning the result is undefined if \c *this contains NaN. 
00189   *
00190   * \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::minCoeff()
00191   */
00192 template<typename Derived>
00193 template<typename IndexType>
00194 typename internal::traits<Derived>::Scalar
00195 DenseBase<Derived>::minCoeff(IndexType* index) const
00196 {
00197   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00198   internal::min_coeff_visitor<Derived> minVisitor;
00199   this->visit(minVisitor);
00200   *index = (RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row;
00201   return minVisitor.res;
00202 }
00203 
00204 /** \returns the maximum of all coefficients of *this and puts in *row and *col its location.
00205   * \warning the result is undefined if \c *this contains NaN. 
00206   *
00207   * \sa DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::maxCoeff()
00208   */
00209 template<typename Derived>
00210 template<typename IndexType>
00211 typename internal::traits<Derived>::Scalar
00212 DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
00213 {
00214   internal::max_coeff_visitor<Derived> maxVisitor;
00215   this->visit(maxVisitor);
00216   *rowPtr = maxVisitor.row;
00217   if (colPtr) *colPtr = maxVisitor.col;
00218   return maxVisitor.res;
00219 }
00220 
00221 /** \returns the maximum of all coefficients of *this and puts in *index its location.
00222   * \warning the result is undefined if \c *this contains NaN.
00223   *
00224   * \sa DenseBase::maxCoeff(IndexType*,IndexType*), DenseBase::minCoeff(IndexType*,IndexType*), DenseBase::visitor(), DenseBase::maxCoeff()
00225   */
00226 template<typename Derived>
00227 template<typename IndexType>
00228 typename internal::traits<Derived>::Scalar
00229 DenseBase<Derived>::maxCoeff(IndexType* index) const
00230 {
00231   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00232   internal::max_coeff_visitor<Derived> maxVisitor;
00233   this->visit(maxVisitor);
00234   *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
00235   return maxVisitor.res;
00236 }
00237 
00238 } // end namespace Eigen
00239 
00240 #endif // EIGEN_VISITOR_H