Merge of itasc branch. Project files, scons and cmake should be working. Makefile...
[blender.git] / extern / Eigen2 / Eigen / src / Core / Redux.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 // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
6 //
7 // Eigen is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU Lesser General Public
9 // License as published by the Free Software Foundation; either
10 // version 3 of the License, or (at your option) any later version.
11 //
12 // Alternatively, you can redistribute it and/or
13 // modify it under the terms of the GNU General Public License as
14 // published by the Free Software Foundation; either version 2 of
15 // the License, or (at your option) any later version.
16 //
17 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
18 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
19 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
20 // GNU General Public License for more details.
21 //
22 // You should have received a copy of the GNU Lesser General Public
23 // License and a copy of the GNU General Public License along with
24 // Eigen. If not, see <http://www.gnu.org/licenses/>.
25
26 #ifndef EIGEN_REDUX_H
27 #define EIGEN_REDUX_H
28
29 template<typename BinaryOp, typename Derived, int Start, int Length>
30 struct ei_redux_impl
31 {
32   enum {
33     HalfLength = Length/2
34   };
35
36   typedef typename ei_result_of<BinaryOp(typename Derived::Scalar)>::type Scalar;
37
38   static Scalar run(const Derived &mat, const BinaryOp& func)
39   {
40     return func(
41       ei_redux_impl<BinaryOp, Derived, Start, HalfLength>::run(mat, func),
42       ei_redux_impl<BinaryOp, Derived, Start+HalfLength, Length - HalfLength>::run(mat, func));
43   }
44 };
45
46 template<typename BinaryOp, typename Derived, int Start>
47 struct ei_redux_impl<BinaryOp, Derived, Start, 1>
48 {
49   enum {
50     col = Start / Derived::RowsAtCompileTime,
51     row = Start % Derived::RowsAtCompileTime
52   };
53
54   typedef typename ei_result_of<BinaryOp(typename Derived::Scalar)>::type Scalar;
55
56   static Scalar run(const Derived &mat, const BinaryOp &)
57   {
58     return mat.coeff(row, col);
59   }
60 };
61
62 template<typename BinaryOp, typename Derived, int Start>
63 struct ei_redux_impl<BinaryOp, Derived, Start, Dynamic>
64 {
65   typedef typename ei_result_of<BinaryOp(typename Derived::Scalar)>::type Scalar;
66   static Scalar run(const Derived& mat, const BinaryOp& func)
67   {
68     ei_assert(mat.rows()>0 && mat.cols()>0 && "you are using a non initialized matrix");
69     Scalar res;
70     res = mat.coeff(0,0);
71     for(int i = 1; i < mat.rows(); ++i)
72       res = func(res, mat.coeff(i, 0));
73     for(int j = 1; j < mat.cols(); ++j)
74       for(int i = 0; i < mat.rows(); ++i)
75         res = func(res, mat.coeff(i, j));
76     return res;
77   }
78 };
79
80 /** \returns the result of a full redux operation on the whole matrix or vector using \a func
81   *
82   * The template parameter \a BinaryOp is the type of the functor \a func which must be
83   * an assiociative operator. Both current STL and TR1 functor styles are handled.
84   *
85   * \sa MatrixBase::sum(), MatrixBase::minCoeff(), MatrixBase::maxCoeff(), MatrixBase::colwise(), MatrixBase::rowwise()
86   */
87 template<typename Derived>
88 template<typename BinaryOp>
89 typename ei_result_of<BinaryOp(typename ei_traits<Derived>::Scalar)>::type
90 MatrixBase<Derived>::redux(const BinaryOp& func) const
91 {
92   const bool unroll = SizeAtCompileTime * CoeffReadCost
93                     + (SizeAtCompileTime-1) * ei_functor_traits<BinaryOp>::Cost
94                     <= EIGEN_UNROLLING_LIMIT;
95   return ei_redux_impl<BinaryOp, Derived, 0, unroll ? int(SizeAtCompileTime) : Dynamic>
96             ::run(derived(), func);
97 }
98
99 /** \returns the minimum of all coefficients of *this
100   */
101 template<typename Derived>
102 inline typename ei_traits<Derived>::Scalar
103 MatrixBase<Derived>::minCoeff() const
104 {
105   return this->redux(Eigen::ei_scalar_min_op<Scalar>());
106 }
107
108 /** \returns the maximum of all coefficients of *this
109   */
110 template<typename Derived>
111 inline typename ei_traits<Derived>::Scalar
112 MatrixBase<Derived>::maxCoeff() const
113 {
114   return this->redux(Eigen::ei_scalar_max_op<Scalar>());
115 }
116
117 #endif // EIGEN_REDUX_H