aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src/Core/Visitor.h
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 /Eigen/src/Core/Visitor.h
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
Diffstat (limited to 'Eigen/src/Core/Visitor.h')
-rw-r--r--Eigen/src/Core/Visitor.h182
1 files changed, 182 insertions, 0 deletions
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