$treeview $search $mathjax
Eigen
3.2.5
$projectbrief
|
$projectbrief
|
$searchbox |
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 static inline void run(const Derived &mat, Visitor& visitor) 00026 { 00027 visitor_impl<Visitor, Derived, UnrollCount-1>::run(mat, visitor); 00028 visitor(mat.coeff(row, col), row, col); 00029 } 00030 }; 00031 00032 template<typename Visitor, typename Derived> 00033 struct visitor_impl<Visitor, Derived, 1> 00034 { 00035 static inline void run(const Derived &mat, Visitor& visitor) 00036 { 00037 return visitor.init(mat.coeff(0, 0), 0, 0); 00038 } 00039 }; 00040 00041 template<typename Visitor, typename Derived> 00042 struct visitor_impl<Visitor, Derived, Dynamic> 00043 { 00044 typedef typename Derived::Index Index; 00045 static inline void run(const Derived& mat, Visitor& visitor) 00046 { 00047 visitor.init(mat.coeff(0,0), 0, 0); 00048 for(Index i = 1; i < mat.rows(); ++i) 00049 visitor(mat.coeff(i, 0), i, 0); 00050 for(Index j = 1; j < mat.cols(); ++j) 00051 for(Index i = 0; i < mat.rows(); ++i) 00052 visitor(mat.coeff(i, j), i, j); 00053 } 00054 }; 00055 00056 } // end namespace internal 00057 00075 template<typename Derived> 00076 template<typename Visitor> 00077 void DenseBase<Derived>::visit(Visitor& visitor) const 00078 { 00079 enum { unroll = SizeAtCompileTime != Dynamic 00080 && CoeffReadCost != Dynamic 00081 && (SizeAtCompileTime == 1 || internal::functor_traits<Visitor>::Cost != Dynamic) 00082 && SizeAtCompileTime * CoeffReadCost + (SizeAtCompileTime-1) * internal::functor_traits<Visitor>::Cost 00083 <= EIGEN_UNROLLING_LIMIT }; 00084 return internal::visitor_impl<Visitor, Derived, 00085 unroll ? int(SizeAtCompileTime) : Dynamic 00086 >::run(derived(), visitor); 00087 } 00088 00089 namespace internal { 00090 00094 template <typename Derived> 00095 struct coeff_visitor 00096 { 00097 typedef typename Derived::Index Index; 00098 typedef typename Derived::Scalar Scalar; 00099 Index row, col; 00100 Scalar res; 00101 inline void init(const Scalar& value, Index i, Index j) 00102 { 00103 res = value; 00104 row = i; 00105 col = j; 00106 } 00107 }; 00108 00114 template <typename Derived> 00115 struct min_coeff_visitor : coeff_visitor<Derived> 00116 { 00117 typedef typename Derived::Index Index; 00118 typedef typename Derived::Scalar Scalar; 00119 void operator() (const Scalar& value, Index i, Index j) 00120 { 00121 if(value < this->res) 00122 { 00123 this->res = value; 00124 this->row = i; 00125 this->col = j; 00126 } 00127 } 00128 }; 00129 00130 template<typename Scalar> 00131 struct functor_traits<min_coeff_visitor<Scalar> > { 00132 enum { 00133 Cost = NumTraits<Scalar>::AddCost 00134 }; 00135 }; 00136 00142 template <typename Derived> 00143 struct max_coeff_visitor : coeff_visitor<Derived> 00144 { 00145 typedef typename Derived::Index Index; 00146 typedef typename Derived::Scalar Scalar; 00147 void operator() (const Scalar& value, Index i, Index j) 00148 { 00149 if(value > this->res) 00150 { 00151 this->res = value; 00152 this->row = i; 00153 this->col = j; 00154 } 00155 } 00156 }; 00157 00158 template<typename Scalar> 00159 struct functor_traits<max_coeff_visitor<Scalar> > { 00160 enum { 00161 Cost = NumTraits<Scalar>::AddCost 00162 }; 00163 }; 00164 00165 } // end namespace internal 00166 00172 template<typename Derived> 00173 template<typename IndexType> 00174 typename internal::traits<Derived>::Scalar 00175 DenseBase<Derived>::minCoeff(IndexType* rowId, IndexType* colId) const 00176 { 00177 internal::min_coeff_visitor<Derived> minVisitor; 00178 this->visit(minVisitor); 00179 *rowId = minVisitor.row; 00180 if (colId) *colId = minVisitor.col; 00181 return minVisitor.res; 00182 } 00183 00189 template<typename Derived> 00190 template<typename IndexType> 00191 typename internal::traits<Derived>::Scalar 00192 DenseBase<Derived>::minCoeff(IndexType* index) const 00193 { 00194 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) 00195 internal::min_coeff_visitor<Derived> minVisitor; 00196 this->visit(minVisitor); 00197 *index = (RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row; 00198 return minVisitor.res; 00199 } 00200 00206 template<typename Derived> 00207 template<typename IndexType> 00208 typename internal::traits<Derived>::Scalar 00209 DenseBase<Derived>::maxCoeff(IndexType* rowPtr, IndexType* colPtr) const 00210 { 00211 internal::max_coeff_visitor<Derived> maxVisitor; 00212 this->visit(maxVisitor); 00213 *rowPtr = maxVisitor.row; 00214 if (colPtr) *colPtr = maxVisitor.col; 00215 return maxVisitor.res; 00216 } 00217 00223 template<typename Derived> 00224 template<typename IndexType> 00225 typename internal::traits<Derived>::Scalar 00226 DenseBase<Derived>::maxCoeff(IndexType* index) const 00227 { 00228 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) 00229 internal::max_coeff_visitor<Derived> maxVisitor; 00230 this->visit(maxVisitor); 00231 *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row; 00232 return maxVisitor.res; 00233 } 00234 00235 } // end namespace Eigen 00236 00237 #endif // EIGEN_VISITOR_H