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 
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 
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 
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 
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 
00185 template<typename Derived>
00186 template<typename IndexType>
00187 typename internal::traits<Derived>::Scalar
00188 DenseBase<Derived>::minCoeff(IndexType* row, IndexType* col) const
00189 {
00190   internal::min_coeff_visitor<Derived> minVisitor;
00191   this->visit(minVisitor);
00192   *row = minVisitor.row;
00193   if (col) *col = minVisitor.col;
00194   return minVisitor.res;
00195 }
00196 
00202 template<typename Derived>
00203 template<typename IndexType>
00204 typename internal::traits<Derived>::Scalar
00205 DenseBase<Derived>::minCoeff(IndexType* index) const
00206 {
00207   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00208   internal::min_coeff_visitor<Derived> minVisitor;
00209   this->visit(minVisitor);
00210   *index = (RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row;
00211   return minVisitor.res;
00212 }
00213 
00219 template<typename Derived>
00220 template<typename IndexType>
00221 typename internal::traits<Derived>::Scalar
00222 DenseBase<Derived>::maxCoeff(IndexType* row, IndexType* col) const
00223 {
00224   internal::max_coeff_visitor<Derived> maxVisitor;
00225   this->visit(maxVisitor);
00226   *row = maxVisitor.row;
00227   if (col) *col = maxVisitor.col;
00228   return maxVisitor.res;
00229 }
00230 
00236 template<typename Derived>
00237 template<typename IndexType>
00238 typename internal::traits<Derived>::Scalar
00239 DenseBase<Derived>::maxCoeff(IndexType* index) const
00240 {
00241   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00242   internal::max_coeff_visitor<Derived> maxVisitor;
00243   this->visit(maxVisitor);
00244   *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
00245   return maxVisitor.res;
00246 }
00247 
00248 #endif // EIGEN_VISITOR_H


libicr
Author(s): Robert Krug
autogenerated on Mon Jan 6 2014 11:34:04