![]() |
Eigen
3.3.3
|
00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2008 Gael Guennebaud <gael.guennebaud@inria.fr> 00005 // 00006 // This Source Code Form is subject to the terms of the Mozilla 00007 // Public License v. 2.0. If a copy of the MPL was not distributed 00008 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 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 EIGEN_DEVICE_FUNC 00026 static inline void run(const Derived &mat, Visitor& visitor) 00027 { 00028 visitor_impl<Visitor, Derived, UnrollCount-1>::run(mat, visitor); 00029 visitor(mat.coeff(row, col), row, col); 00030 } 00031 }; 00032 00033 template<typename Visitor, typename Derived> 00034 struct visitor_impl<Visitor, Derived, 1> 00035 { 00036 EIGEN_DEVICE_FUNC 00037 static inline void run(const Derived &mat, Visitor& visitor) 00038 { 00039 return visitor.init(mat.coeff(0, 0), 0, 0); 00040 } 00041 }; 00042 00043 template<typename Visitor, typename Derived> 00044 struct visitor_impl<Visitor, Derived, Dynamic> 00045 { 00046 EIGEN_DEVICE_FUNC 00047 static inline void run(const Derived& mat, Visitor& visitor) 00048 { 00049 visitor.init(mat.coeff(0,0), 0, 0); 00050 for(Index i = 1; i < mat.rows(); ++i) 00051 visitor(mat.coeff(i, 0), i, 0); 00052 for(Index j = 1; j < mat.cols(); ++j) 00053 for(Index i = 0; i < mat.rows(); ++i) 00054 visitor(mat.coeff(i, j), i, j); 00055 } 00056 }; 00057 00058 // evaluator adaptor 00059 template<typename XprType> 00060 class visitor_evaluator 00061 { 00062 public: 00063 EIGEN_DEVICE_FUNC 00064 explicit visitor_evaluator(const XprType &xpr) : m_evaluator(xpr), m_xpr(xpr) {} 00065 00066 typedef typename XprType::Scalar Scalar; 00067 typedef typename XprType::CoeffReturnType CoeffReturnType; 00068 00069 enum { 00070 RowsAtCompileTime = XprType::RowsAtCompileTime, 00071 CoeffReadCost = internal::evaluator<XprType>::CoeffReadCost 00072 }; 00073 00074 EIGEN_DEVICE_FUNC Index rows() const { return m_xpr.rows(); } 00075 EIGEN_DEVICE_FUNC Index cols() const { return m_xpr.cols(); } 00076 EIGEN_DEVICE_FUNC Index size() const { return m_xpr.size(); } 00077 00078 EIGEN_DEVICE_FUNC CoeffReturnType coeff(Index row, Index col) const 00079 { return m_evaluator.coeff(row, col); } 00080 00081 protected: 00082 internal::evaluator<XprType> m_evaluator; 00083 const XprType &m_xpr; 00084 }; 00085 } // end namespace internal 00086 00104 template<typename Derived> 00105 template<typename Visitor> 00106 EIGEN_DEVICE_FUNC 00107 void DenseBase<Derived>::visit(Visitor& visitor) const 00108 { 00109 typedef typename internal::visitor_evaluator<Derived> ThisEvaluator; 00110 ThisEvaluator thisEval(derived()); 00111 00112 enum { 00113 unroll = SizeAtCompileTime != Dynamic 00114 && SizeAtCompileTime * ThisEvaluator::CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost <= EIGEN_UNROLLING_LIMIT 00115 }; 00116 return internal::visitor_impl<Visitor, ThisEvaluator, unroll ? int(SizeAtCompileTime) : Dynamic>::run(thisEval, visitor); 00117 } 00118 00119 namespace internal { 00120 00124 template <typename Derived> 00125 struct coeff_visitor 00126 { 00127 typedef typename Derived::Scalar Scalar; 00128 Index row, col; 00129 Scalar res; 00130 EIGEN_DEVICE_FUNC 00131 inline void init(const Scalar& value, Index i, Index j) 00132 { 00133 res = value; 00134 row = i; 00135 col = j; 00136 } 00137 }; 00138 00144 template <typename Derived> 00145 struct min_coeff_visitor : coeff_visitor<Derived> 00146 { 00147 typedef typename Derived::Scalar Scalar; 00148 EIGEN_DEVICE_FUNC 00149 void operator() (const Scalar& value, Index i, Index j) 00150 { 00151 if(value < this->res) 00152 { 00153 this->res = value; 00154 this->row = i; 00155 this->col = j; 00156 } 00157 } 00158 }; 00159 00160 template<typename Scalar> 00161 struct functor_traits<min_coeff_visitor<Scalar> > { 00162 enum { 00163 Cost = NumTraits<Scalar>::AddCost 00164 }; 00165 }; 00166 00172 template <typename Derived> 00173 struct max_coeff_visitor : coeff_visitor<Derived> 00174 { 00175 typedef typename Derived::Scalar Scalar; 00176 EIGEN_DEVICE_FUNC 00177 void operator() (const Scalar& value, Index i, Index j) 00178 { 00179 if(value > this->res) 00180 { 00181 this->res = value; 00182 this->row = i; 00183 this->col = j; 00184 } 00185 } 00186 }; 00187 00188 template<typename Scalar> 00189 struct functor_traits<max_coeff_visitor<Scalar> > { 00190 enum { 00191 Cost = NumTraits<Scalar>::AddCost 00192 }; 00193 }; 00194 00195 } // end namespace internal 00196 00203 template<typename Derived> 00204 template<typename IndexType> 00205 EIGEN_DEVICE_FUNC 00206 typename internal::traits<Derived>::Scalar 00207 DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const 00208 { 00209 internal::min_coeff_visitor<Derived> minVisitor; 00210 this->visit(minVisitor); 00211 *rowId = minVisitor.row; 00212 if (colId) *colId = minVisitor.col; 00213 return minVisitor.res; 00214 } 00215 00221 template<typename Derived> 00222 template<typename IndexType> 00223 EIGEN_DEVICE_FUNC 00224 typename internal::traits<Derived>::Scalar 00225 DenseBase<Derived>::minCoeff(IndexType* index) const 00226 { 00227 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) 00228 internal::min_coeff_visitor<Derived> minVisitor; 00229 this->visit(minVisitor); 00230 *index = IndexType((RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row); 00231 return minVisitor.res; 00232 } 00233 00240 template<typename Derived> 00241 template<typename IndexType> 00242 EIGEN_DEVICE_FUNC 00243 typename internal::traits<Derived>::Scalar 00244 DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const 00245 { 00246 internal::max_coeff_visitor<Derived> maxVisitor; 00247 this->visit(maxVisitor); 00248 *rowPtr = maxVisitor.row; 00249 if (colPtr) *colPtr = maxVisitor.col; 00250 return maxVisitor.res; 00251 } 00252 00258 template<typename Derived> 00259 template<typename IndexType> 00260 EIGEN_DEVICE_FUNC 00261 typename internal::traits<Derived>::Scalar 00262 DenseBase<Derived>::maxCoeff(IndexType* index) const 00263 { 00264 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) 00265 internal::max_coeff_visitor<Derived> maxVisitor; 00266 this->visit(maxVisitor); 00267 *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row; 00268 return maxVisitor.res; 00269 } 00270 00271 } // end namespace Eigen 00272 00273 #endif // EIGEN_VISITOR_H