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 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 }
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 }
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