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 template<typename Visitor, typename Derived, int UnrollCount>
00029 struct ei_visitor_impl
00030 {
00031 enum {
00032 col = (UnrollCount-1) / Derived::RowsAtCompileTime,
00033 row = (UnrollCount-1) % Derived::RowsAtCompileTime
00034 };
00035
00036 inline static void run(const Derived &mat, Visitor& visitor)
00037 {
00038 ei_visitor_impl<Visitor, Derived, UnrollCount-1>::run(mat, visitor);
00039 visitor(mat.coeff(row, col), row, col);
00040 }
00041 };
00042
00043 template<typename Visitor, typename Derived>
00044 struct ei_visitor_impl<Visitor, Derived, 1>
00045 {
00046 inline static void run(const Derived &mat, Visitor& visitor)
00047 {
00048 return visitor.init(mat.coeff(0, 0), 0, 0);
00049 }
00050 };
00051
00052 template<typename Visitor, typename Derived>
00053 struct ei_visitor_impl<Visitor, Derived, Dynamic>
00054 {
00055 inline static void run(const Derived& mat, Visitor& visitor)
00056 {
00057 visitor.init(mat.coeff(0,0), 0, 0);
00058 for(int i = 1; i < mat.rows(); ++i)
00059 visitor(mat.coeff(i, 0), i, 0);
00060 for(int j = 1; j < mat.cols(); ++j)
00061 for(int i = 0; i < mat.rows(); ++i)
00062 visitor(mat.coeff(i, j), i, j);
00063 }
00064 };
00065
00066
00084 template<typename Derived>
00085 template<typename Visitor>
00086 void MatrixBase<Derived>::visit(Visitor& visitor) const
00087 {
00088 const bool unroll = SizeAtCompileTime * CoeffReadCost
00089 + (SizeAtCompileTime-1) * ei_functor_traits<Visitor>::Cost
00090 <= EIGEN_UNROLLING_LIMIT;
00091 return ei_visitor_impl<Visitor, Derived,
00092 unroll ? int(SizeAtCompileTime) : Dynamic
00093 >::run(derived(), visitor);
00094 }
00095
00099 template <typename Scalar>
00100 struct ei_coeff_visitor
00101 {
00102 int row, col;
00103 Scalar res;
00104 inline void init(const Scalar& value, int i, int j)
00105 {
00106 res = value;
00107 row = i;
00108 col = j;
00109 }
00110 };
00111
00117 template <typename Scalar>
00118 struct ei_min_coeff_visitor : ei_coeff_visitor<Scalar>
00119 {
00120 void operator() (const Scalar& value, int i, int j)
00121 {
00122 if(value < this->res)
00123 {
00124 this->res = value;
00125 this->row = i;
00126 this->col = j;
00127 }
00128 }
00129 };
00130
00131 template<typename Scalar>
00132 struct ei_functor_traits<ei_min_coeff_visitor<Scalar> > {
00133 enum {
00134 Cost = NumTraits<Scalar>::AddCost
00135 };
00136 };
00137
00143 template <typename Scalar>
00144 struct ei_max_coeff_visitor : ei_coeff_visitor<Scalar>
00145 {
00146 void operator() (const Scalar& value, int i, int j)
00147 {
00148 if(value > this->res)
00149 {
00150 this->res = value;
00151 this->row = i;
00152 this->col = j;
00153 }
00154 }
00155 };
00156
00157 template<typename Scalar>
00158 struct ei_functor_traits<ei_max_coeff_visitor<Scalar> > {
00159 enum {
00160 Cost = NumTraits<Scalar>::AddCost
00161 };
00162 };
00163
00169 template<typename Derived>
00170 typename ei_traits<Derived>::Scalar
00171 MatrixBase<Derived>::minCoeff(int* row, int* col) const
00172 {
00173 ei_min_coeff_visitor<Scalar> minVisitor;
00174 this->visit(minVisitor);
00175 *row = minVisitor.row;
00176 if (col) *col = minVisitor.col;
00177 return minVisitor.res;
00178 }
00179
00185 template<typename Derived>
00186 typename ei_traits<Derived>::Scalar
00187 MatrixBase<Derived>::minCoeff(int* index) const
00188 {
00189 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00190 ei_min_coeff_visitor<Scalar> minVisitor;
00191 this->visit(minVisitor);
00192 *index = (RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row;
00193 return minVisitor.res;
00194 }
00195
00201 template<typename Derived>
00202 typename ei_traits<Derived>::Scalar
00203 MatrixBase<Derived>::maxCoeff(int* row, int* col) const
00204 {
00205 ei_max_coeff_visitor<Scalar> maxVisitor;
00206 this->visit(maxVisitor);
00207 *row = maxVisitor.row;
00208 if (col) *col = maxVisitor.col;
00209 return maxVisitor.res;
00210 }
00211
00217 template<typename Derived>
00218 typename ei_traits<Derived>::Scalar
00219 MatrixBase<Derived>::maxCoeff(int* index) const
00220 {
00221 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00222 ei_max_coeff_visitor<Scalar> maxVisitor;
00223 this->visit(maxVisitor);
00224 *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
00225 return maxVisitor.res;
00226 }
00227
00228 #endif // EIGEN_VISITOR_H