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
00071
00072
00073
00074
00075
00076
00077
00078
00079
00080
00081
00082
00083
00084
00085
00086
00087
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
00104
00105
00106
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
00122
00123
00124
00125
00126
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
00150
00151
00152
00153
00154
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
00180
00181
00182
00183
00184
00185 template<typename Derived>
00186 typename internal::traits<Derived>::Scalar
00187 DenseBase<Derived>::minCoeff(Index* row, Index* col) const
00188 {
00189 internal::min_coeff_visitor<Derived> minVisitor;
00190 this->visit(minVisitor);
00191 *row = minVisitor.row;
00192 if (col) *col = minVisitor.col;
00193 return minVisitor.res;
00194 }
00195
00196
00197
00198
00199
00200
00201 template<typename Derived>
00202 typename internal::traits<Derived>::Scalar
00203 DenseBase<Derived>::minCoeff(Index* index) const
00204 {
00205 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00206 internal::min_coeff_visitor<Derived> minVisitor;
00207 this->visit(minVisitor);
00208 *index = (RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row;
00209 return minVisitor.res;
00210 }
00211
00212
00213
00214
00215
00216
00217 template<typename Derived>
00218 typename internal::traits<Derived>::Scalar
00219 DenseBase<Derived>::maxCoeff(Index* row, Index* col) const
00220 {
00221 internal::max_coeff_visitor<Derived> maxVisitor;
00222 this->visit(maxVisitor);
00223 *row = maxVisitor.row;
00224 if (col) *col = maxVisitor.col;
00225 return maxVisitor.res;
00226 }
00227
00228
00229
00230
00231
00232
00233 template<typename Derived>
00234 typename internal::traits<Derived>::Scalar
00235 DenseBase<Derived>::maxCoeff(Index* index) const
00236 {
00237 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00238 internal::max_coeff_visitor<Derived> maxVisitor;
00239 this->visit(maxVisitor);
00240 *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
00241 return maxVisitor.res;
00242 }
00243
00244 #endif // EIGEN_VISITOR_H