Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025 #ifndef EIGEN_VISITOR_H
00026 #define EIGEN_VISITOR_H
00027
00028 namespace Eigen {
00029
00030 namespace internal {
00031
00032 template<typename Visitor, typename Derived, int UnrollCount>
00033 struct visitor_impl
00034 {
00035 enum {
00036 col = (UnrollCount-1) / Derived::RowsAtCompileTime,
00037 row = (UnrollCount-1) % Derived::RowsAtCompileTime
00038 };
00039
00040 static inline void run(const Derived &mat, Visitor& visitor)
00041 {
00042 visitor_impl<Visitor, Derived, UnrollCount-1>::run(mat, visitor);
00043 visitor(mat.coeff(row, col), row, col);
00044 }
00045 };
00046
00047 template<typename Visitor, typename Derived>
00048 struct visitor_impl<Visitor, Derived, 1>
00049 {
00050 static inline void run(const Derived &mat, Visitor& visitor)
00051 {
00052 return visitor.init(mat.coeff(0, 0), 0, 0);
00053 }
00054 };
00055
00056 template<typename Visitor, typename Derived>
00057 struct visitor_impl<Visitor, Derived, Dynamic>
00058 {
00059 typedef typename Derived::Index Index;
00060 static inline void run(const Derived& mat, Visitor& visitor)
00061 {
00062 visitor.init(mat.coeff(0,0), 0, 0);
00063 for(Index i = 1; i < mat.rows(); ++i)
00064 visitor(mat.coeff(i, 0), i, 0);
00065 for(Index j = 1; j < mat.cols(); ++j)
00066 for(Index i = 0; i < mat.rows(); ++i)
00067 visitor(mat.coeff(i, j), i, j);
00068 }
00069 };
00070
00071 }
00072
00090 template<typename Derived>
00091 template<typename Visitor>
00092 void DenseBase<Derived>::visit(Visitor& visitor) const
00093 {
00094 enum { unroll = SizeAtCompileTime != Dynamic
00095 && CoeffReadCost != Dynamic
00096 && (SizeAtCompileTime == 1 || internal::functor_traits<Visitor>::Cost != Dynamic)
00097 && SizeAtCompileTime * CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost
00098 <= EIGEN_UNROLLING_LIMIT };
00099 return internal::visitor_impl<Visitor, Derived,
00100 unroll ? int(SizeAtCompileTime) : Dynamic
00101 >::run(derived(), visitor);
00102 }
00103
00104 namespace internal {
00105
00109 template <typename Derived>
00110 struct coeff_visitor
00111 {
00112 typedef typename Derived::Index Index;
00113 typedef typename Derived::Scalar Scalar;
00114 Index row, col;
00115 Scalar res;
00116 inline void init(const Scalar& value, Index i, Index j)
00117 {
00118 res = value;
00119 row = i;
00120 col = j;
00121 }
00122 };
00123
00129 template <typename Derived>
00130 struct min_coeff_visitor : coeff_visitor<Derived>
00131 {
00132 typedef typename Derived::Index Index;
00133 typedef typename Derived::Scalar Scalar;
00134 void operator() (const Scalar& value, Index i, Index j)
00135 {
00136 if(value < this->res)
00137 {
00138 this->res = value;
00139 this->row = i;
00140 this->col = j;
00141 }
00142 }
00143 };
00144
00145 template<typename Scalar>
00146 struct functor_traits<min_coeff_visitor<Scalar> > {
00147 enum {
00148 Cost = NumTraits<Scalar>::AddCost
00149 };
00150 };
00151
00157 template <typename Derived>
00158 struct max_coeff_visitor : coeff_visitor<Derived>
00159 {
00160 typedef typename Derived::Index Index;
00161 typedef typename Derived::Scalar Scalar;
00162 void operator() (const Scalar& value, Index i, Index j)
00163 {
00164 if(value > this->res)
00165 {
00166 this->res = value;
00167 this->row = i;
00168 this->col = j;
00169 }
00170 }
00171 };
00172
00173 template<typename Scalar>
00174 struct functor_traits<max_coeff_visitor<Scalar> > {
00175 enum {
00176 Cost = NumTraits<Scalar>::AddCost
00177 };
00178 };
00179
00180 }
00181
00187 template<typename Derived>
00188 template<typename IndexType>
00189 typename internal::traits<Derived>::Scalar
00190 DenseBase<Derived>::minCoeff(IndexType* row, IndexType* col) const
00191 {
00192 internal::min_coeff_visitor<Derived> minVisitor;
00193 this->visit(minVisitor);
00194 *row = minVisitor.row;
00195 if (col) *col = minVisitor.col;
00196 return minVisitor.res;
00197 }
00198
00204 template<typename Derived>
00205 template<typename IndexType>
00206 typename internal::traits<Derived>::Scalar
00207 DenseBase<Derived>::minCoeff(IndexType* index) const
00208 {
00209 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00210 internal::min_coeff_visitor<Derived> minVisitor;
00211 this->visit(minVisitor);
00212 *index = (RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row;
00213 return minVisitor.res;
00214 }
00215
00221 template<typename Derived>
00222 template<typename IndexType>
00223 typename internal::traits<Derived>::Scalar
00224 DenseBase<Derived>::maxCoeff(IndexType* row, IndexType* col) const
00225 {
00226 internal::max_coeff_visitor<Derived> maxVisitor;
00227 this->visit(maxVisitor);
00228 *row = maxVisitor.row;
00229 if (col) *col = maxVisitor.col;
00230 return maxVisitor.res;
00231 }
00232
00238 template<typename Derived>
00239 template<typename IndexType>
00240 typename internal::traits<Derived>::Scalar
00241 DenseBase<Derived>::maxCoeff(IndexType* index) const
00242 {
00243 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00244 internal::max_coeff_visitor<Derived> maxVisitor;
00245 this->visit(maxVisitor);
00246 *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
00247 return maxVisitor.res;
00248 }
00249
00250 }
00251
00252 #endif // EIGEN_VISITOR_H