aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2008-03-16 14:36:25 +0000
committerGravatar Gael Guennebaud <g.gael@free.fr>2008-03-16 14:36:25 +0000
commit612350e3f85998c25d1155ec4d8a38c623f9457c (patch)
tree1f6086a94b5b4be8885e67bb275b428d23f9c452
parent29184ad27df1b398d4619dea78d0fb8aee445c1f (diff)
* Added a generic *redux* mini framework allowing custom redux operations
as well as partial redux (vertical or horizontal redux). Includes shortcuts for: sum, minCoeff and maxCoeff. There is no shortcut for the partial redux. * Added a generic *visitor* mini framework. A visitor is a custom object sequentially applied on each coefficient with knowledge of its value and coordinates. It is currentlly used to implement minCoeff(int*,int*) and maxCoeff(int*,int*). findBiggestCoeff is now a shortcut for "this->cwiseAbs().maxCoeff(i,j)" * Added coeff-wise min and max. * fixed an issue with ei_pow(int,int) and gcc < 4.3 or ICC
-rw-r--r--Eigen/Core4
-rw-r--r--Eigen/src/Core/AssociativeFunctors.h64
-rw-r--r--Eigen/src/Core/CwiseBinaryOp.h42
-rw-r--r--Eigen/src/Core/ForwardDeclarations.h3
-rw-r--r--Eigen/src/Core/MathFunctions.h10
-rw-r--r--Eigen/src/Core/MatrixBase.h59
-rw-r--r--Eigen/src/Core/Redux.h232
-rw-r--r--Eigen/src/Core/SumOfCoeffs.h102
-rw-r--r--Eigen/src/Core/Util.h2
-rw-r--r--Eigen/src/Core/Visitor.h182
10 files changed, 554 insertions, 146 deletions
diff --git a/Eigen/Core b/Eigen/Core
index 87b4c7766..f56a13ab8 100644
--- a/Eigen/Core
+++ b/Eigen/Core
@@ -31,12 +31,14 @@ namespace Eigen {
#include "src/Core/DiagonalMatrix.h"
#include "src/Core/DiagonalCoeffs.h"
#include "src/Core/Identity.h"
-#include "src/Core/SumOfCoeffs.h"
+#include "src/Core/Redux.h"
+#include "src/Core/Visitor.h"
#include "src/Core/Fuzzy.h"
#include "src/Core/Map.h"
#include "src/Core/IO.h"
#include "src/Core/Swap.h"
#include "src/Core/CommaInitializer.h"
+#include "src/Core/AssociativeFunctors.h"
#include "src/Core/EvalOMP.h"
} // namespace Eigen
diff --git a/Eigen/src/Core/AssociativeFunctors.h b/Eigen/src/Core/AssociativeFunctors.h
new file mode 100644
index 000000000..106549f75
--- /dev/null
+++ b/Eigen/src/Core/AssociativeFunctors.h
@@ -0,0 +1,64 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 3 of the License, or (at your option) any later version.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_ASSOCIATIVE_FUNCTORS_H
+#define EIGEN_ASSOCIATIVE_FUNCTORS_H
+
+/** \internal
+ * \brief Template functor to compute the sum of two scalars
+ *
+ * \sa class CwiseBinaryOp, MatrixBase::operator+, class PartialRedux, MatrixBase::sum()
+ */
+struct ei_scalar_sum_op EIGEN_EMPTY_STRUCT {
+ template<typename Scalar> Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; }
+};
+
+/** \internal
+ * \brief Template functor to compute the product of two scalars
+ *
+ * \sa class CwiseBinaryOp, MatrixBase::cwiseProduct(), class PartialRedux, MatrixBase::redux()
+ */
+struct ei_scalar_product_op EIGEN_EMPTY_STRUCT {
+ template<typename Scalar> Scalar operator() (const Scalar& a, const Scalar& b) const { return a * b; }
+};
+
+/** \internal
+ * \brief Template functor to compute the min of two scalars
+ *
+ * \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class PartialRedux, MatrixBase::minCoeff()
+ */
+struct ei_scalar_min_op EIGEN_EMPTY_STRUCT {
+ template<typename Scalar> Scalar operator() (const Scalar& a, const Scalar& b) const { return ei_min(a, b); }
+};
+
+/** \internal
+ * \brief Template functor to compute the max of two scalars
+ *
+ * \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class PartialRedux, MatrixBase::maxCoeff()
+ */
+struct ei_scalar_max_op EIGEN_EMPTY_STRUCT {
+ template<typename Scalar> Scalar operator() (const Scalar& a, const Scalar& b) const { return ei_max(a, b); }
+};
+
+#endif // EIGEN_ASSOCIATIVE_FUNCTORS_H
diff --git a/Eigen/src/Core/CwiseBinaryOp.h b/Eigen/src/Core/CwiseBinaryOp.h
index 131e98362..1ab759241 100644
--- a/Eigen/src/Core/CwiseBinaryOp.h
+++ b/Eigen/src/Core/CwiseBinaryOp.h
@@ -94,15 +94,6 @@ class CwiseBinaryOp : ei_no_assignment_operator,
};
/** \internal
- * \brief Template functor to compute the sum of two scalars
- *
- * \sa class CwiseBinaryOp, MatrixBase::operator+
- */
-struct ei_scalar_sum_op EIGEN_EMPTY_STRUCT {
- template<typename Scalar> Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; }
-};
-
-/** \internal
* \brief Template functor to compute the difference of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::operator-
@@ -112,15 +103,6 @@ struct ei_scalar_difference_op EIGEN_EMPTY_STRUCT {
};
/** \internal
- * \brief Template functor to compute the product of two scalars
- *
- * \sa class CwiseBinaryOp, MatrixBase::cwiseProduct()
- */
-struct ei_scalar_product_op EIGEN_EMPTY_STRUCT {
- template<typename Scalar> Scalar operator() (const Scalar& a, const Scalar& b) const { return a * b; }
-};
-
-/** \internal
* \brief Template functor to compute the quotient of two scalars
*
* \sa class CwiseBinaryOp, MatrixBase::cwiseQuotient()
@@ -203,6 +185,30 @@ MatrixBase<Derived>::cwiseQuotient(const MatrixBase<OtherDerived> &other) const
return CwiseBinaryOp<ei_scalar_quotient_op, Derived, OtherDerived>(derived(), other.derived());
}
+/** \returns an expression of the coefficient-wise min of *this and \a other
+ *
+ * \sa class CwiseBinaryOp
+ */
+template<typename Derived>
+template<typename OtherDerived>
+const CwiseBinaryOp<ei_scalar_min_op, Derived, OtherDerived>
+MatrixBase<Derived>::cwiseMin(const MatrixBase<OtherDerived> &other) const
+{
+ return CwiseBinaryOp<ei_scalar_min_op, Derived, OtherDerived>(derived(), other.derived());
+}
+
+/** \returns an expression of the coefficient-wise max of *this and \a other
+ *
+ * \sa class CwiseBinaryOp
+ */
+template<typename Derived>
+template<typename OtherDerived>
+const CwiseBinaryOp<ei_scalar_max_op, Derived, OtherDerived>
+MatrixBase<Derived>::cwiseMax(const MatrixBase<OtherDerived> &other) const
+{
+ return CwiseBinaryOp<ei_scalar_max_op, Derived, OtherDerived>(derived(), other.derived());
+}
+
/** \returns an expression of a custom coefficient-wise operator \a func of *this and \a other
*
* The template parameter \a CustomBinaryOp is the type of the functor
diff --git a/Eigen/src/Core/ForwardDeclarations.h b/Eigen/src/Core/ForwardDeclarations.h
index 69b8cab7b..9e0bbe2e6 100644
--- a/Eigen/src/Core/ForwardDeclarations.h
+++ b/Eigen/src/Core/ForwardDeclarations.h
@@ -45,6 +45,7 @@ template<typename MatrixType> class Identity;
template<typename MatrixType> class Map;
template<typename Derived> class Eval;
template<typename Derived> class EvalOMP;
+template<int Direction, typename UnaryOp, typename MatrixType> class PartialRedux;
struct ei_scalar_sum_op;
struct ei_scalar_difference_op;
@@ -62,6 +63,8 @@ struct ei_scalar_sin_op;
template<typename Scalar> struct ei_scalar_pow_op;
template<typename NewType> struct ei_scalar_cast_op;
template<typename Scalar> struct ei_scalar_multiple_op;
+struct ei_scalar_min_op;
+struct ei_scalar_max_op;
template<typename T> struct ei_xpr_copy
{
diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h
index 13bd549f4..a1a54cc38 100644
--- a/Eigen/src/Core/MathFunctions.h
+++ b/Eigen/src/Core/MathFunctions.h
@@ -5,12 +5,12 @@
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
+// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of
+// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
@@ -18,7 +18,7 @@
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
-// You should have received a copy of the GNU Lesser General Public
+// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
@@ -40,7 +40,11 @@ inline int ei_exp(int) { assert(false); return 0; }
inline int ei_log(int) { assert(false); return 0; }
inline int ei_sin(int) { assert(false); return 0; }
inline int ei_cos(int) { assert(false); return 0; }
+#if (defined __ICC) || (defined __GNUC__ && (__GNUC__<4 || __GNUC_MINOR__<3))
+inline int ei_pow(int x, int y) { return int(std::pow(double(x), y)); }
+#else
inline int ei_pow(int x, int y) { return std::pow(x, y); }
+#endif
template<> inline int ei_random(int a, int b)
{
diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h
index 95fc05b8e..f3be4977f 100644
--- a/Eigen/src/Core/MatrixBase.h
+++ b/Eigen/src/Core/MatrixBase.h
@@ -81,7 +81,7 @@ template<typename Derived> class MatrixBase
/**< This is equal to the number of coefficients, i.e. the number of
* rows times the number of columns, or to \a Dynamic if this is not
* known at compile-time. \sa RowsAtCompileTime, ColsAtCompileTime */
-
+
MaxRowsAtCompileTime = ei_traits<Derived>::MaxRowsAtCompileTime,
/**< This value is equal to the maximum possible number of rows that this expression
* might have. If this expression might have an arbitrarily high number of rows,
@@ -245,13 +245,6 @@ template<typename Derived> class MatrixBase
Derived& operator*=(const MatrixBase<OtherDerived>& other);
//@}
- /** \name Sums of coefficients
- */
- //@{
- Scalar sum() const;
- Scalar trace() const;
- //@}
-
/** \name Dot product and related notions
* including vector norm, adjoint, transpose ...
*/
@@ -350,20 +343,7 @@ template<typename Derived> class MatrixBase
* which has the biggest absolute value.
*/
void findBiggestCoeff(int *row, int *col) const
- {
- RealScalar biggest = 0;
- for(int j = 0; j < cols(); j++)
- for(int i = 0; i < rows(); i++)
- {
- RealScalar x = ei_abs(coeff(i,j));
- if(x > biggest)
- {
- biggest = x;
- *row = i;
- *col = j;
- }
- }
- }
+ { (*this).cwiseAbs().maxCoeff(row, col); }
//@}
/// \name Special functions
@@ -396,6 +376,14 @@ template<typename Derived> class MatrixBase
const CwiseBinaryOp<ei_scalar_quotient_op, Derived, OtherDerived>
cwiseQuotient(const MatrixBase<OtherDerived> &other) const;
+ template<typename OtherDerived>
+ const CwiseBinaryOp<ei_scalar_min_op, Derived, OtherDerived>
+ cwiseMin(const MatrixBase<OtherDerived> &other) const;
+
+ template<typename OtherDerived>
+ const CwiseBinaryOp<ei_scalar_max_op, Derived, OtherDerived>
+ cwiseMax(const MatrixBase<OtherDerived> &other) const;
+
const CwiseUnaryOp<ei_scalar_abs_op, Derived> cwiseAbs() const;
const CwiseUnaryOp<ei_scalar_abs2_op, Derived> cwiseAbs2() const;
const CwiseUnaryOp<ei_scalar_sqrt_op, Derived> cwiseSqrt() const;
@@ -414,6 +402,33 @@ template<typename Derived> class MatrixBase
cwise(const MatrixBase<OtherDerived> &other, const CustomBinaryOp& func = CustomBinaryOp()) const;
//@}
+ /// \name Redux and visitor
+ //@{
+ Scalar sum() const;
+ Scalar trace() const;
+
+ typename ei_traits<Derived>::Scalar minCoeff() const;
+ typename ei_traits<Derived>::Scalar maxCoeff() const;
+
+ typename ei_traits<Derived>::Scalar minCoeff(int* row, int* col = 0) const;
+ typename ei_traits<Derived>::Scalar maxCoeff(int* row, int* col = 0) const;
+
+ template<typename BinaryOp>
+ const PartialRedux<Vertical, BinaryOp, Derived>
+ verticalRedux(const BinaryOp& func) const;
+
+ template<typename BinaryOp>
+ const PartialRedux<Horizontal, BinaryOp, Derived>
+ horizontalRedux(const BinaryOp& func) const;
+
+ template<typename BinaryOp>
+ typename ei_result_of<BinaryOp(typename ei_traits<Derived>::Scalar)>::type
+ redux(const BinaryOp& func) const;
+
+ template<typename Visitor>
+ void visit(Visitor& func) const;
+ //@}
+
/// \name Casting to the derived type
//@{
const Derived& derived() const { return *static_cast<const Derived*>(this); }
diff --git a/Eigen/src/Core/Redux.h b/Eigen/src/Core/Redux.h
new file mode 100644
index 000000000..fa1f0e652
--- /dev/null
+++ b/Eigen/src/Core/Redux.h
@@ -0,0 +1,232 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+// Copyright (C) 2006-2008 Benoit Jacob <jacob@math.jussieu.fr>
+//
+// Eigen is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 3 of the License, or (at your option) any later version.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_REDUX_H
+#define EIGEN_REDUX_H
+
+
+template<typename BinaryOp, typename Derived, int Start, int Length>
+struct ei_redux_unroller
+{
+ enum {
+ HalfLength = Length/2
+ };
+
+ typedef typename ei_result_of<BinaryOp(typename Derived::Scalar)>::type Scalar;
+
+ static Scalar run(const Derived &mat, const BinaryOp& func)
+ {
+ return func(
+ ei_redux_unroller<BinaryOp, Derived, Start, HalfLength>::run(mat, func),
+ ei_redux_unroller<BinaryOp, Derived, Start+HalfLength, Length - HalfLength>::run(mat, func));
+ }
+};
+
+template<typename BinaryOp, typename Derived, int Start>
+struct ei_redux_unroller<BinaryOp, Derived, Start, 1>
+{
+ enum {
+ col = Start / Derived::RowsAtCompileTime,
+ row = Start % Derived::RowsAtCompileTime
+ };
+
+ typedef typename ei_result_of<BinaryOp(typename Derived::Scalar)>::type Scalar;
+
+ static Scalar run(const Derived &mat, const BinaryOp &func)
+ {
+ return mat.coeff(row, col);
+ }
+};
+
+template<typename BinaryOp, typename Derived, int Start>
+struct ei_redux_unroller<BinaryOp, Derived, Start, Dynamic>
+{
+ typedef typename ei_result_of<BinaryOp(typename Derived::Scalar)>::type Scalar;
+ static Scalar run(const Derived&, const BinaryOp&) { return Scalar(); }
+};
+
+
+/** \class PartialRedux
+ *
+ * \brief Generic expression of a partially reduxed matrix
+ *
+ * \param Direction indicates the direction of the redux (Vertical or Horizontal)
+ * \param BinaryOp type of the binary functor implementing the operator (must be associative)
+ * \param MatrixType the type of the matrix we are applying the redux operation
+ *
+ * This class represents an expression of a partial redux operator of a matrix.
+ * It is the return type of MatrixBase::verticalRedux(), MatrixBase::horizontalRedux(),
+ * and most of the time this is the only way it is used.
+ *
+ * \sa class CwiseBinaryOp
+ */
+template<int Direction, typename BinaryOp, typename MatrixType>
+struct ei_traits<PartialRedux<Direction, BinaryOp, MatrixType> >
+{
+ typedef typename ei_result_of<
+ BinaryOp(typename MatrixType::Scalar)
+ >::type Scalar;
+ enum {
+ RowsAtCompileTime = Direction==Vertical ? 1 : MatrixType::RowsAtCompileTime,
+ ColsAtCompileTime = Direction==Horizontal ? 1 : MatrixType::ColsAtCompileTime,
+ MaxRowsAtCompileTime = MatrixType::MaxRowsAtCompileTime,
+ MaxColsAtCompileTime = MatrixType::MaxColsAtCompileTime
+ };
+};
+
+template<int Direction, typename BinaryOp, typename MatrixType>
+class PartialRedux : ei_no_assignment_operator,
+ public MatrixBase<PartialRedux<Direction, BinaryOp, MatrixType> >
+{
+ public:
+
+ EIGEN_GENERIC_PUBLIC_INTERFACE(PartialRedux)
+
+ PartialRedux(const MatrixType& mat, const BinaryOp& func = BinaryOp())
+ : m_matrix(mat), m_functor(func) {}
+
+ private:
+
+ int _rows() const { return (Direction==Vertical ? 1 : m_matrix.rows()); }
+ int _cols() const { return (Direction==Horizontal ? 1 : m_matrix.cols()); }
+
+ Scalar _coeff(int i, int j) const
+ {
+ if (Direction==Vertical)
+ return this->col(j).redux(m_functor);
+ else
+ return this->row(i).redux(m_functor);
+ }
+
+ protected:
+ const typename MatrixType::XprCopy m_matrix;
+ const BinaryOp m_functor;
+};
+
+/** \returns a row vector expression of *this vertically reduxed by \a func
+ *
+ * The template parameter \a BinaryOp is the type of the functor
+ * of the custom redux operator. Note that func must be an associative operator.
+ *
+ * \sa class PartialRedux, MatrixBase::horizontalRedux()
+ */
+template<typename Derived>
+template<typename BinaryOp>
+const PartialRedux<Vertical, BinaryOp, Derived>
+MatrixBase<Derived>::verticalRedux(const BinaryOp& func) const
+{
+ return PartialRedux<Vertical, BinaryOp, Derived>(derived(), func);
+}
+
+/** \returns a row vector expression of *this horizontally reduxed by \a func
+ *
+ * The template parameter \a BinaryOp is the type of the functor
+ * of the custom redux operator. Note that func must be an associative operator.
+ *
+ * \sa class PartialRedux, MatrixBase::verticalRedux()
+ */
+template<typename Derived>
+template<typename BinaryOp>
+const PartialRedux<Horizontal, BinaryOp, Derived>
+MatrixBase<Derived>::horizontalRedux(const BinaryOp& func) const
+{
+ return PartialRedux<Horizontal, BinaryOp, Derived>(derived(), func);
+}
+
+
+/** \returns the result of a full redux operation on the whole matrix or vector using \a func
+ *
+ * The template parameter \a BinaryOp is the type of the functor \a func which must be
+ * an assiociative operator. Both current STL and TR1 functor styles are handled.
+ *
+ * \sa MatrixBase::sum(), MatrixBase::minCoeff(), MatrixBase::maxCoeff(), MatrixBase::verticalRedux(), MatrixBase::horizontalRedux()
+ */
+template<typename Derived>
+template<typename BinaryOp>
+typename ei_result_of<BinaryOp(typename ei_traits<Derived>::Scalar)>::type
+MatrixBase<Derived>::redux(const BinaryOp& func) const
+{
+ if(EIGEN_UNROLLED_LOOPS
+ && SizeAtCompileTime != Dynamic
+ && SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT)
+ return ei_redux_unroller<BinaryOp, Derived, 0,
+ (SizeAtCompileTime>0 && SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT) ?
+ SizeAtCompileTime : Dynamic>::run(derived(), func);
+ else
+ {
+ Scalar res;
+ res = coeff(0,0);
+ for(int i = 1; i < rows(); i++)
+ res = func(res, coeff(i, 0));
+ for(int j = 1; j < cols(); j++)
+ for(int i = 0; i < rows(); i++)
+ res = func(res, coeff(i, j));
+ return res;
+ }
+}
+
+/** \returns the sum of all coefficients of *this
+ *
+ * \sa trace()
+ */
+template<typename Derived>
+typename ei_traits<Derived>::Scalar
+MatrixBase<Derived>::sum() const
+{
+ return this->redux(Eigen::ei_scalar_sum_op());
+}
+
+/** \returns the trace of \c *this, i.e. the sum of the coefficients on the main diagonal.
+ *
+ * \c *this can be any matrix, not necessarily square.
+ *
+ * \sa diagonal(), sum()
+ */
+template<typename Derived>
+typename ei_traits<Derived>::Scalar
+MatrixBase<Derived>::trace() const
+{
+ return diagonal().sum();
+}
+
+/** \returns the minimum of all coefficients of *this
+ */
+template<typename Derived>
+typename ei_traits<Derived>::Scalar
+MatrixBase<Derived>::minCoeff() const
+{
+ return this->redux(Eigen::ei_scalar_min_op());
+}
+
+/** \returns the maximum of all coefficients of *this
+ */
+template<typename Derived>
+typename ei_traits<Derived>::Scalar
+MatrixBase<Derived>::maxCoeff() const
+{
+ return this->redux(Eigen::ei_scalar_max_op());
+}
+
+#endif // EIGEN_REDUX_H
diff --git a/Eigen/src/Core/SumOfCoeffs.h b/Eigen/src/Core/SumOfCoeffs.h
deleted file mode 100644
index 36e75d3e9..000000000
--- a/Eigen/src/Core/SumOfCoeffs.h
+++ /dev/null
@@ -1,102 +0,0 @@
-// This file is part of Eigen, a lightweight C++ template library
-// for linear algebra. Eigen itself is part of the KDE project.
-//
-// Copyright (C) 2006-2008 Benoit Jacob <jacob@math.jussieu.fr>
-//
-// Eigen is free software; you can redistribute it and/or
-// modify it under the terms of the GNU Lesser General Public
-// License as published by the Free Software Foundation; either
-// version 3 of the License, or (at your option) any later version.
-//
-// Alternatively, you can redistribute it and/or
-// modify it under the terms of the GNU General Public License as
-// published by the Free Software Foundation; either version 2 of
-// the License, or (at your option) any later version.
-//
-// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
-// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
-// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
-// GNU General Public License for more details.
-//
-// You should have received a copy of the GNU Lesser General Public
-// License and a copy of the GNU General Public License along with
-// Eigen. If not, see <http://www.gnu.org/licenses/>.
-
-#ifndef EIGEN_SUMOFCOEFFS_H
-#define EIGEN_SUMOFCOEFFS_H
-
-template<int Index, int Size, typename Derived>
-struct ei_sumofcoeffs_unroller
-{
- static void run(const Derived &v1, typename Derived::Scalar &dot)
- {
- ei_sumofcoeffs_unroller<Index-1, Size, Derived>::run(v1, dot);
- dot += v1.coeff(Index);
- }
-};
-
-template<int Size, typename Derived>
-struct ei_sumofcoeffs_unroller<0, Size, Derived>
-{
- static void run(const Derived &v1, typename Derived::Scalar &dot)
- {
- dot = v1.coeff(0);
- }
-};
-
-template<int Index, typename Derived>
-struct ei_sumofcoeffs_unroller<Index, Dynamic, Derived>
-{
- static void run(const Derived&, typename Derived::Scalar&) {}
-};
-
-// prevent buggy user code from causing an infinite recursion
-template<int Index, typename Derived>
-struct ei_sumofcoeffs_unroller<Index, 0, Derived>
-{
- static void run(const Derived&, typename Derived::Scalar&)
-{}
-};
-
-/** \returns the sum of all coefficients of *this
- *
- * \only_for_vectors
- *
- * \sa trace()
- */
-template<typename Derived>
-typename ei_traits<Derived>::Scalar
-MatrixBase<Derived>::sum() const
-{
- assert(IsVectorAtCompileTime);
- Scalar res;
- if(EIGEN_UNROLLED_LOOPS
- && SizeAtCompileTime != Dynamic
- && SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT)
- ei_sumofcoeffs_unroller<SizeAtCompileTime-1,
- SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT ? SizeAtCompileTime : Dynamic,
- Derived>
- ::run(derived(),res);
- else
- {
- res = coeff(0);
- for(int i = 1; i < size(); i++)
- res += coeff(i);
- }
- return res;
-}
-
-/** \returns the trace of \c *this, i.e. the sum of the coefficients on the main diagonal.
- *
- * \c *this can be any matrix, not necessarily square.
- *
- * \sa diagonal(), sum()
- */
-template<typename Derived>
-typename ei_traits<Derived>::Scalar
-MatrixBase<Derived>::trace() const
-{
- return diagonal().sum();
-}
-
-#endif // EIGEN_SUMOFCOEFFS_H
diff --git a/Eigen/src/Core/Util.h b/Eigen/src/Core/Util.h
index 71a8294f6..54c56eb3c 100644
--- a/Eigen/src/Core/Util.h
+++ b/Eigen/src/Core/Util.h
@@ -120,6 +120,8 @@ const int RowMajor = 1;
enum CornerType { TopLeft, TopRight, BottomLeft, BottomRight };
+enum DirectionType { Vertical, Horizontal };
+
// just a workaround because GCC seems to not really like empty structs
#ifdef __GNUG__
struct ei_empty_struct{char _ei_dummy_;};
diff --git a/Eigen/src/Core/Visitor.h b/Eigen/src/Core/Visitor.h
new file mode 100644
index 000000000..a3a2ef34e
--- /dev/null
+++ b/Eigen/src/Core/Visitor.h
@@ -0,0 +1,182 @@
+// This file is part of Eigen, a lightweight C++ template library
+// for linear algebra. Eigen itself is part of the KDE project.
+//
+// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
+//
+// Eigen is free software; you can redistribute it and/or
+// modify it under the terms of the GNU Lesser General Public
+// License as published by the Free Software Foundation; either
+// version 3 of the License, or (at your option) any later version.
+//
+// Alternatively, you can redistribute it and/or
+// modify it under the terms of the GNU General Public License as
+// published by the Free Software Foundation; either version 2 of
+// the License, or (at your option) any later version.
+//
+// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
+// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
+// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
+// GNU General Public License for more details.
+//
+// You should have received a copy of the GNU Lesser General Public
+// License and a copy of the GNU General Public License along with
+// Eigen. If not, see <http://www.gnu.org/licenses/>.
+
+#ifndef EIGEN_VISITOR_H
+#define EIGEN_VISITOR_H
+
+template<typename Visitor, typename Derived, int UnrollCount>
+struct ei_visitor_unroller
+{
+ enum {
+ col = (UnrollCount-1) / Derived::RowsAtCompileTime,
+ row = (UnrollCount-1) % Derived::RowsAtCompileTime
+ };
+
+ static void run(const Derived &mat, Visitor& visitor)
+ {
+ ei_visitor_unroller<Visitor, Derived, UnrollCount-1>::run(mat, visitor);
+ visitor(mat.coeff(row, col), row, col);
+ }
+};
+
+template<typename Visitor, typename Derived>
+struct ei_visitor_unroller<Visitor, Derived, 1>
+{
+ static void run(const Derived &mat, Visitor& visitor)
+ {
+ return visitor.init(mat.coeff(0, 0), 0, 0);
+ }
+};
+
+template<typename Visitor, typename Derived>
+struct ei_visitor_unroller<Visitor, Derived, Dynamic>
+{
+ static void run(const Derived &mat, Visitor& visitor) {}
+};
+
+
+/** Applies the visitor \a visitor to the whole coefficients of the matrix or vector.
+ *
+ * The template parameter \a Visitor is the type of the visitor and provides the following interface:
+ * \code
+ * struct MyVisitor {
+ * // called for the first coefficient
+ * void init(const Scalar& value, int i, int j);
+ * // called for all other coefficients
+ * void operator() (const Scalar& value, int i, int j);
+ * };
+ * \endcode
+ *
+ * \sa minCoeff(int*,int*), maxCoeff(int*,int*), MatrixBase::redux()
+ */
+template<typename Derived>
+template<typename Visitor>
+void MatrixBase<Derived>::visit(Visitor& visitor) const
+{
+ if(EIGEN_UNROLLED_LOOPS
+ && SizeAtCompileTime != Dynamic
+ && SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT)
+ return ei_visitor_unroller<Visitor, Derived,
+ (SizeAtCompileTime>0 && SizeAtCompileTime <= EIGEN_UNROLLING_LIMIT) ?
+ SizeAtCompileTime : Dynamic>::run(derived(), visitor);
+ else
+ {
+ Scalar res;
+ visitor.init(coeff(0,0), 0, 0);
+ for(int i = 1; i < rows(); i++)
+ visitor(res, coeff(i, 0), i, 0);
+ for(int j = 1; j < cols(); j++)
+ for(int i = 0; i < rows(); i++)
+ visitor(res, coeff(i, j), i, j);
+ }
+}
+
+/** \internal
+ * \brief Base class to implement min and max visitors
+ */
+template <typename Scalar>
+struct ei_coeff_visitor
+{
+ int row, col;
+ Scalar res;
+ void init(const Scalar& value, int i, int j)
+ {
+ res = value;
+ row = i;
+ col = j;
+ }
+};
+
+/** \internal
+ * \brief Visitor computing the min coefficient with its value and coordinates
+ *
+ * \sa ei_coeff_visitor, ei_max_coeff_visitor, MatrixBase::minCoeff(int*, int*)
+ */
+template <typename Scalar>
+struct ei_min_coeff_visitor : ei_coeff_visitor<Scalar>
+{
+ void operator() (const Scalar& value, int i, int j)
+ {
+ if(value < this->res)
+ {
+ this->res = value;
+ this->row = i;
+ this->col = j;
+ }
+ }
+};
+
+/** \internal
+ * \brief Visitor computing the max coefficient with its value and coordinates
+ *
+ * \sa ei_coeff_visitor, ei_min_coeff_visitor, MatrixBase::maxCoeff(int*, int*)
+ */
+template <typename Scalar>
+struct ei_max_coeff_visitor : ei_coeff_visitor<Scalar>
+{
+ void operator() (const Scalar& value, int i, int j)
+ {
+ if(value > this->res)
+ {
+ this->res = value;
+ this->row = i;
+ this->col = j;
+ }
+ }
+};
+
+/** \returns the minimum of all coefficients of *this
+ * and puts in *row and *col its location.
+ *
+ * \sa MatrixBase::maxCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::minCoeff()
+ */
+template<typename Derived>
+typename ei_traits<Derived>::Scalar
+MatrixBase<Derived>::minCoeff(int* row, int* col) const
+{
+ ei_min_coeff_visitor<Scalar> minVisitor;
+ this->visit(minVisitor);
+ *row = minVisitor.row;
+ if (col) *col = minVisitor.col;
+ return minVisitor.res;
+}
+
+/** \returns the maximum of all coefficients of *this
+ * and puts in *row and *col its location.
+ *
+ * \sa MatrixBase::minCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::maxCoeff()
+ */
+template<typename Derived>
+typename ei_traits<Derived>::Scalar
+MatrixBase<Derived>::maxCoeff(int* row, int* col) const
+{
+ ei_max_coeff_visitor<Scalar> maxVisitor;
+ this->visit(maxVisitor);
+ *row = maxVisitor.row;
+ if (col) *col = maxVisitor.col;
+ return maxVisitor.res;
+}
+
+
+#endif // EIGEN_VISITOR_H