Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
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 }
00057
00075 template<typename Derived>
00076 template<typename Visitor>
00077 void DenseBase<Derived>::visit(Visitor& visitor) const
00078 {
00079 enum { unroll = SizeAtCompileTime != Dynamic
00080 && CoeffReadCost != Dynamic
00081 && (SizeAtCompileTime == 1 || internal::functor_traits<Visitor>::Cost != Dynamic)
00082 && SizeAtCompileTime * CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost
00083 <= EIGEN_UNROLLING_LIMIT };
00084 return internal::visitor_impl<Visitor, Derived,
00085 unroll ? int(SizeAtCompileTime) : Dynamic
00086 >::run(derived(), visitor);
00087 }
00088
00089 namespace internal {
00090
00094 template <typename Derived>
00095 struct coeff_visitor
00096 {
00097 typedef typename Derived::Index Index;
00098 typedef typename Derived::Scalar Scalar;
00099 Index row, col;
00100 Scalar res;
00101 inline void init(const Scalar& value, Index i, Index j)
00102 {
00103 res = value;
00104 row = i;
00105 col = j;
00106 }
00107 };
00108
00114 template <typename Derived>
00115 struct min_coeff_visitor : coeff_visitor<Derived>
00116 {
00117 typedef typename Derived::Index Index;
00118 typedef typename Derived::Scalar Scalar;
00119 void operator() (const Scalar& value, Index i, Index j)
00120 {
00121 if(value < this->res)
00122 {
00123 this->res = value;
00124 this->row = i;
00125 this->col = j;
00126 }
00127 }
00128 };
00129
00130 template<typename Scalar>
00131 struct functor_traits<min_coeff_visitor<Scalar> > {
00132 enum {
00133 Cost = NumTraits<Scalar>::AddCost
00134 };
00135 };
00136
00142 template <typename Derived>
00143 struct max_coeff_visitor : coeff_visitor<Derived>
00144 {
00145 typedef typename Derived::Index Index;
00146 typedef typename Derived::Scalar Scalar;
00147 void operator() (const Scalar& value, Index i, Index j)
00148 {
00149 if(value > this->res)
00150 {
00151 this->res = value;
00152 this->row = i;
00153 this->col = j;
00154 }
00155 }
00156 };
00157
00158 template<typename Scalar>
00159 struct functor_traits<max_coeff_visitor<Scalar> > {
00160 enum {
00161 Cost = NumTraits<Scalar>::AddCost
00162 };
00163 };
00164
00165 }
00166
00172 template<typename Derived>
00173 template<typename IndexType>
00174 typename internal::traits<Derived>::Scalar
00175 DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const
00176 {
00177 internal::min_coeff_visitor<Derived> minVisitor;
00178 this->visit(minVisitor);
00179 *rowId = minVisitor.row;
00180 if (colId) *colId = minVisitor.col;
00181 return minVisitor.res;
00182 }
00183
00189 template<typename Derived>
00190 template<typename IndexType>
00191 typename internal::traits<Derived>::Scalar
00192 DenseBase<Derived>::minCoeff(IndexType* index) const
00193 {
00194 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00195 internal::min_coeff_visitor<Derived> minVisitor;
00196 this->visit(minVisitor);
00197 *index = (RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row;
00198 return minVisitor.res;
00199 }
00200
00206 template<typename Derived>
00207 template<typename IndexType>
00208 typename internal::traits<Derived>::Scalar
00209 DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const
00210 {
00211 internal::max_coeff_visitor<Derived> maxVisitor;
00212 this->visit(maxVisitor);
00213 *rowPtr = maxVisitor.row;
00214 if (colPtr) *colPtr = maxVisitor.col;
00215 return maxVisitor.res;
00216 }
00217
00223 template<typename Derived>
00224 template<typename IndexType>
00225 typename internal::traits<Derived>::Scalar
00226 DenseBase<Derived>::maxCoeff(IndexType* index) const
00227 {
00228 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00229 internal::max_coeff_visitor<Derived> maxVisitor;
00230 this->visit(maxVisitor);
00231 *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
00232 return maxVisitor.res;
00233 }
00234
00235 }
00236
00237 #endif // EIGEN_VISITOR_H