Main MRPT website > C++ reference
MRPT logo

Visitor.h

Go to the documentation of this file.
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 // Eigen is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 3 of the License, or (at your option) any later version.
00010 //
00011 // Alternatively, you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License as
00013 // published by the Free Software Foundation; either version 2 of
00014 // the License, or (at your option) any later version.
00015 //
00016 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00017 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00019 // GNU General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License and a copy of the GNU General Public License along with
00023 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00024 
00025 #ifndef EIGEN_VISITOR_H
00026 #define EIGEN_VISITOR_H
00027 
00028 namespace internal {
00029 
00030 template<typename Visitor, typename Derived, int UnrollCount>
00031 struct visitor_impl
00032 {
00033   enum {
00034     col = (UnrollCount-1) / Derived::RowsAtCompileTime,
00035     row = (UnrollCount-1) % Derived::RowsAtCompileTime
00036   };
00037 
00038   inline static void run(const Derived &mat, Visitor& visitor)
00039   {
00040     visitor_impl<Visitor, Derived, UnrollCount-1>::run(mat, visitor);
00041     visitor(mat.coeff(row, col), row, col);
00042   }
00043 };
00044 
00045 template<typename Visitor, typename Derived>
00046 struct visitor_impl<Visitor, Derived, 1>
00047 {
00048   inline static void run(const Derived &mat, Visitor& visitor)
00049   {
00050     return visitor.init(mat.coeff(0, 0), 0, 0);
00051   }
00052 };
00053 
00054 template<typename Visitor, typename Derived>
00055 struct visitor_impl<Visitor, Derived, Dynamic>
00056 {
00057   typedef typename Derived::Index Index;
00058   inline static void run(const Derived& mat, Visitor& visitor)
00059   {
00060     visitor.init(mat.coeff(0,0), 0, 0);
00061     for(Index i = 1; i < mat.rows(); ++i)
00062       visitor(mat.coeff(i, 0), i, 0);
00063     for(Index j = 1; j < mat.cols(); ++j)
00064       for(Index i = 0; i < mat.rows(); ++i)
00065         visitor(mat.coeff(i, j), i, j);
00066   }
00067 };
00068 
00069 } // end namespace internal
00070 
00071 /** Applies the visitor \a visitor to the whole coefficients of the matrix or vector.
00072   *
00073   * The template parameter \a Visitor is the type of the visitor and provides the following interface:
00074   * \code
00075   * struct MyVisitor {
00076   *   // called for the first coefficient
00077   *   void init(const Scalar& value, Index i, Index j);
00078   *   // called for all other coefficients
00079   *   void operator() (const Scalar& value, Index i, Index j);
00080   * };
00081   * \endcode
00082   *
00083   * \note compared to one or two \em for \em loops, visitors offer automatic
00084   * unrolling for small fixed size matrix.
00085   *
00086   * \sa minCoeff(Index*,Index*), maxCoeff(Index*,Index*), DenseBase::redux()
00087   */
00088 template<typename Derived>
00089 template<typename Visitor>
00090 void DenseBase<Derived>::visit(Visitor& visitor) const
00091 {
00092   enum { unroll = SizeAtCompileTime != Dynamic
00093                    && CoeffReadCost != Dynamic
00094                    && (SizeAtCompileTime == 1 || internal::functor_traits<Visitor>::Cost != Dynamic)
00095                    && SizeAtCompileTime * CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost
00096                       <= EIGEN_UNROLLING_LIMIT };
00097   return internal::visitor_impl<Visitor, Derived,
00098       unroll ? int(SizeAtCompileTime) : Dynamic
00099     >::run(derived(), visitor);
00100 }
00101 
00102 namespace internal {
00103 
00104 /** \internal
00105   * \brief Base class to implement min and max visitors
00106   */
00107 template <typename Derived>
00108 struct coeff_visitor
00109 {
00110   typedef typename Derived::Index Index;
00111   typedef typename Derived::Scalar Scalar;
00112   Index row, col;
00113   Scalar res;
00114   inline void init(const Scalar& value, Index i, Index j)
00115   {
00116     res = value;
00117     row = i;
00118     col = j;
00119   }
00120 };
00121 
00122 /** \internal
00123   * \brief Visitor computing the min coefficient with its value and coordinates
00124   *
00125   * \sa DenseBase::minCoeff(Index*, Index*)
00126   */
00127 template <typename Derived>
00128 struct min_coeff_visitor : coeff_visitor<Derived>
00129 {
00130   typedef typename Derived::Index Index;
00131   typedef typename Derived::Scalar Scalar;
00132   void operator() (const Scalar& value, Index i, Index j)
00133   {
00134     if(value < this->res)
00135     {
00136       this->res = value;
00137       this->row = i;
00138       this->col = j;
00139     }
00140   }
00141 };
00142 
00143 template<typename Scalar>
00144 struct functor_traits<min_coeff_visitor<Scalar> > {
00145   enum {
00146     Cost = NumTraits<Scalar>::AddCost
00147   };
00148 };
00149 
00150 /** \internal
00151   * \brief Visitor computing the max coefficient with its value and coordinates
00152   *
00153   * \sa DenseBase::maxCoeff(Index*, Index*)
00154   */
00155 template <typename Derived>
00156 struct max_coeff_visitor : coeff_visitor<Derived>
00157 {
00158   typedef typename Derived::Index Index;
00159   typedef typename Derived::Scalar Scalar;
00160   void operator() (const Scalar& value, Index i, Index j)
00161   {
00162     if(value > this->res)
00163     {
00164       this->res = value;
00165       this->row = i;
00166       this->col = j;
00167     }
00168   }
00169 };
00170 
00171 template<typename Scalar>
00172 struct functor_traits<max_coeff_visitor<Scalar> > {
00173   enum {
00174     Cost = NumTraits<Scalar>::AddCost
00175   };
00176 };
00177 
00178 } // end namespace internal
00179 
00180 /** \returns the minimum of all coefficients of *this
00181   * and puts in *row and *col its location.
00182   *
00183   * \sa DenseBase::minCoeff(Index*), DenseBase::maxCoeff(Index*,Index*), DenseBase::visitor(), DenseBase::minCoeff()
00184   */
00185 template<typename Derived>
00186 typename internal::traits<Derived>::Scalar
00187 DenseBase<Derived>::minCoeff(Index* row, Index* col) const
00188 {
00189   internal::min_coeff_visitor<Derived> minVisitor;
00190   this->visit(minVisitor);
00191   *row = minVisitor.row;
00192   if (col) *col = minVisitor.col;
00193   return minVisitor.res;
00194 }
00195 
00196 /** \returns the minimum of all coefficients of *this
00197   * and puts in *index its location.
00198   *
00199   * \sa DenseBase::minCoeff(Index*,Index*), DenseBase::maxCoeff(Index*,Index*), DenseBase::visitor(), DenseBase::minCoeff()
00200   */
00201 template<typename Derived>
00202 typename internal::traits<Derived>::Scalar
00203 DenseBase<Derived>::minCoeff(Index* index) const
00204 {
00205   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00206   internal::min_coeff_visitor<Derived> minVisitor;
00207   this->visit(minVisitor);
00208   *index = (RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row;
00209   return minVisitor.res;
00210 }
00211 
00212 /** \returns the maximum of all coefficients of *this
00213   * and puts in *row and *col its location.
00214   *
00215   * \sa DenseBase::minCoeff(Index*,Index*), DenseBase::visitor(), DenseBase::maxCoeff()
00216   */
00217 template<typename Derived>
00218 typename internal::traits<Derived>::Scalar
00219 DenseBase<Derived>::maxCoeff(Index* row, Index* col) const
00220 {
00221   internal::max_coeff_visitor<Derived> maxVisitor;
00222   this->visit(maxVisitor);
00223   *row = maxVisitor.row;
00224   if (col) *col = maxVisitor.col;
00225   return maxVisitor.res;
00226 }
00227 
00228 /** \returns the maximum of all coefficients of *this
00229   * and puts in *index its location.
00230   *
00231   * \sa DenseBase::maxCoeff(Index*,Index*), DenseBase::minCoeff(Index*,Index*), DenseBase::visitor(), DenseBase::maxCoeff()
00232   */
00233 template<typename Derived>
00234 typename internal::traits<Derived>::Scalar
00235 DenseBase<Derived>::maxCoeff(Index* index) const
00236 {
00237   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00238   internal::max_coeff_visitor<Derived> maxVisitor;
00239   this->visit(maxVisitor);
00240   *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
00241   return maxVisitor.res;
00242 }
00243 
00244 #endif // EIGEN_VISITOR_H



Page generated by Doxygen 1.7.3 for MRPT 0.9.4 SVN: at Sat Mar 26 06:40:17 UTC 2011