Merge of itasc branch. Project files, scons and cmake should be working. Makefile...
[blender.git] / extern / Eigen2 / Eigen / src / Core / Visitor.h
1 // This file is part of Eigen, a lightweight C++ template library
2 // for linear algebra. Eigen itself is part of the KDE project.
3 //
4 // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
5 //
6 // Eigen is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU Lesser General Public
8 // License as published by the Free Software Foundation; either
9 // version 3 of the License, or (at your option) any later version.
10 //
11 // Alternatively, you can redistribute it and/or
12 // modify it under the terms of the GNU General Public License as
13 // published by the Free Software Foundation; either version 2 of
14 // the License, or (at your option) any later version.
15 //
16 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
17 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
18 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
19 // GNU General Public License for more details.
20 //
21 // You should have received a copy of the GNU Lesser General Public
22 // License and a copy of the GNU General Public License along with
23 // Eigen. If not, see <http://www.gnu.org/licenses/>.
24
25 #ifndef EIGEN_VISITOR_H
26 #define EIGEN_VISITOR_H
27
28 template<typename Visitor, typename Derived, int UnrollCount>
29 struct ei_visitor_impl
30 {
31   enum {
32     col = (UnrollCount-1) / Derived::RowsAtCompileTime,
33     row = (UnrollCount-1) % Derived::RowsAtCompileTime
34   };
35
36   inline static void run(const Derived &mat, Visitor& visitor)
37   {
38     ei_visitor_impl<Visitor, Derived, UnrollCount-1>::run(mat, visitor);
39     visitor(mat.coeff(row, col), row, col);
40   }
41 };
42
43 template<typename Visitor, typename Derived>
44 struct ei_visitor_impl<Visitor, Derived, 1>
45 {
46   inline static void run(const Derived &mat, Visitor& visitor)
47   {
48     return visitor.init(mat.coeff(0, 0), 0, 0);
49   }
50 };
51
52 template<typename Visitor, typename Derived>
53 struct ei_visitor_impl<Visitor, Derived, Dynamic>
54 {
55   inline static void run(const Derived& mat, Visitor& visitor)
56   {
57     visitor.init(mat.coeff(0,0), 0, 0);
58     for(int i = 1; i < mat.rows(); ++i)
59       visitor(mat.coeff(i, 0), i, 0);
60     for(int j = 1; j < mat.cols(); ++j)
61       for(int i = 0; i < mat.rows(); ++i)
62         visitor(mat.coeff(i, j), i, j);
63   }
64 };
65
66
67 /** Applies the visitor \a visitor to the whole coefficients of the matrix or vector.
68   *
69   * The template parameter \a Visitor is the type of the visitor and provides the following interface:
70   * \code
71   * struct MyVisitor {
72   *   // called for the first coefficient
73   *   void init(const Scalar& value, int i, int j);
74   *   // called for all other coefficients
75   *   void operator() (const Scalar& value, int i, int j);
76   * };
77   * \endcode
78   *
79   * \note compared to one or two \em for \em loops, visitors offer automatic
80   * unrolling for small fixed size matrix.
81   *
82   * \sa minCoeff(int*,int*), maxCoeff(int*,int*), MatrixBase::redux()
83   */
84 template<typename Derived>
85 template<typename Visitor>
86 void MatrixBase<Derived>::visit(Visitor& visitor) const
87 {
88   const bool unroll = SizeAtCompileTime * CoeffReadCost
89                     + (SizeAtCompileTime-1) * ei_functor_traits<Visitor>::Cost
90                     <= EIGEN_UNROLLING_LIMIT;
91   return ei_visitor_impl<Visitor, Derived,
92       unroll ? int(SizeAtCompileTime) : Dynamic
93     >::run(derived(), visitor);
94 }
95
96 /** \internal
97   * \brief Base class to implement min and max visitors
98   */
99 template <typename Scalar>
100 struct ei_coeff_visitor
101 {
102   int row, col;
103   Scalar res;
104   inline void init(const Scalar& value, int i, int j)
105   {
106     res = value;
107     row = i;
108     col = j;
109   }
110 };
111
112 /** \internal
113   * \brief Visitor computing the min coefficient with its value and coordinates
114   *
115   * \sa MatrixBase::minCoeff(int*, int*)
116   */
117 template <typename Scalar>
118 struct ei_min_coeff_visitor : ei_coeff_visitor<Scalar>
119 {
120   void operator() (const Scalar& value, int i, int j)
121   {
122     if(value < this->res)
123     {
124       this->res = value;
125       this->row = i;
126       this->col = j;
127     }
128   }
129 };
130
131 template<typename Scalar>
132 struct ei_functor_traits<ei_min_coeff_visitor<Scalar> > {
133   enum {
134     Cost = NumTraits<Scalar>::AddCost
135   };
136 };
137
138 /** \internal
139   * \brief Visitor computing the max coefficient with its value and coordinates
140   *
141   * \sa MatrixBase::maxCoeff(int*, int*)
142   */
143 template <typename Scalar>
144 struct ei_max_coeff_visitor : ei_coeff_visitor<Scalar>
145 {
146   void operator() (const Scalar& value, int i, int j)
147   {
148     if(value > this->res)
149     {
150       this->res = value;
151       this->row = i;
152       this->col = j;
153     }
154   }
155 };
156
157 template<typename Scalar>
158 struct ei_functor_traits<ei_max_coeff_visitor<Scalar> > {
159   enum {
160     Cost = NumTraits<Scalar>::AddCost
161   };
162 };
163
164 /** \returns the minimum of all coefficients of *this
165   * and puts in *row and *col its location.
166   *
167   * \sa MatrixBase::minCoeff(int*), MatrixBase::maxCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::minCoeff()
168   */
169 template<typename Derived>
170 typename ei_traits<Derived>::Scalar
171 MatrixBase<Derived>::minCoeff(int* row, int* col) const
172 {
173   ei_min_coeff_visitor<Scalar> minVisitor;
174   this->visit(minVisitor);
175   *row = minVisitor.row;
176   if (col) *col = minVisitor.col;
177   return minVisitor.res;
178 }
179
180 /** \returns the minimum of all coefficients of *this
181   * and puts in *index its location.
182   *
183   * \sa MatrixBase::minCoeff(int*,int*), MatrixBase::maxCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::minCoeff()
184   */
185 template<typename Derived>
186 typename ei_traits<Derived>::Scalar
187 MatrixBase<Derived>::minCoeff(int* index) const
188 {
189   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
190   ei_min_coeff_visitor<Scalar> minVisitor;
191   this->visit(minVisitor);
192   *index = (RowsAtCompileTime==1) ? minVisitor.col : minVisitor.row;
193   return minVisitor.res;
194 }
195
196 /** \returns the maximum of all coefficients of *this
197   * and puts in *row and *col its location.
198   *
199   * \sa MatrixBase::minCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::maxCoeff()
200   */
201 template<typename Derived>
202 typename ei_traits<Derived>::Scalar
203 MatrixBase<Derived>::maxCoeff(int* row, int* col) const
204 {
205   ei_max_coeff_visitor<Scalar> maxVisitor;
206   this->visit(maxVisitor);
207   *row = maxVisitor.row;
208   if (col) *col = maxVisitor.col;
209   return maxVisitor.res;
210 }
211
212 /** \returns the maximum of all coefficients of *this
213   * and puts in *index its location.
214   *
215   * \sa MatrixBase::maxCoeff(int*,int*), MatrixBase::minCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::maxCoeff()
216   */
217 template<typename Derived>
218 typename ei_traits<Derived>::Scalar
219 MatrixBase<Derived>::maxCoeff(int* index) const
220 {
221   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
222   ei_max_coeff_visitor<Scalar> maxVisitor;
223   this->visit(maxVisitor);
224   *index = (RowsAtCompileTime==1) ? maxVisitor.col : maxVisitor.row;
225   return maxVisitor.res;
226 }
227
228 #endif // EIGEN_VISITOR_H