diff options
author | Benoit Jacob <jacob.benoit.1@gmail.com> | 2008-03-31 17:24:09 +0000 |
---|---|---|
committer | Benoit Jacob <jacob.benoit.1@gmail.com> | 2008-03-31 17:24:09 +0000 |
commit | e74fbfb2bc13dee268950361a957aea73bcefc21 (patch) | |
tree | 5f059fd5ca63f1cf370235cee4c2490036db2f70 /disabled | |
parent | cff5e3ce9c1e09553125bce464b9c80f8bc2eb76 (diff) |
- remove Eval/EvalOMP (moving them to a disabled/ subdir in order
to preserve SVN history). They are made useless by the new
ei_eval_unless_lazy.
- introduce a generic Eval member typedef so one can do e.g.
T t; U u; Product<T, U>::Eval m; m = t*u;
Diffstat (limited to 'disabled')
-rw-r--r-- | disabled/Eval.h | 109 | ||||
-rw-r--r-- | disabled/EvalOMP.h | 132 | ||||
-rw-r--r-- | disabled/Eval_MatrixType.cpp | 13 | ||||
-rw-r--r-- | disabled/class_Eval.cpp | 28 |
4 files changed, 282 insertions, 0 deletions
diff --git a/disabled/Eval.h b/disabled/Eval.h new file mode 100644 index 000000000..23e35a96a --- /dev/null +++ b/disabled/Eval.h @@ -0,0 +1,109 @@ +// 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_EVAL_H +#define EIGEN_EVAL_H + +/** \class Eval + * + * \brief Evaluation of an expression + * + * The template parameter Expression is the type of the expression that we are evaluating. + * + * This class is the return + * type of MatrixBase::eval() and most of the time this is the only way it + * is used. + * + * However, if you want to write a function returning an evaluation of an expression, you + * will need to use this class. + * + * Here is an example illustrating this: + * \include class_Eval.cpp + * Output: \verbinclude class_Eval.out + * + * \sa MatrixBase::eval() + */ +template<typename ExpressionType> +struct ei_traits<Eval<ExpressionType> > +{ + typedef typename ExpressionType::Scalar Scalar; + enum { + RowsAtCompileTime = ExpressionType::RowsAtCompileTime, + ColsAtCompileTime = ExpressionType::ColsAtCompileTime, + MaxRowsAtCompileTime = ExpressionType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = ExpressionType::MaxColsAtCompileTime, + Flags = ExpressionType::Flags & ~LazyBit + }; +}; + +template<typename ExpressionType> class Eval : ei_no_assignment_operator, + public Matrix< typename ExpressionType::Scalar, + ExpressionType::RowsAtCompileTime, + ExpressionType::ColsAtCompileTime, + ExpressionType::Flags, + ExpressionType::MaxRowsAtCompileTime, + ExpressionType::MaxColsAtCompileTime> +{ + public: + + /** The actual matrix type to evaluate to. This type can be used independently + * of the rest of this class to get the actual matrix type to evaluate and store + * the value of an expression. + * + * Here is an example illustrating this: + * \include Eval_MatrixType.cpp + * Output: \verbinclude Eval_MatrixType.out + */ + typedef Matrix<typename ExpressionType::Scalar, + ExpressionType::RowsAtCompileTime, + ExpressionType::ColsAtCompileTime, + ExpressionType::Flags, + ExpressionType::MaxRowsAtCompileTime, + ExpressionType::MaxColsAtCompileTime> MatrixType; + + _EIGEN_GENERIC_PUBLIC_INTERFACE(Eval, MatrixType) + + explicit Eval(const ExpressionType& expr) : MatrixType(expr) {} +}; + +/** Evaluates *this, which can be any expression, and returns the obtained matrix. + * + * A common use case for this is the following. In an expression-templates library + * like Eigen, the coefficients of an expression are only computed as they are + * accessed, they are not computed when the expression itself is constructed. This is + * usually a good thing, as this "lazy evaluation" improves performance, but can also + * in certain cases lead to wrong results and/or to redundant computations. In such + * cases, one can restore the classical immediate-evaluation behavior by calling eval(). + * + * Example: \include MatrixBase_eval.cpp + * Output: \verbinclude MatrixBase_eval.out + * + * \sa class Eval */ +template<typename Derived> +const typename ei_eval_unless_lazy<Derived>::Type MatrixBase<Derived>::eval() const +{ + return typename ei_eval_unless_lazy<Derived>::Type(derived()); +} + +#endif // EIGEN_EVAL_H diff --git a/disabled/EvalOMP.h b/disabled/EvalOMP.h new file mode 100644 index 000000000..32398b6be --- /dev/null +++ b/disabled/EvalOMP.h @@ -0,0 +1,132 @@ +// 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_EVAL_OMP_H +#define EIGEN_EVAL_OMP_H + +/** \class EvalOMP + * + * \brief Parallel evaluation of an expression using OpenMP + * + * The template parameter Expression is the type of the expression that we are evaluating. + * + * This class is the return type of MatrixBase::evalOMP() and most of the time this is the + * only way it is used. + * + * Note that if OpenMP is not enabled, then this class is equivalent to Eval. + * + * \sa MatrixBase::evalOMP(), class Eval, MatrixBase::eval() + */ +template<typename ExpressionType> +struct ei_traits<EvalOMP<ExpressionType> > +{ + typedef typename ExpressionType::Scalar Scalar; + enum { + RowsAtCompileTime = ExpressionType::RowsAtCompileTime, + ColsAtCompileTime = ExpressionType::ColsAtCompileTime, + MaxRowsAtCompileTime = ExpressionType::MaxRowsAtCompileTime, + MaxColsAtCompileTime = ExpressionType::MaxColsAtCompileTime, + Flags = ExpressionType::Flags & ~LazyBit + }; +}; + +template<typename ExpressionType> class EvalOMP : ei_no_assignment_operator, + public Matrix< typename ExpressionType::Scalar, + ExpressionType::RowsAtCompileTime, + ExpressionType::ColsAtCompileTime, + ExpressionType::Flags, + ExpressionType::MaxRowsAtCompileTime, + ExpressionType::MaxColsAtCompileTime> +{ + public: + + /** The actual matrix type to evaluate to. This type can be used independently + * of the rest of this class to get the actual matrix type to evaluate and store + * the value of an expression. + */ + typedef Matrix<typename ExpressionType::Scalar, + ExpressionType::RowsAtCompileTime, + ExpressionType::ColsAtCompileTime, + ExpressionType::Flags, + ExpressionType::MaxRowsAtCompileTime, + ExpressionType::MaxColsAtCompileTime> MatrixType; + + _EIGEN_GENERIC_PUBLIC_INTERFACE(EvalOMP, MatrixType) + + #ifdef _OPENMP + explicit EvalOMP(const ExpressionType& other) + : MatrixType(other.rows(), other.cols()) + { + #ifdef __INTEL_COMPILER + #pragma omp parallel default(none) shared(other) + #else + #pragma omp parallel default(none) + #endif + { + if (this->cols()>this->rows()) + { + #pragma omp for + for(int j = 0; j < this->cols(); j++) + for(int i = 0; i < this->rows(); i++) + this->coeffRef(i, j) = other.coeff(i, j); + } + else + { + #pragma omp for + for(int i = 0; i < this->rows(); i++) + for(int j = 0; j < this->cols(); j++) + this->coeffRef(i, j) = other.coeff(i, j); + } + } + } + #else + explicit EvalOMP(const ExpressionType& other) : MatrixType(other) {} + #endif +}; + +/** Evaluates *this in a parallel fashion using OpenMP and returns the obtained matrix. + * + * Of course, it only makes sense to call this function for complex expressions, and/or + * large matrices (>32x32), \b and if there is no outer loop which can be parallelized. + * + * It is the responsibility of the user manage the OpenMP parameters, for instance: + * \code + * #include <omp.h> + * // ... + * omp_set_num_threads(omp_get_num_procs()); + * \endcode + * You also need to enable OpenMP on your compiler (e.g., -fopenmp) during both compilation and linking. + * + * Note that if OpenMP is not enabled, then evalOMP() is equivalent to eval(). + * + * \sa class EvalOMP, eval() + */ +template<typename Derived> +const EvalOMP<Derived> MatrixBase<Derived>::evalOMP() const +{ + return EvalOMP<Derived>(*static_cast<const Derived*>(this)); +} + +#endif // EIGEN_EVAL_OMP_H diff --git a/disabled/Eval_MatrixType.cpp b/disabled/Eval_MatrixType.cpp new file mode 100644 index 000000000..ccff677ac --- /dev/null +++ b/disabled/Eval_MatrixType.cpp @@ -0,0 +1,13 @@ +typedef Matrix3i MyMatrixType; +MyMatrixType m = MyMatrixType::random(3, 3); +cout << "Here's the matrix m:" << endl << m << endl; +typedef Eigen::Eval<Eigen::Block<MyMatrixType,1,MyMatrixType::ColsAtCompileTime> >::MatrixType MyRowType; +// now MyRowType is just the same typedef as RowVector3i +MyRowType r = m.row(0); +cout << "Here's r:" << endl << r << endl; +typedef Eigen::Eval<Eigen::Block<MyMatrixType> >::MatrixType MyBlockType; +MyBlockType c = m.corner(Eigen::TopRight, 2, 2); +// now MyBlockType is a a matrix type where the number of rows and columns +// are dynamic, but know at compile-time to be <= 2. Therefore no dynamic memory +// allocation occurs. +cout << "Here's c:" << endl << c << endl; diff --git a/disabled/class_Eval.cpp b/disabled/class_Eval.cpp new file mode 100644 index 000000000..ee6ee89d1 --- /dev/null +++ b/disabled/class_Eval.cpp @@ -0,0 +1,28 @@ +#include <Eigen/Core> +USING_PART_OF_NAMESPACE_EIGEN +using namespace std; + +template<typename Derived> +const Eigen::Eval<Eigen::Transpose<Derived> > +evaluatedTranspose(const MatrixBase<Derived>& m) +{ + return m.transpose().eval(); +} + +int main(int, char**) +{ + Matrix2f M = Matrix2f::random(); + Matrix2f m; + m = M; + cout << "Here is the matrix m:" << endl << m << endl; + cout << "Now we want to replace m by its own transpose." << endl; + cout << "If we do m = m.transpose(), then m becomes:" << endl; + m = m.transpose(); + cout << m << endl << "which is wrong!" << endl; + cout << "Now let us instead do m = evaluatedTranspose(m). Then m becomes" << endl; + m = M; + m = evaluatedTranspose(m); + cout << m << endl << "which is right." << endl; + + return 0; +} |