diff options
Diffstat (limited to 'Eigen')
110 files changed, 4852 insertions, 2833 deletions
diff --git a/Eigen/Array b/Eigen/Array index ff1f05a51..b35242f1a 100644 --- a/Eigen/Array +++ b/Eigen/Array @@ -28,7 +28,6 @@ namespace Eigen { * \endcode */ -#include "src/Array/CwiseOperators.h" #include "src/Array/Functors.h" #include "src/Array/BooleanRedux.h" #include "src/Array/Select.h" @@ -37,6 +36,9 @@ namespace Eigen { #include "src/Array/Norms.h" #include "src/Array/Replicate.h" #include "src/Array/Reverse.h" +#include "src/Array/ArrayBase.h" +#include "src/Array/ArrayWrapper.h" +#include "src/Array/Array.h" } // namespace Eigen diff --git a/Eigen/Cholesky b/Eigen/Cholesky index 9e422ecce..a0e0d146b 100644 --- a/Eigen/Cholesky +++ b/Eigen/Cholesky @@ -31,7 +31,6 @@ namespace Eigen { */ #include "src/misc/Solve.h" -#include "src/Array/CwiseOperators.h" #include "src/Array/Functors.h" #include "src/Cholesky/LLT.h" #include "src/Cholesky/LDLT.h" diff --git a/Eigen/Core b/Eigen/Core index 49bb4bfb0..d452a6cd9 100644 --- a/Eigen/Core +++ b/Eigen/Core @@ -23,6 +23,10 @@ // License and a copy of the GNU General Public License along with // Eigen. If not, see <http://www.gnu.org/licenses/>. +#ifdef EIGEN2_SUPPORT +#include "Eigen2Support" +#endif + #ifndef EIGEN_CORE_H #define EIGEN_CORE_H @@ -127,6 +131,9 @@ namespace Eigen { * \endcode */ +/** The type used to identify a dense storage. */ +struct Dense {}; + #include "src/Core/util/Macros.h" #include "src/Core/util/Constants.h" #include "src/Core/util/ForwardDeclarations.h" @@ -151,6 +158,7 @@ namespace Eigen { #endif #include "src/Core/Functors.h" +#include "src/Core/DenseBase.h" #include "src/Core/MatrixBase.h" #include "src/Core/AnyMatrixBase.h" #include "src/Core/Coeffs.h" @@ -163,11 +171,12 @@ namespace Eigen { #include "src/Core/util/BlasUtil.h" #include "src/Core/MatrixStorage.h" #include "src/Core/NestByValue.h" +#include "src/Core/ForceAlignedAccess.h" #include "src/Core/ReturnByValue.h" -#include "src/Core/Flagged.h" #include "src/Core/NoAlias.h" +#include "src/Core/DenseStorageBase.h" #include "src/Core/Matrix.h" -#include "src/Core/Cwise.h" +#include "src/Core/SelfCwiseBinaryOp.h" #include "src/Core/CwiseBinaryOp.h" #include "src/Core/CwiseUnaryOp.h" #include "src/Core/CwiseNullaryOp.h" @@ -207,7 +216,6 @@ namespace Eigen { #include "src/Core/products/TriangularMatrixMatrix.h" #include "src/Core/products/TriangularSolverMatrix.h" #include "src/Core/BandMatrix.h" -#include "src/Core/ExpressionMaker.h" } // namespace Eigen diff --git a/Eigen/Eigen2Support b/Eigen/Eigen2Support new file mode 100644 index 000000000..b95b51dec --- /dev/null +++ b/Eigen/Eigen2Support @@ -0,0 +1,57 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 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 EIGEN2SUPPORT_H +#define EIGEN2SUPPORT_H + +#include "src/Core/util/DisableMSVCWarnings.h" + +#ifndef EIGEN2_SUPPORT +#define EIGEN2_SUPPORT +#endif + +#include "Core" +#include "Array" + +namespace Eigen { + +/** \defgroup Eigen2Support_Module Eigen2 support module + * This module provides a couple of deprecated functions improving the compatibility with Eigen2. + * + * \code + * #include <Eigen/Eigen2Support> + * \endcode + */ + +#include "src/Eigen2Support/Flagged.h" +#include "src/Eigen2Support/Lazy.h" +#include "src/Eigen2Support/Cwise.h" +#include "src/Eigen2Support/CwiseOperators.h" +#include "src/Eigen2Support/TriangularSolver.h" + +} // namespace Eigen + +#include "src/Core/util/EnableMSVCWarnings.h" + +#endif // EIGEN2SUPPORT_H diff --git a/Eigen/Sparse b/Eigen/Sparse index 35e252d01..f027d3e6c 100644 --- a/Eigen/Sparse +++ b/Eigen/Sparse @@ -82,6 +82,9 @@ namespace Eigen { * \endcode */ +/** The type used to identify a general sparse storage. */ +struct Sparse {}; + #include "src/Sparse/SparseUtil.h" #include "src/Sparse/SparseMatrixBase.h" #include "src/Sparse/CompressedStorage.h" @@ -94,22 +97,20 @@ namespace Eigen { #include "src/Sparse/SparseVector.h" #include "src/Sparse/CoreIterators.h" #include "src/Sparse/SparseTranspose.h" -#include "src/Sparse/SparseCwise.h" #include "src/Sparse/SparseCwiseUnaryOp.h" #include "src/Sparse/SparseCwiseBinaryOp.h" #include "src/Sparse/SparseDot.h" #include "src/Sparse/SparseAssign.h" #include "src/Sparse/SparseRedux.h" #include "src/Sparse/SparseFuzzy.h" -#include "src/Sparse/SparseFlagged.h" #include "src/Sparse/SparseProduct.h" #include "src/Sparse/SparseDiagonalProduct.h" -#include "src/Sparse/SparseTriangular.h" +#include "src/Sparse/SparseTriangularView.h" +#include "src/Sparse/SparseSelfAdjointView.h" #include "src/Sparse/TriangularSolver.h" #include "src/Sparse/SparseLLT.h" #include "src/Sparse/SparseLDLT.h" #include "src/Sparse/SparseLU.h" -#include "src/Sparse/SparseExpressionMaker.h" #ifdef EIGEN_CHOLMOD_SUPPORT # include "src/Sparse/CholmodSupport.h" diff --git a/Eigen/src/Array/Array.h b/Eigen/src/Array/Array.h new file mode 100644 index 000000000..2f155aeeb --- /dev/null +++ b/Eigen/src/Array/Array.h @@ -0,0 +1,290 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 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_ARRAY_H +#define EIGEN_ARRAY_H + +template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> +struct ei_traits<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > : ei_traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > +{ + typedef DenseStorageArray DenseStorageType; +}; + +template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> +class Array + : public DenseStorageBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, ArrayBase, _Options> +{ + public: + + typedef DenseStorageBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, ArrayBase, _Options> Base; + _EIGEN_DENSE_PUBLIC_INTERFACE(Array) + + enum { Options = _Options }; + typedef typename Base::PlainMatrixType PlainMatrixType; + + protected: + using Base::m_storage; + public: + enum { NeedsToAlign = (!(Options&DontAlign)) + && SizeAtCompileTime!=Dynamic && ((sizeof(Scalar)*SizeAtCompileTime)%16)==0 }; + EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) + + using Base::base; + using Base::coeff; + using Base::coeffRef; + using Base::operator=; + using Base::operator+=; + using Base::operator-=; + using Base::operator*=; + using Base::operator/=; + + /** Copies the value of the expression \a other into \c *this with automatic resizing. + * + * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), + * it will be initialized. + * + * Note that copying a row-vector into a vector (and conversely) is allowed. + * The resizing, if any, is then done in the appropriate way so that row-vectors + * remain row-vectors and vectors remain vectors. + */ + template<typename OtherDerived> + EIGEN_STRONG_INLINE Array& operator=(const ArrayBase<OtherDerived>& other) + { + return Base::_set(other); + } + + /** This is a special case of the templated operator=. Its purpose is to + * prevent a default operator= from hiding the templated operator=. + */ + EIGEN_STRONG_INLINE Array& operator=(const Array& other) + { + return Base::_set(other); + } + + /** Default constructor. + * + * For fixed-size matrices, does nothing. + * + * For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix + * is called a null matrix. This constructor is the unique way to create null matrices: resizing + * a matrix to 0 is not supported. + * + * \sa resize(int,int) + */ + EIGEN_STRONG_INLINE explicit Array() : Base() + { + Base::_check_template_params(); + EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + } + +#ifndef EIGEN_PARSED_BY_DOXYGEN + // FIXME is it still needed ?? + /** \internal */ + Array(ei_constructor_without_unaligned_array_assert) + : Base(ei_constructor_without_unaligned_array_assert()) + { + Base::_check_template_params(); + EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + } +#endif + + /** Constructs a vector or row-vector with given dimension. \only_for_vectors + * + * Note that this is only useful for dynamic-size vectors. For fixed-size vectors, + * it is redundant to pass the dimension here, so it makes more sense to use the default + * constructor Matrix() instead. + */ + EIGEN_STRONG_INLINE explicit Array(int dim) + : Base(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim) + { + Base::_check_template_params(); + EIGEN_STATIC_ASSERT_VECTOR_ONLY(Array) + ei_assert(dim > 0); + ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim); + EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + } + + #ifndef EIGEN_PARSED_BY_DOXYGEN + template<typename T0, typename T1> + EIGEN_STRONG_INLINE Array(const T0& x, const T1& y) + { + Base::_check_template_params(); + this->template _init2<T0,T1>(x, y); + } + #else + /** constructs an uninitialized matrix with \a rows rows and \a cols columns. + * + * This is useful for dynamic-size matrices. For fixed-size matrices, + * it is redundant to pass these parameters, so one should use the default constructor + * Matrix() instead. */ + Array(int rows, int cols); + /** constructs an initialized 2D vector with given coefficients */ + Array(const Scalar& x, const Scalar& y); + #endif + + /** constructs an initialized 3D vector with given coefficients */ + EIGEN_STRONG_INLINE Array(const Scalar& x, const Scalar& y, const Scalar& z) + { + Base::_check_template_params(); + EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 3) + m_storage.data()[0] = x; + m_storage.data()[1] = y; + m_storage.data()[2] = z; + } + /** constructs an initialized 4D vector with given coefficients */ + EIGEN_STRONG_INLINE Array(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w) + { + Base::_check_template_params(); + EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Array, 4) + m_storage.data()[0] = x; + m_storage.data()[1] = y; + m_storage.data()[2] = z; + m_storage.data()[3] = w; + } + + explicit Array(const Scalar *data); + + /** Constructor copying the value of the expression \a other */ + template<typename OtherDerived> + EIGEN_STRONG_INLINE Array(const ArrayBase<OtherDerived>& other) + : Base(other.rows() * other.cols(), other.rows(), other.cols()) + { + Base::_check_template_params(); + Base::_set_noalias(other); + } + /** Copy constructor */ + EIGEN_STRONG_INLINE Array(const Array& other) + : Base(other.rows() * other.cols(), other.rows(), other.cols()) + { + Base::_check_template_params(); + Base::_set_noalias(other); + } + /** Copy constructor with in-place evaluation */ + template<typename OtherDerived> + EIGEN_STRONG_INLINE Array(const ReturnByValue<OtherDerived>& other) + { + Base::_check_template_params(); + Base::resize(other.rows(), other.cols()); + other.evalTo(*this); + } + + /** \sa MatrixBase::operator=(const AnyMatrixBase<OtherDerived>&) */ + template<typename OtherDerived> + EIGEN_STRONG_INLINE Array(const AnyMatrixBase<OtherDerived> &other) + : Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) + { + Base::_check_template_params(); + Base::resize(other.rows(), other.cols()); + *this = other; + } + + /** Override MatrixBase::swap() since for dynamic-sized matrices of same type it is enough to swap the + * data pointers. + */ + template<typename OtherDerived> + void swap(ArrayBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other) + { this->_swap(other.derived()); } + + #ifdef EIGEN_ARRAY_PLUGIN + #include EIGEN_ARRAY_PLUGIN + #endif + + private: + + template<typename MatrixType, typename OtherDerived, bool SwapPointers> + friend struct ei_matrix_swap_impl; +}; + +/** \defgroup arraytypedefs Global array typedefs + * + * \ingroup Array_Module + * + * Eigen defines several typedef shortcuts for most common 1D and 2D array types. + * + * The general patterns are the following: + * + * \c ArrayRowsColsType where \c Rows and \c Cols can be \c 2,\c 3,\c 4 for fixed size square matrices or \c X for dynamic size, + * and where \c Type can be \c i for integer, \c f for float, \c d for double, \c cf for complex float, \c cd + * for complex double. + * + * For example, \c Array33d is a fixed-size 3x3 array type of doubles, and \c ArrayXXf is a dynamic-size matrix of floats. + * + * There are also \c ArraySizeType which are self-explanatory. For example, \c Array4cf is + * a fixed-size 1D array of 4 complex floats. + * + * \sa class Array + */ + +#define EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Size, SizeSuffix) \ +/** \ingroup arraytypedefs */ \ +typedef Array<Type, Size, Size> Array##SizeSuffix##SizeSuffix##TypeSuffix; \ +/** \ingroup matrixtypedefs */ \ +typedef Array<Type, Size, 1> Array##SizeSuffix##TypeSuffix; + +#define EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, Size) \ +/** \ingroup arraytypedefs */ \ +typedef Array<Type, Size, Dynamic> Array##Size##X##TypeSuffix; \ +/** \ingroup arraytypedefs */ \ +typedef Array<Type, Dynamic, Size> Array##X##Size##TypeSuffix; + +#define EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(Type, TypeSuffix) \ +EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 2, 2) \ +EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 3, 3) \ +EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, 4, 4) \ +EIGEN_MAKE_ARRAY_TYPEDEFS(Type, TypeSuffix, Dynamic, X) \ +EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 2) \ +EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 3) \ +EIGEN_MAKE_ARRAY_FIXED_TYPEDEFS(Type, TypeSuffix, 4) + +EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(int, i) +EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(float, f) +EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(double, d) +EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<float>, cf) +EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES(std::complex<double>, cd) + +#undef EIGEN_MAKE_ARRAY_TYPEDEFS_ALL_SIZES +#undef EIGEN_MAKE_ARRAY_TYPEDEFS + +#undef EIGEN_MAKE_ARRAY_TYPEDEFS_LARGE + +#define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, SizeSuffix) \ +using Eigen::Matrix##SizeSuffix##TypeSuffix; \ +using Eigen::Vector##SizeSuffix##TypeSuffix; \ +using Eigen::RowVector##SizeSuffix##TypeSuffix; + +#define EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(TypeSuffix) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 2) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 3) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, 4) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE_AND_SIZE(TypeSuffix, X) \ + +#define EIGEN_USING_ARRAY_TYPEDEFS \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(i) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(f) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(d) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cf) \ +EIGEN_USING_ARRAY_TYPEDEFS_FOR_TYPE(cd) + + +#endif // EIGEN_ARRAY_H diff --git a/Eigen/src/Array/ArrayBase.h b/Eigen/src/Array/ArrayBase.h new file mode 100644 index 000000000..ccc8b8373 --- /dev/null +++ b/Eigen/src/Array/ArrayBase.h @@ -0,0 +1,245 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 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_ARRAYBASE_H +#define EIGEN_ARRAYBASE_H + +template<typename ExpressionType> class MatrixWrapper; + +/** \ingroup Array_Module + * + * \class ArrayBase + * + * \brief Base class for all 1D and 2D array, and related expressions + * + * An array is similar to a dense vector or matrix. While matrices are mathematical + * objects with well defined linear algebra operators, an array is just a collection + * of scalar values arranged in a one or two dimensionnal fashion. The main consequence, + * is that all operations applied to an array are performed coefficient wise. Furthermore, + * arays support scalar math functions of the c++ standard library, and convenient + * constructors allowing to easily write generic code working for both scalar values + * and arrays. + * + * This class is the base that is inherited by all array expression types. + * + * \param Derived is the derived type, e.g. an array type, or an expression, etc. + * + * \sa class ArrayBase + */ +template<typename Derived> class ArrayBase + : public DenseBase<Derived> +{ + public: +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** The base class for a given storage type. */ + typedef ArrayBase StorageBaseType; + /** Construct the base class type for the derived class OtherDerived */ + template <typename OtherDerived> struct MakeBase { typedef ArrayBase<OtherDerived> Type; }; + + using ei_special_scalar_op_base<Derived,typename ei_traits<Derived>::Scalar, + typename NumTraits<typename ei_traits<Derived>::Scalar>::Real>::operator*; + + class InnerIterator; + + typedef typename ei_traits<Derived>::Scalar Scalar; + typedef typename ei_packet_traits<Scalar>::type PacketScalar; + + typedef DenseBase<Derived> Base; + using Base::RowsAtCompileTime; + using Base::ColsAtCompileTime; + using Base::SizeAtCompileTime; + using Base::MaxRowsAtCompileTime; + using Base::MaxColsAtCompileTime; + using Base::MaxSizeAtCompileTime; + using Base::IsVectorAtCompileTime; + using Base::Flags; + using Base::CoeffReadCost; + using Base::_HasDirectAccess; + + using Base::derived; + using Base::const_cast_derived; + using Base::rows; + using Base::cols; + using Base::size; + using Base::coeff; + using Base::coeffRef; + using Base::lazyAssign; + using Base::operator=; + using Base::operator+=; + using Base::operator-=; + using Base::operator*=; + using Base::operator/=; + + typedef typename Base::RealScalar RealScalar; + typedef typename Base::CoeffReturnType CoeffReturnType; +#endif // not EIGEN_PARSED_BY_DOXYGEN + +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal the plain matrix type corresponding to this expression. Note that is not necessarily + * exactly the return type of eval(): in the case of plain matrices, the return type of eval() is a const + * reference to a matrix, not a matrix! It is however guaranteed that the return type of eval() is either + * PlainMatrixType or const PlainMatrixType&. + */ + typedef Array<typename ei_traits<Derived>::Scalar, + ei_traits<Derived>::RowsAtCompileTime, + ei_traits<Derived>::ColsAtCompileTime, + AutoAlign | (ei_traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor), + ei_traits<Derived>::MaxRowsAtCompileTime, + ei_traits<Derived>::MaxColsAtCompileTime + > PlainMatrixType; + + + /** \internal Represents a matrix with all coefficients equal to one another*/ + typedef CwiseNullaryOp<ei_scalar_constant_op<Scalar>,Derived> ConstantReturnType; +#endif // not EIGEN_PARSED_BY_DOXYGEN + +#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::ArrayBase +# include "../plugins/CommonCwiseUnaryOps.h" +# include "../plugins/MatrixCwiseUnaryOps.h" +# include "../plugins/ArrayCwiseUnaryOps.h" +# include "../plugins/CommonCwiseBinaryOps.h" +# include "../plugins/MatrixCwiseBinaryOps.h" +# include "../plugins/ArrayCwiseBinaryOps.h" +# ifdef EIGEN_ARRAYBASE_PLUGIN +# include EIGEN_ARRAYBASE_PLUGIN +# endif +#undef EIGEN_CURRENT_STORAGE_BASE_CLASS + + + /** Copies \a other into *this. \returns a reference to *this. */ +// template<typename OtherDerived> +// Derived& operator=(const ArrayBase<OtherDerived>& other); + + /** Special case of the template operator=, in order to prevent the compiler + * from generating a default operator= (issue hit with g++ 4.1) + */ + Derived& operator=(const ArrayBase& other) + { + return ei_assign_selector<Derived,Derived>::run(derived(), other.derived()); + } + +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** Copies \a other into *this without evaluating other. \returns a reference to *this. */ +// template<typename OtherDerived> +// Derived& lazyAssign(const ArrayBase<OtherDerived>& other); +// template<typename OtherDerived> +// Derived& lazyAssign(const MatrixBase<OtherDerived>& other); +#endif // not EIGEN_PARSED_BY_DOXYGEN + + Derived& operator+=(const Scalar& scalar) + { return *this = derived() + scalar; } + Derived& operator-=(const Scalar& scalar) + { return *this = derived() - scalar; } + + template<typename OtherDerived> + Derived& operator+=(const ArrayBase<OtherDerived>& other); + template<typename OtherDerived> + Derived& operator-=(const ArrayBase<OtherDerived>& other); + + template<typename OtherDerived> + Derived& operator*=(const ArrayBase<OtherDerived>& other); + + template<typename OtherDerived> + inline bool operator==(const ArrayBase<OtherDerived>& other) const + { return cwiseEqual(other).all(); } + + template<typename OtherDerived> + inline bool operator!=(const ArrayBase<OtherDerived>& other) const + { return cwiseNotEqual(other).all(); } + + + /** \returns the matrix or vector obtained by evaluating this expression. + * + * Notice that in the case of a plain matrix or vector (not an expression) this function just returns + * a const reference, in order to avoid a useless copy. + */ +// EIGEN_STRONG_INLINE const typename ei_eval<Derived>::type eval() const +// { return typename ei_eval<Derived>::type(derived()); } + +// template<typename OtherDerived> +// void swap(ArrayBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other); + + +// const VectorwiseOp<Derived,Horizontal> rowwise() const; +// VectorwiseOp<Derived,Horizontal> rowwise(); +// const VectorwiseOp<Derived,Vertical> colwise() const; +// VectorwiseOp<Derived,Vertical> colwise(); + + + + public: + MatrixWrapper<Derived> asMatrix() { return derived(); } + const MatrixWrapper<Derived> asMatrix() const { return derived(); } + + template<typename Dest> + inline void evalTo(Dest& dst) const { dst = asMatrix(); } + + protected: + /** Default constructor. Do nothing. */ + ArrayBase() + { + /* Just checks for self-consistency of the flags. + * Only do it when debugging Eigen, as this borders on paranoiac and could slow compilation down + */ +#ifdef EIGEN_INTERNAL_DEBUGGING + EIGEN_STATIC_ASSERT(ei_are_flags_consistent<Flags>::ret, + INVALID_MATRIXBASE_TEMPLATE_PARAMETERS) +#endif + } + + private: + explicit ArrayBase(int); + ArrayBase(int,int); + template<typename OtherDerived> explicit ArrayBase(const ArrayBase<OtherDerived>&); +}; + +/** replaces \c *this by \c *this - \a other. + * + * \returns a reference to \c *this + */ +template<typename Derived> +template<typename OtherDerived> +EIGEN_STRONG_INLINE Derived & +ArrayBase<Derived>::operator-=(const ArrayBase<OtherDerived> &other) +{ + SelfCwiseBinaryOp<ei_scalar_difference_op<Scalar>, Derived> tmp(derived()); + tmp = other; + return derived(); +} + +/** replaces \c *this by \c *this + \a other. + * + * \returns a reference to \c *this + */ +template<typename Derived> +template<typename OtherDerived> +EIGEN_STRONG_INLINE Derived & +ArrayBase<Derived>::operator+=(const ArrayBase<OtherDerived>& other) +{ + SelfCwiseBinaryOp<ei_scalar_sum_op<Scalar>, Derived> tmp(derived()); + tmp = other.derived(); + return derived(); +} + +#endif // EIGEN_ARRAYBASE_H diff --git a/Eigen/src/Array/ArrayWrapper.h b/Eigen/src/Array/ArrayWrapper.h new file mode 100644 index 000000000..5850b6cb5 --- /dev/null +++ b/Eigen/src/Array/ArrayWrapper.h @@ -0,0 +1,168 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 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_ARRAYWRAPPER_H +#define EIGEN_ARRAYWRAPPER_H + +template<typename ExpressionType> +struct ei_traits<ArrayWrapper<ExpressionType> > + : public ei_traits<ExpressionType> +{ + typedef DenseStorageArray DenseStorageType; +}; + +template<typename ExpressionType> +class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> > +{ + public: + typedef ArrayBase<ArrayWrapper> Base; + _EIGEN_DENSE_PUBLIC_INTERFACE(ArrayWrapper) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(ArrayWrapper) + + inline ArrayWrapper(const ExpressionType& matrix) : m_expression(matrix) {} + + inline int rows() const { return m_expression.rows(); } + inline int cols() const { return m_expression.cols(); } + inline int stride() const { return m_expression.stride(); } + + inline const CoeffReturnType coeff(int row, int col) const + { + return m_expression.coeff(row, col); + } + + inline Scalar& coeffRef(int row, int col) + { + return m_expression.const_cast_derived().coeffRef(row, col); + } + + inline const CoeffReturnType coeff(int index) const + { + return m_expression.coeff(index); + } + + inline Scalar& coeffRef(int index) + { + return m_expression.const_cast_derived().coeffRef(index); + } + + template<int LoadMode> + inline const PacketScalar packet(int row, int col) const + { + return m_expression.template packet<LoadMode>(row, col); + } + + template<int LoadMode> + inline void writePacket(int row, int col, const PacketScalar& x) + { + m_expression.const_cast_derived().template writePacket<LoadMode>(row, col, x); + } + + template<int LoadMode> + inline const PacketScalar packet(int index) const + { + return m_expression.template packet<LoadMode>(index); + } + + template<int LoadMode> + inline void writePacket(int index, const PacketScalar& x) + { + m_expression.const_cast_derived().template writePacket<LoadMode>(index, x); + } + + template<typename Dest> + inline void evalTo(Dest& dst) const { dst = m_expression; } + + protected: + const ExpressionType& m_expression; +}; + +template<typename ExpressionType> +struct ei_traits<MatrixWrapper<ExpressionType> > + : public ei_traits<ExpressionType> +{ + typedef DenseStorageMatrix DenseStorageType; +}; + +template<typename ExpressionType> +class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> > +{ + public: + EIGEN_GENERIC_PUBLIC_INTERFACE(MatrixWrapper) + EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper); + + inline MatrixWrapper(const ExpressionType& matrix) : m_expression(matrix) {} + + inline int rows() const { return m_expression.rows(); } + inline int cols() const { return m_expression.cols(); } + inline int stride() const { return m_expression.stride(); } + + inline const CoeffReturnType coeff(int row, int col) const + { + return m_expression.coeff(row, col); + } + + inline Scalar& coeffRef(int row, int col) + { + return m_expression.const_cast_derived().coeffRef(row, col); + } + + inline const CoeffReturnType coeff(int index) const + { + return m_expression.coeff(index); + } + + inline Scalar& coeffRef(int index) + { + return m_expression.const_cast_derived().coeffRef(index); + } + + template<int LoadMode> + inline const PacketScalar packet(int row, int col) const + { + return m_expression.template packet<LoadMode>(row, col); + } + + template<int LoadMode> + inline void writePacket(int row, int col, const PacketScalar& x) + { + m_expression.const_cast_derived().template writePacket<LoadMode>(row, col, x); + } + + template<int LoadMode> + inline const PacketScalar packet(int index) const + { + return m_expression.template packet<LoadMode>(index); + } + + template<int LoadMode> + inline void writePacket(int index, const PacketScalar& x) + { + m_expression.const_cast_derived().template writePacket<LoadMode>(index, x); + } + + protected: + const ExpressionType& m_expression; +}; + +#endif // EIGEN_ARRAYWRAPPER_H diff --git a/Eigen/src/Array/BooleanRedux.h b/Eigen/src/Array/BooleanRedux.h index ab6e06d56..9c6985a29 100644 --- a/Eigen/src/Array/BooleanRedux.h +++ b/Eigen/src/Array/BooleanRedux.h @@ -84,10 +84,10 @@ struct ei_any_unroller<Derived, Dynamic> * Example: \include MatrixBase_all.cpp * Output: \verbinclude MatrixBase_all.out * - * \sa MatrixBase::any(), Cwise::operator<() + * \sa any(), Cwise::operator<() */ template<typename Derived> -inline bool MatrixBase<Derived>::all() const +inline bool DenseBase<Derived>::all() const { const bool unroll = SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT; @@ -108,10 +108,10 @@ inline bool MatrixBase<Derived>::all() const * * \returns true if at least one coefficient is true * - * \sa MatrixBase::all() + * \sa all() */ template<typename Derived> -inline bool MatrixBase<Derived>::any() const +inline bool DenseBase<Derived>::any() const { const bool unroll = SizeAtCompileTime * (CoeffReadCost + NumTraits<Scalar>::AddCost) <= EIGEN_UNROLLING_LIMIT; @@ -132,12 +132,12 @@ inline bool MatrixBase<Derived>::any() const * * \returns the number of coefficients which evaluate to true * - * \sa MatrixBase::all(), MatrixBase::any() + * \sa all(), any() */ template<typename Derived> -inline int MatrixBase<Derived>::count() const +inline int DenseBase<Derived>::count() const { - return this->cast<bool>().cast<int>().sum(); + return derived().template cast<bool>().template cast<int>().sum(); } #endif // EIGEN_ALLANDANY_H diff --git a/Eigen/src/Array/Norms.h b/Eigen/src/Array/Norms.h index ef3f2f20d..07741cdc9 100644 --- a/Eigen/src/Array/Norms.h +++ b/Eigen/src/Array/Norms.h @@ -31,7 +31,7 @@ struct ei_lpNorm_selector typedef typename NumTraits<typename ei_traits<Derived>::Scalar>::Real RealScalar; inline static RealScalar run(const MatrixBase<Derived>& m) { - return ei_pow(m.cwise().abs().cwise().pow(p).sum(), RealScalar(1)/p); + return ei_pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p); } }; @@ -40,7 +40,7 @@ struct ei_lpNorm_selector<Derived, 1> { inline static typename NumTraits<typename ei_traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m) { - return m.cwise().abs().sum(); + return m.cwiseAbs().sum(); } }; @@ -58,12 +58,12 @@ struct ei_lpNorm_selector<Derived, Infinity> { inline static typename NumTraits<typename ei_traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m) { - return m.cwise().abs().maxCoeff(); + return m.cwiseAbs().maxCoeff(); } }; /** \array_module - * + * * \returns the \f$ \ell^p \f$ norm of *this, that is, returns the p-th root of the sum of the p-th powers of the absolute values * of the coefficients of *this. If \a p is the special value \a Eigen::Infinity, this function returns the \f$ \ell^p\infty \f$ * norm, that is the maximum of the absolute values of the coefficients of *this. diff --git a/Eigen/src/Array/Random.h b/Eigen/src/Array/Random.h index b94ccda68..97ca0fba3 100644 --- a/Eigen/src/Array/Random.h +++ b/Eigen/src/Array/Random.h @@ -55,7 +55,7 @@ struct ei_functor_traits<ei_scalar_random_op<Scalar> > */ template<typename Derived> inline const CwiseNullaryOp<ei_scalar_random_op<typename ei_traits<Derived>::Scalar>, Derived> -MatrixBase<Derived>::Random(int rows, int cols) +DenseBase<Derived>::Random(int rows, int cols) { return NullaryExpr(rows, cols, ei_scalar_random_op<Scalar>()); } @@ -84,7 +84,7 @@ MatrixBase<Derived>::Random(int rows, int cols) */ template<typename Derived> inline const CwiseNullaryOp<ei_scalar_random_op<typename ei_traits<Derived>::Scalar>, Derived> -MatrixBase<Derived>::Random(int size) +DenseBase<Derived>::Random(int size) { return NullaryExpr(size, ei_scalar_random_op<Scalar>()); } @@ -107,7 +107,7 @@ MatrixBase<Derived>::Random(int size) */ template<typename Derived> inline const CwiseNullaryOp<ei_scalar_random_op<typename ei_traits<Derived>::Scalar>, Derived> -MatrixBase<Derived>::Random() +DenseBase<Derived>::Random() { return NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, ei_scalar_random_op<Scalar>()); } @@ -122,7 +122,7 @@ MatrixBase<Derived>::Random() * \sa class CwiseNullaryOp, setRandom(int), setRandom(int,int) */ template<typename Derived> -inline Derived& MatrixBase<Derived>::setRandom() +inline Derived& DenseBase<Derived>::setRandom() { return *this = Random(rows(), cols()); } @@ -136,9 +136,9 @@ inline Derived& MatrixBase<Derived>::setRandom() * * \sa MatrixBase::setRandom(), setRandom(int,int), class CwiseNullaryOp, MatrixBase::Random() */ -template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> -EIGEN_STRONG_INLINE Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& -Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setRandom(int size) +template<typename Derived, template<typename> class _Base, int _Options> +EIGEN_STRONG_INLINE Derived& +DenseStorageBase<Derived,_Base,_Options>::setRandom(int size) { resize(size); return setRandom(); @@ -154,9 +154,9 @@ Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setRandom(int size) * * \sa MatrixBase::setRandom(), setRandom(int), class CwiseNullaryOp, MatrixBase::Random() */ -template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> -EIGEN_STRONG_INLINE Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& -Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setRandom(int rows, int cols) +template<typename Derived, template<typename> class _Base, int _Options> +EIGEN_STRONG_INLINE Derived& +DenseStorageBase<Derived,_Base,_Options>::setRandom(int rows, int cols) { resize(rows, cols); return setRandom(); diff --git a/Eigen/src/Array/Replicate.h b/Eigen/src/Array/Replicate.h index 653bda666..3f87e09fe 100644 --- a/Eigen/src/Array/Replicate.h +++ b/Eigen/src/Array/Replicate.h @@ -33,15 +33,17 @@ * \param MatrixType the type of the object we are replicating * * This class represents an expression of the multiple replication of a matrix or vector. - * It is the return type of MatrixBase::replicate() and most of the time + * It is the return type of DenseBase::replicate() and most of the time * this is the only way it is used. * - * \sa MatrixBase::replicate() + * \sa DenseBase::replicate() */ template<typename MatrixType,int RowFactor,int ColFactor> struct ei_traits<Replicate<MatrixType,RowFactor,ColFactor> > + : ei_traits<MatrixType> { typedef typename MatrixType::Scalar Scalar; + typedef typename ei_traits<MatrixType>::StorageType StorageType; typedef typename ei_nested<MatrixType>::type MatrixTypeNested; typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested; enum { @@ -59,11 +61,12 @@ struct ei_traits<Replicate<MatrixType,RowFactor,ColFactor> > }; template<typename MatrixType,int RowFactor,int ColFactor> class Replicate - : public MatrixBase<Replicate<MatrixType,RowFactor,ColFactor> > + : public MatrixType::template MakeBase< Replicate<MatrixType,RowFactor,ColFactor> >::Type { public: - EIGEN_GENERIC_PUBLIC_INTERFACE(Replicate) + typedef typename MatrixType::template MakeBase< Replicate<MatrixType,RowFactor,ColFactor> >::Type Base; + _EIGEN_GENERIC_PUBLIC_INTERFACE(Replicate) template<typename OriginalMatrixType> inline explicit Replicate(const OriginalMatrixType& matrix) @@ -102,12 +105,12 @@ template<typename MatrixType,int RowFactor,int ColFactor> class Replicate * Example: \include MatrixBase_replicate.cpp * Output: \verbinclude MatrixBase_replicate.out * - * \sa VectorwiseOp::replicate(), MatrixBase::replicate(int,int), class Replicate + * \sa VectorwiseOp::replicate(), DenseBase::replicate(int,int), class Replicate */ template<typename Derived> template<int RowFactor, int ColFactor> inline const Replicate<Derived,RowFactor,ColFactor> -MatrixBase<Derived>::replicate() const +DenseBase<Derived>::replicate() const { return Replicate<Derived,RowFactor,ColFactor>(derived()); } @@ -118,11 +121,11 @@ MatrixBase<Derived>::replicate() const * Example: \include MatrixBase_replicate_int_int.cpp * Output: \verbinclude MatrixBase_replicate_int_int.out * - * \sa VectorwiseOp::replicate(), MatrixBase::replicate<int,int>(), class Replicate + * \sa VectorwiseOp::replicate(), DenseBase::replicate<int,int>(), class Replicate */ template<typename Derived> inline const Replicate<Derived,Dynamic,Dynamic> -MatrixBase<Derived>::replicate(int rowFactor,int colFactor) const +DenseBase<Derived>::replicate(int rowFactor,int colFactor) const { return Replicate<Derived,Dynamic,Dynamic>(derived(),rowFactor,colFactor); } @@ -133,7 +136,7 @@ MatrixBase<Derived>::replicate(int rowFactor,int colFactor) const * Example: \include DirectionWise_replicate_int.cpp * Output: \verbinclude DirectionWise_replicate_int.out * - * \sa VectorwiseOp::replicate(), MatrixBase::replicate(), class Replicate + * \sa VectorwiseOp::replicate(), DenseBase::replicate(), class Replicate */ template<typename ExpressionType, int Direction> const Replicate<ExpressionType,(Direction==Vertical?Dynamic:1),(Direction==Horizontal?Dynamic:1)> diff --git a/Eigen/src/Array/Reverse.h b/Eigen/src/Array/Reverse.h index 4807bea55..a8d8310a9 100644 --- a/Eigen/src/Array/Reverse.h +++ b/Eigen/src/Array/Reverse.h @@ -43,8 +43,10 @@ */ template<typename MatrixType, int Direction> struct ei_traits<Reverse<MatrixType, Direction> > + : ei_traits<MatrixType> { typedef typename MatrixType::Scalar Scalar; + typedef typename ei_traits<MatrixType>::StorageType StorageType; typedef typename ei_nested<MatrixType>::type MatrixTypeNested; typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested; enum { @@ -75,11 +77,12 @@ template<typename PacketScalar> struct ei_reverse_packet_cond<PacketScalar,false }; template<typename MatrixType, int Direction> class Reverse - : public MatrixBase<Reverse<MatrixType, Direction> > + : public MatrixType::template MakeBase< Reverse<MatrixType, Direction> >::Type { public: - EIGEN_GENERIC_PUBLIC_INTERFACE(Reverse) + typedef typename MatrixType::template MakeBase< Reverse<MatrixType, Direction> >::Type Base; + _EIGEN_GENERIC_PUBLIC_INTERFACE(Reverse) protected: enum { @@ -167,7 +170,7 @@ template<typename MatrixType, int Direction> class Reverse */ template<typename Derived> inline Reverse<Derived, BothDirections> -MatrixBase<Derived>::reverse() +DenseBase<Derived>::reverse() { return derived(); } @@ -175,7 +178,7 @@ MatrixBase<Derived>::reverse() /** This is the const version of reverse(). */ template<typename Derived> inline const Reverse<Derived, BothDirections> -MatrixBase<Derived>::reverse() const +DenseBase<Derived>::reverse() const { return derived(); } @@ -193,7 +196,7 @@ MatrixBase<Derived>::reverse() const * * \sa reverse() */ template<typename Derived> -inline void MatrixBase<Derived>::reverseInPlace() +inline void DenseBase<Derived>::reverseInPlace() { derived() = derived().reverse().eval(); } diff --git a/Eigen/src/Array/Select.h b/Eigen/src/Array/Select.h index bc55147fd..b1fab69c9 100644 --- a/Eigen/src/Array/Select.h +++ b/Eigen/src/Array/Select.h @@ -36,15 +36,17 @@ * \param ElseMatrixType the type of the \em else expression * * This class represents an expression of a coefficient wise version of the C++ ternary operator ?:. - * It is the return type of MatrixBase::select() and most of the time this is the only way it is used. + * It is the return type of DenseBase::select() and most of the time this is the only way it is used. * - * \sa MatrixBase::select(const MatrixBase<ThenDerived>&, const MatrixBase<ElseDerived>&) const + * \sa DenseBase::select(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const */ template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType> struct ei_traits<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> > + : ei_traits<ThenMatrixType> { typedef typename ei_traits<ThenMatrixType>::Scalar Scalar; + typedef Dense StorageType; typedef typename ConditionMatrixType::Nested ConditionMatrixNested; typedef typename ThenMatrixType::Nested ThenMatrixNested; typedef typename ElseMatrixType::Nested ElseMatrixNested; @@ -62,11 +64,12 @@ struct ei_traits<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> > template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType> class Select : ei_no_assignment_operator, - public MatrixBase<Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> > + public ThenMatrixType::template MakeBase< Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >::Type { public: - EIGEN_GENERIC_PUBLIC_INTERFACE(Select) + typedef typename ThenMatrixType::template MakeBase< Select<ConditionMatrixType, ThenMatrixType, ElseMatrixType> >::Type Base; + _EIGEN_GENERIC_PUBLIC_INTERFACE(Select) Select(const ConditionMatrixType& conditionMatrix, const ThenMatrixType& thenMatrix, @@ -87,7 +90,7 @@ class Select : ei_no_assignment_operator, else return m_else.coeff(i,j); } - + const Scalar coeff(int i) const { if (m_condition.coeff(i)) @@ -116,23 +119,23 @@ class Select : ei_no_assignment_operator, template<typename Derived> template<typename ThenDerived,typename ElseDerived> inline const Select<Derived,ThenDerived,ElseDerived> -MatrixBase<Derived>::select(const MatrixBase<ThenDerived>& thenMatrix, - const MatrixBase<ElseDerived>& elseMatrix) const +DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix, + const DenseBase<ElseDerived>& elseMatrix) const { return Select<Derived,ThenDerived,ElseDerived>(derived(), thenMatrix.derived(), elseMatrix.derived()); } /** \array_module * - * Version of MatrixBase::select(const MatrixBase&, const MatrixBase&) with + * Version of DenseBase::select(const DenseBase&, const DenseBase&) with * the \em else expression being a scalar value. * - * \sa MatrixBase::select(const MatrixBase<ThenDerived>&, const MatrixBase<ElseDerived>&) const, class Select + * \sa DenseBase::select(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const, class Select */ template<typename Derived> template<typename ThenDerived> inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType> -MatrixBase<Derived>::select(const MatrixBase<ThenDerived>& thenMatrix, +DenseBase<Derived>::select(const DenseBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const { return Select<Derived,ThenDerived,typename ThenDerived::ConstantReturnType>( @@ -141,16 +144,16 @@ MatrixBase<Derived>::select(const MatrixBase<ThenDerived>& thenMatrix, /** \array_module * - * Version of MatrixBase::select(const MatrixBase&, const MatrixBase&) with + * Version of DenseBase::select(const DenseBase&, const DenseBase&) with * the \em then expression being a scalar value. * - * \sa MatrixBase::select(const MatrixBase<ThenDerived>&, const MatrixBase<ElseDerived>&) const, class Select + * \sa DenseBase::select(const DenseBase<ThenDerived>&, const DenseBase<ElseDerived>&) const, class Select */ template<typename Derived> template<typename ElseDerived> inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived > -MatrixBase<Derived>::select(typename ElseDerived::Scalar thenScalar, - const MatrixBase<ElseDerived>& elseMatrix) const +DenseBase<Derived>::select(typename ElseDerived::Scalar thenScalar, + const DenseBase<ElseDerived>& elseMatrix) const { return Select<Derived,typename ElseDerived::ConstantReturnType,ElseDerived>( derived(), ElseDerived::Constant(rows(),cols(),thenScalar), elseMatrix.derived()); diff --git a/Eigen/src/Array/VectorwiseOp.h b/Eigen/src/Array/VectorwiseOp.h index bb695c795..05dd69789 100644 --- a/Eigen/src/Array/VectorwiseOp.h +++ b/Eigen/src/Array/VectorwiseOp.h @@ -48,8 +48,10 @@ class PartialReduxExpr; template<typename MatrixType, typename MemberOp, int Direction> struct ei_traits<PartialReduxExpr<MatrixType, MemberOp, Direction> > + : ei_traits<MatrixType> { typedef typename MemberOp::result_type Scalar; + typedef typename ei_traits<MatrixType>::StorageType StorageType; typedef typename MatrixType::Scalar InputScalar; typedef typename ei_nested<MatrixType>::type MatrixTypeNested; typedef typename ei_cleantype<MatrixTypeNested>::type _MatrixTypeNested; @@ -73,11 +75,12 @@ struct ei_traits<PartialReduxExpr<MatrixType, MemberOp, Direction> > template< typename MatrixType, typename MemberOp, int Direction> class PartialReduxExpr : ei_no_assignment_operator, - public MatrixBase<PartialReduxExpr<MatrixType, MemberOp, Direction> > + public MatrixType::template MakeBase< PartialReduxExpr<MatrixType, MemberOp, Direction> >::Type { public: - EIGEN_GENERIC_PUBLIC_INTERFACE(PartialReduxExpr) + typedef typename MatrixType::template MakeBase< PartialReduxExpr<MatrixType, MemberOp, Direction> >::Type Base; + _EIGEN_GENERIC_PUBLIC_INTERFACE(PartialReduxExpr) typedef typename ei_traits<PartialReduxExpr>::MatrixTypeNested MatrixTypeNested; typedef typename ei_traits<PartialReduxExpr>::_MatrixTypeNested _MatrixTypeNested; diff --git a/Eigen/src/CMakeLists.txt b/Eigen/src/CMakeLists.txt index 4c3ee6cb8..0d3604f06 100644 --- a/Eigen/src/CMakeLists.txt +++ b/Eigen/src/CMakeLists.txt @@ -10,4 +10,5 @@ ADD_SUBDIRECTORY(Sparse) ADD_SUBDIRECTORY(Jacobi) ADD_SUBDIRECTORY(Householder) ADD_SUBDIRECTORY(Eigenvalues) -ADD_SUBDIRECTORY(misc)
\ No newline at end of file +ADD_SUBDIRECTORY(misc) +ADD_SUBDIRECTORY(plugins) diff --git a/Eigen/src/Cholesky/LDLT.h b/Eigen/src/Cholesky/LDLT.h index d0f292634..c13be9ac2 100644 --- a/Eigen/src/Cholesky/LDLT.h +++ b/Eigen/src/Cholesky/LDLT.h @@ -81,7 +81,7 @@ template<typename _MatrixType> class LDLT /** \returns the lower triangular matrix L */ inline TriangularView<MatrixType, UnitLowerTriangular> matrixL(void) const - { + { ei_assert(m_isInitialized && "LDLT is not initialized."); return m_matrix; } @@ -132,7 +132,7 @@ template<typename _MatrixType> class LDLT && "LDLT::solve(): invalid number of rows of the right hand side matrix b"); return ei_solve_retval<LDLT, Rhs>(*this, b.derived()); } - + template<typename Derived> bool solveInPlace(MatrixBase<Derived> &bAndX) const; @@ -150,7 +150,7 @@ template<typename _MatrixType> class LDLT inline int rows() const { return m_matrix.rows(); } inline int cols() const { return m_matrix.cols(); } - + protected: /** \internal * Used to compute and store the Cholesky decomposition A = L D L^* = U^* D U. @@ -194,7 +194,7 @@ LDLT<MatrixType>& LDLT<MatrixType>::compute(const MatrixType& a) { // Find largest diagonal element int index_of_biggest_in_corner; - biggest_in_corner = m_matrix.diagonal().end(size-j).cwise().abs() + biggest_in_corner = m_matrix.diagonal().end(size-j).cwiseAbs() .maxCoeff(&index_of_biggest_in_corner); index_of_biggest_in_corner += j; @@ -304,7 +304,7 @@ bool LDLT<MatrixType>::solveInPlace(MatrixBase<Derived> &bAndX) const m_matrix.template triangularView<UnitLowerTriangular>().solveInPlace(bAndX); // w = D^-1 y - bAndX = (m_matrix.diagonal().cwise().inverse().asDiagonal() * bAndX).lazy(); + bAndX = m_matrix.diagonal().asDiagonal().inverse() * bAndX; // u = L^-T w m_matrix.adjoint().template triangularView<UnitUpperTriangular>().solveInPlace(bAndX); diff --git a/Eigen/src/Core/AnyMatrixBase.h b/Eigen/src/Core/AnyMatrixBase.h index eddf2d232..d1c16923b 100644 --- a/Eigen/src/Core/AnyMatrixBase.h +++ b/Eigen/src/Core/AnyMatrixBase.h @@ -37,11 +37,16 @@ */ template<typename Derived> struct AnyMatrixBase { - typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType; +// typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType; + /** \returns a reference to the derived object */ Derived& derived() { return *static_cast<Derived*>(this); } + /** \returns a const reference to the derived object */ const Derived& derived() const { return *static_cast<const Derived*>(this); } + inline Derived& const_cast_derived() const + { return *static_cast<Derived*>(const_cast<AnyMatrixBase*>(this)); } + /** \returns the number of rows. \sa cols(), RowsAtCompileTime */ inline int rows() const { return derived().rows(); } /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/ @@ -99,7 +104,7 @@ template<typename Derived> struct AnyMatrixBase * special matrix without having to modify MatrixBase */ template<typename Derived> template<typename OtherDerived> -Derived& MatrixBase<Derived>::operator=(const AnyMatrixBase<OtherDerived> &other) +Derived& DenseBase<Derived>::operator=(const AnyMatrixBase<OtherDerived> &other) { other.derived().evalTo(derived()); return derived(); @@ -107,7 +112,7 @@ Derived& MatrixBase<Derived>::operator=(const AnyMatrixBase<OtherDerived> &other template<typename Derived> template<typename OtherDerived> -Derived& MatrixBase<Derived>::operator+=(const AnyMatrixBase<OtherDerived> &other) +Derived& DenseBase<Derived>::operator+=(const AnyMatrixBase<OtherDerived> &other) { other.derived().addTo(derived()); return derived(); @@ -115,7 +120,7 @@ Derived& MatrixBase<Derived>::operator+=(const AnyMatrixBase<OtherDerived> &othe template<typename Derived> template<typename OtherDerived> -Derived& MatrixBase<Derived>::operator-=(const AnyMatrixBase<OtherDerived> &other) +Derived& DenseBase<Derived>::operator-=(const AnyMatrixBase<OtherDerived> &other) { other.derived().subTo(derived()); return derived(); diff --git a/Eigen/src/Core/Assign.h b/Eigen/src/Core/Assign.h index d544a6198..d6bf37c6e 100644 --- a/Eigen/src/Core/Assign.h +++ b/Eigen/src/Core/Assign.h @@ -469,13 +469,13 @@ struct ei_assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling> }; /*************************************************************************** -* Part 4 : implementation of MatrixBase methods +* Part 4 : implementation of DenseBase methods ***************************************************************************/ template<typename Derived> template<typename OtherDerived> -EIGEN_STRONG_INLINE Derived& MatrixBase<Derived> - ::lazyAssign(const MatrixBase<OtherDerived>& other) +EIGEN_STRONG_INLINE Derived& DenseBase<Derived> + ::lazyAssign(const DenseBase<OtherDerived>& other) { EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived) EIGEN_STATIC_ASSERT((ei_is_same_type<typename Derived::Scalar, typename OtherDerived::Scalar>::ret), @@ -521,16 +521,21 @@ struct ei_assign_selector<Derived,OtherDerived,true,true> { template<typename Derived> template<typename OtherDerived> -EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const MatrixBase<OtherDerived>& other) +EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase<OtherDerived>& other) { return ei_assign_selector<Derived,OtherDerived>::run(derived(), other.derived()); } template<typename Derived> -EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const MatrixBase& other) +EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::operator=(const DenseBase& other) { return ei_assign_selector<Derived,Derived>::run(derived(), other.derived()); } +template<typename Derived> +EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::operator=(const MatrixBase& other) +{ + return ei_assign_selector<Derived,Derived>::run(derived(), other.derived()); +} #endif // EIGEN_ASSIGN_H diff --git a/Eigen/src/Core/Block.h b/Eigen/src/Core/Block.h index f9bbf473d..461652410 100644 --- a/Eigen/src/Core/Block.h +++ b/Eigen/src/Core/Block.h @@ -33,14 +33,10 @@ * \param MatrixType the type of the object in which we are taking a block * \param BlockRows the number of rows of the block we are taking at compile time (optional) * \param BlockCols the number of columns of the block we are taking at compile time (optional) - * \param _PacketAccess \internal used to enforce aligned loads in expressions such as - * \code mat.block() += other; \endcode. Possible values are - * \c AsRequested (default) and \c EnforceAlignedAccess. - * See class MapBase for more details. * \param _DirectAccessStatus \internal used for partial specialization * * This class represents an expression of either a fixed-size or dynamic-size block. It is the return - * type of MatrixBase::block(int,int,int,int) and MatrixBase::block<int,int>(int,int) and + * type of DenseBase::block(int,int,int,int) and DenseBase::block<int,int>(int,int) and * most of the time this is the only way it is used. * * However, if you want to directly maniputate block expressions, @@ -59,10 +55,10 @@ * \include class_FixedBlock.cpp * Output: \verbinclude class_FixedBlock.out * - * \sa MatrixBase::block(int,int,int,int), MatrixBase::block(int,int), class VectorBlock + * \sa DenseBase::block(int,int,int,int), DenseBase::block(int,int), class VectorBlock */ -template<typename MatrixType, int BlockRows, int BlockCols, int _PacketAccess, int _DirectAccessStatus> -struct ei_traits<Block<MatrixType, BlockRows, BlockCols, _PacketAccess, _DirectAccessStatus> > +template<typename MatrixType, int BlockRows, int BlockCols, int _DirectAccessStatus> +struct ei_traits<Block<MatrixType, BlockRows, BlockCols, _DirectAccessStatus> > : ei_traits<MatrixType> { typedef typename ei_traits<MatrixType>::Scalar Scalar; typedef typename ei_nested<MatrixType>::type MatrixTypeNested; @@ -80,17 +76,12 @@ struct ei_traits<Block<MatrixType, BlockRows, BlockCols, _PacketAccess, _DirectA MaskPacketAccessBit = (InnerMaxSize == Dynamic || (InnerSize >= ei_packet_traits<Scalar>::size)) ? PacketAccessBit : 0, FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0, - Flags = (ei_traits<MatrixType>::Flags & (HereditaryBits | MaskPacketAccessBit | DirectAccessBit)) | FlagsLinearAccessBit, - CoeffReadCost = ei_traits<MatrixType>::CoeffReadCost, - PacketAccess = _PacketAccess + Flags = (ei_traits<MatrixType>::Flags & (HereditaryBits | MaskPacketAccessBit | DirectAccessBit)) | FlagsLinearAccessBit }; - typedef typename ei_meta_if<int(PacketAccess)==EnforceAlignedAccess, - Block<MatrixType, BlockRows, BlockCols, _PacketAccess, _DirectAccessStatus>&, - Block<MatrixType, BlockRows, BlockCols, EnforceAlignedAccess, _DirectAccessStatus> >::ret AlignedDerivedType; }; -template<typename MatrixType, int BlockRows, int BlockCols, int PacketAccess, int _DirectAccessStatus> class Block - : public MatrixBase<Block<MatrixType, BlockRows, BlockCols, PacketAccess, _DirectAccessStatus> > +template<typename MatrixType, int BlockRows, int BlockCols, int _DirectAccessStatus> class Block + :public MatrixType::template MakeBase< Block<MatrixType, BlockRows, BlockCols, _DirectAccessStatus> >::Type { public: @@ -218,26 +209,18 @@ template<typename MatrixType, int BlockRows, int BlockCols, int PacketAccess, in }; /** \internal */ -template<typename MatrixType, int BlockRows, int BlockCols, int PacketAccess> -class Block<MatrixType,BlockRows,BlockCols,PacketAccess,HasDirectAccess> - : public MapBase<Block<MatrixType, BlockRows, BlockCols,PacketAccess,HasDirectAccess> > +template<typename MatrixType, int BlockRows, int BlockCols> +class Block<MatrixType,BlockRows,BlockCols,HasDirectAccess> + : public MapBase<Block<MatrixType, BlockRows, BlockCols,HasDirectAccess>, + typename MatrixType::template MakeBase< Block<MatrixType, BlockRows, BlockCols,HasDirectAccess> >::Type> { public: - _EIGEN_GENERIC_PUBLIC_INTERFACE(Block, MapBase<Block>) - - class InnerIterator; - typedef typename ei_traits<Block>::AlignedDerivedType AlignedDerivedType; - friend class Block<MatrixType,BlockRows,BlockCols,PacketAccess==int(EnforceAlignedAccess)?AsRequested:EnforceAlignedAccess,HasDirectAccess>; + typedef MapBase<Block, typename MatrixType::template MakeBase<Block>::Type> Base; + _EIGEN_GENERIC_PUBLIC_INTERFACE(Block) EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block) - AlignedDerivedType _convertToEnforceAlignedAccess() - { - return Block<MatrixType,BlockRows,BlockCols,EnforceAlignedAccess,HasDirectAccess> - (m_matrix, Base::m_data, Base::m_rows.value(), Base::m_cols.value()); - } - /** Column or Row constructor */ inline Block(const MatrixType& matrix, int i) @@ -318,7 +301,7 @@ class Block<MatrixType,BlockRows,BlockCols,PacketAccess,HasDirectAccess> * \sa class Block, block(int,int) */ template<typename Derived> -inline typename BlockReturnType<Derived>::Type MatrixBase<Derived> +inline typename BlockReturnType<Derived>::Type DenseBase<Derived> ::block(int startRow, int startCol, int blockRows, int blockCols) { return typename BlockReturnType<Derived>::Type(derived(), startRow, startCol, blockRows, blockCols); @@ -326,7 +309,7 @@ inline typename BlockReturnType<Derived>::Type MatrixBase<Derived> /** This is the const version of block(int,int,int,int). */ template<typename Derived> -inline const typename BlockReturnType<Derived>::Type MatrixBase<Derived> +inline const typename BlockReturnType<Derived>::Type DenseBase<Derived> ::block(int startRow, int startCol, int blockRows, int blockCols) const { return typename BlockReturnType<Derived>::Type(derived(), startRow, startCol, blockRows, blockCols); @@ -349,7 +332,7 @@ inline const typename BlockReturnType<Derived>::Type MatrixBase<Derived> * \sa class Block, block(int,int,int,int) */ template<typename Derived> -inline typename BlockReturnType<Derived>::Type MatrixBase<Derived> +inline typename BlockReturnType<Derived>::Type DenseBase<Derived> ::corner(CornerType type, int cRows, int cCols) { switch(type) @@ -370,7 +353,7 @@ inline typename BlockReturnType<Derived>::Type MatrixBase<Derived> /** This is the const version of corner(CornerType, int, int).*/ template<typename Derived> inline const typename BlockReturnType<Derived>::Type -MatrixBase<Derived>::corner(CornerType type, int cRows, int cCols) const +DenseBase<Derived>::corner(CornerType type, int cRows, int cCols) const { switch(type) { @@ -402,7 +385,7 @@ MatrixBase<Derived>::corner(CornerType type, int cRows, int cCols) const template<typename Derived> template<int CRows, int CCols> inline typename BlockReturnType<Derived, CRows, CCols>::Type -MatrixBase<Derived>::corner(CornerType type) +DenseBase<Derived>::corner(CornerType type) { switch(type) { @@ -423,7 +406,7 @@ MatrixBase<Derived>::corner(CornerType type) template<typename Derived> template<int CRows, int CCols> inline const typename BlockReturnType<Derived, CRows, CCols>::Type -MatrixBase<Derived>::corner(CornerType type) const +DenseBase<Derived>::corner(CornerType type) const { switch(type) { @@ -459,7 +442,7 @@ MatrixBase<Derived>::corner(CornerType type) const template<typename Derived> template<int BlockRows, int BlockCols> inline typename BlockReturnType<Derived, BlockRows, BlockCols>::Type -MatrixBase<Derived>::block(int startRow, int startCol) +DenseBase<Derived>::block(int startRow, int startCol) { return Block<Derived, BlockRows, BlockCols>(derived(), startRow, startCol); } @@ -468,7 +451,7 @@ MatrixBase<Derived>::block(int startRow, int startCol) template<typename Derived> template<int BlockRows, int BlockCols> inline const typename BlockReturnType<Derived, BlockRows, BlockCols>::Type -MatrixBase<Derived>::block(int startRow, int startCol) const +DenseBase<Derived>::block(int startRow, int startCol) const { return Block<Derived, BlockRows, BlockCols>(derived(), startRow, startCol); } @@ -480,16 +463,16 @@ MatrixBase<Derived>::block(int startRow, int startCol) const * * \sa row(), class Block */ template<typename Derived> -inline typename MatrixBase<Derived>::ColXpr -MatrixBase<Derived>::col(int i) +inline typename DenseBase<Derived>::ColXpr +DenseBase<Derived>::col(int i) { return ColXpr(derived(), i); } /** This is the const version of col(). */ template<typename Derived> -inline const typename MatrixBase<Derived>::ColXpr -MatrixBase<Derived>::col(int i) const +inline const typename DenseBase<Derived>::ColXpr +DenseBase<Derived>::col(int i) const { return ColXpr(derived(), i); } @@ -501,16 +484,16 @@ MatrixBase<Derived>::col(int i) const * * \sa col(), class Block */ template<typename Derived> -inline typename MatrixBase<Derived>::RowXpr -MatrixBase<Derived>::row(int i) +inline typename DenseBase<Derived>::RowXpr +DenseBase<Derived>::row(int i) { return RowXpr(derived(), i); } /** This is the const version of row(). */ template<typename Derived> -inline const typename MatrixBase<Derived>::RowXpr -MatrixBase<Derived>::row(int i) const +inline const typename DenseBase<Derived>::RowXpr +DenseBase<Derived>::row(int i) const { return RowXpr(derived(), i); } diff --git a/Eigen/src/Core/Coeffs.h b/Eigen/src/Core/Coeffs.h index eda36b7bb..b8af2531e 100644 --- a/Eigen/src/Core/Coeffs.h +++ b/Eigen/src/Core/Coeffs.h @@ -40,7 +40,7 @@ * \sa operator()(int,int) const, coeffRef(int,int), coeff(int) const */ template<typename Derived> -EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::CoeffReturnType MatrixBase<Derived> +EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase<Derived> ::coeff(int row, int col) const { ei_internal_assert(row >= 0 && row < rows() @@ -53,7 +53,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::CoeffReturnType MatrixBa * \sa operator()(int,int), operator[](int) const */ template<typename Derived> -EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::CoeffReturnType MatrixBase<Derived> +EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase<Derived> ::operator()(int row, int col) const { ei_assert(row >= 0 && row < rows() @@ -76,7 +76,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::CoeffReturnType MatrixBa * \sa operator()(int,int), coeff(int, int) const, coeffRef(int) */ template<typename Derived> -EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived> +EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& DenseBase<Derived> ::coeffRef(int row, int col) { ei_internal_assert(row >= 0 && row < rows() @@ -89,7 +89,7 @@ EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived> * \sa operator()(int,int) const, operator[](int) */ template<typename Derived> -EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived> +EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& DenseBase<Derived> ::operator()(int row, int col) { ei_assert(row >= 0 && row < rows() @@ -112,7 +112,7 @@ EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived> * \sa operator[](int) const, coeffRef(int), coeff(int,int) const */ template<typename Derived> -EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::CoeffReturnType MatrixBase<Derived> +EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase<Derived> ::coeff(int index) const { ei_internal_assert(index >= 0 && index < size()); @@ -127,7 +127,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::CoeffReturnType MatrixBa * z() const, w() const */ template<typename Derived> -EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::CoeffReturnType MatrixBase<Derived> +EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase<Derived> ::operator[](int index) const { ei_assert(index >= 0 && index < size()); @@ -144,7 +144,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::CoeffReturnType MatrixBa * z() const, w() const */ template<typename Derived> -EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::CoeffReturnType MatrixBase<Derived> +EIGEN_STRONG_INLINE const typename DenseBase<Derived>::CoeffReturnType DenseBase<Derived> ::operator()(int index) const { ei_assert(index >= 0 && index < size()); @@ -166,7 +166,7 @@ EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::CoeffReturnType MatrixBa * \sa operator[](int), coeff(int) const, coeffRef(int,int) */ template<typename Derived> -EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived> +EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& DenseBase<Derived> ::coeffRef(int index) { ei_internal_assert(index >= 0 && index < size()); @@ -180,7 +180,7 @@ EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived> * \sa operator[](int) const, operator()(int,int), x(), y(), z(), w() */ template<typename Derived> -EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived> +EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& DenseBase<Derived> ::operator[](int index) { ei_assert(index >= 0 && index < size()); @@ -196,7 +196,7 @@ EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived> * \sa operator[](int) const, operator()(int,int), x(), y(), z(), w() */ template<typename Derived> -EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived> +EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& DenseBase<Derived> ::operator()(int index) { ei_assert(index >= 0 && index < size()); @@ -254,7 +254,7 @@ EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar& MatrixBase<Derived> template<typename Derived> template<int LoadMode> EIGEN_STRONG_INLINE typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type -MatrixBase<Derived>::packet(int row, int col) const +DenseBase<Derived>::packet(int row, int col) const { ei_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols()); @@ -271,7 +271,7 @@ MatrixBase<Derived>::packet(int row, int col) const */ template<typename Derived> template<int StoreMode> -EIGEN_STRONG_INLINE void MatrixBase<Derived>::writePacket +EIGEN_STRONG_INLINE void DenseBase<Derived>::writePacket (int row, int col, const typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type& x) { ei_internal_assert(row >= 0 && row < rows() @@ -290,7 +290,7 @@ EIGEN_STRONG_INLINE void MatrixBase<Derived>::writePacket template<typename Derived> template<int LoadMode> EIGEN_STRONG_INLINE typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type -MatrixBase<Derived>::packet(int index) const +DenseBase<Derived>::packet(int index) const { ei_internal_assert(index >= 0 && index < size()); return derived().template packet<LoadMode>(index); @@ -306,7 +306,7 @@ MatrixBase<Derived>::packet(int index) const */ template<typename Derived> template<int StoreMode> -EIGEN_STRONG_INLINE void MatrixBase<Derived>::writePacket +EIGEN_STRONG_INLINE void DenseBase<Derived>::writePacket (int index, const typename ei_packet_traits<typename ei_traits<Derived>::Scalar>::type& x) { ei_internal_assert(index >= 0 && index < size()); @@ -324,7 +324,7 @@ EIGEN_STRONG_INLINE void MatrixBase<Derived>::writePacket */ template<typename Derived> template<typename OtherDerived> -EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyCoeff(int row, int col, const MatrixBase<OtherDerived>& other) +EIGEN_STRONG_INLINE void DenseBase<Derived>::copyCoeff(int row, int col, const DenseBase<OtherDerived>& other) { ei_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols()); @@ -340,7 +340,7 @@ EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyCoeff(int row, int col, const */ template<typename Derived> template<typename OtherDerived> -EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyCoeff(int index, const MatrixBase<OtherDerived>& other) +EIGEN_STRONG_INLINE void DenseBase<Derived>::copyCoeff(int index, const DenseBase<OtherDerived>& other) { ei_internal_assert(index >= 0 && index < size()); derived().coeffRef(index) = other.derived().coeff(index); @@ -355,7 +355,7 @@ EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyCoeff(int index, const MatrixB */ template<typename Derived> template<typename OtherDerived, int StoreMode, int LoadMode> -EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyPacket(int row, int col, const MatrixBase<OtherDerived>& other) +EIGEN_STRONG_INLINE void DenseBase<Derived>::copyPacket(int row, int col, const DenseBase<OtherDerived>& other) { ei_internal_assert(row >= 0 && row < rows() && col >= 0 && col < cols()); @@ -372,7 +372,7 @@ EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyPacket(int row, int col, const */ template<typename Derived> template<typename OtherDerived, int StoreMode, int LoadMode> -EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyPacket(int index, const MatrixBase<OtherDerived>& other) +EIGEN_STRONG_INLINE void DenseBase<Derived>::copyPacket(int index, const DenseBase<OtherDerived>& other) { ei_internal_assert(index >= 0 && index < size()); derived().template writePacket<StoreMode>(index, @@ -383,14 +383,14 @@ EIGEN_STRONG_INLINE void MatrixBase<Derived>::copyPacket(int index, const Matrix template<typename Derived, typename Integer, bool JustReturnZero> struct ei_alignmentOffset_impl { - inline static Integer run(const MatrixBase<Derived>&, Integer) + inline static Integer run(const DenseBase<Derived>&, Integer) { return 0; } }; template<typename Derived, typename Integer> struct ei_alignmentOffset_impl<Derived, Integer, false> { - inline static Integer run(const MatrixBase<Derived>& m, Integer maxOffset) + inline static Integer run(const DenseBase<Derived>& m, Integer maxOffset) { return ei_alignmentOffset(&m.const_cast_derived().coeffRef(0,0), maxOffset); } @@ -404,7 +404,7 @@ struct ei_alignmentOffset_impl<Derived, Integer, false> * There is also the variant ei_alignmentOffset(const Scalar*, Integer) defined in Memory.h. */ template<typename Derived, typename Integer> -inline static Integer ei_alignmentOffset(const MatrixBase<Derived>& m, Integer maxOffset) +inline static Integer ei_alignmentOffset(const DenseBase<Derived>& m, Integer maxOffset) { return ei_alignmentOffset_impl<Derived, Integer, (Derived::Flags & AlignedBit) || !(Derived::Flags & DirectAccessBit)> diff --git a/Eigen/src/Core/CommaInitializer.h b/Eigen/src/Core/CommaInitializer.h index e86f47ad0..a312b40f5 100644 --- a/Eigen/src/Core/CommaInitializer.h +++ b/Eigen/src/Core/CommaInitializer.h @@ -47,7 +47,7 @@ struct CommaInitializer } template<typename OtherDerived> - inline CommaInitializer(MatrixType& mat, const MatrixBase<OtherDerived>& other) + inline CommaInitializer(MatrixType& mat, const DenseBase<OtherDerived>& other) : m_matrix(mat), m_row(0), m_col(other.cols()), m_currentBlockRows(other.rows()) { m_matrix.block(0, 0, other.rows(), other.cols()) = other; @@ -73,7 +73,7 @@ struct CommaInitializer /* inserts a matrix expression in the target matrix */ template<typename OtherDerived> - CommaInitializer& operator,(const MatrixBase<OtherDerived>& other) + CommaInitializer& operator,(const DenseBase<OtherDerived>& other) { if (m_col==m_matrix.cols()) { @@ -130,7 +130,7 @@ struct CommaInitializer * \sa CommaInitializer::finished(), class CommaInitializer */ template<typename Derived> -inline CommaInitializer<Derived> MatrixBase<Derived>::operator<< (const Scalar& s) +inline CommaInitializer<Derived> DenseBase<Derived>::operator<< (const Scalar& s) { return CommaInitializer<Derived>(*static_cast<Derived*>(this), s); } @@ -139,7 +139,7 @@ inline CommaInitializer<Derived> MatrixBase<Derived>::operator<< (const Scalar& template<typename Derived> template<typename OtherDerived> inline CommaInitializer<Derived> -MatrixBase<Derived>::operator<<(const MatrixBase<OtherDerived>& other) +DenseBase<Derived>::operator<<(const DenseBase<OtherDerived>& other) { return CommaInitializer<Derived>(*static_cast<Derived *>(this), other); } diff --git a/Eigen/src/Core/CwiseBinaryOp.h b/Eigen/src/Core/CwiseBinaryOp.h index 4bea0425f..4d7ab6598 100644 --- a/Eigen/src/Core/CwiseBinaryOp.h +++ b/Eigen/src/Core/CwiseBinaryOp.h @@ -1,7 +1,7 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> +// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // // Eigen is free software; you can redistribute it and/or @@ -44,7 +44,7 @@ * \sa MatrixBase::binaryExpr(const MatrixBase<OtherDerived> &,const CustomBinaryOp &) const, class CwiseUnaryOp, class CwiseNullaryOp */ template<typename BinaryOp, typename Lhs, typename Rhs> -struct ei_traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > +struct ei_traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > : ei_traits<Lhs> { // even though we require Lhs and Rhs to have the same scalar type (see CwiseBinaryOp constructor), // we still want to handle the case when the result type is different. @@ -54,6 +54,8 @@ struct ei_traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > typename Rhs::Scalar ) >::type Scalar; + typedef typename ei_promote_storage_type<typename ei_traits<Lhs>::StorageType, + typename ei_traits<Rhs>::StorageType>::ret StorageType; typedef typename Lhs::Nested LhsNested; typedef typename Rhs::Nested RhsNested; typedef typename ei_unref<LhsNested>::type _LhsNested; @@ -63,10 +65,6 @@ struct ei_traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > RhsCoeffReadCost = _RhsNested::CoeffReadCost, LhsFlags = _LhsNested::Flags, RhsFlags = _RhsNested::Flags, - RowsAtCompileTime = Lhs::RowsAtCompileTime, - ColsAtCompileTime = Lhs::ColsAtCompileTime, - MaxRowsAtCompileTime = Lhs::MaxRowsAtCompileTime, - MaxColsAtCompileTime = Lhs::MaxColsAtCompileTime, StorageOrdersAgree = (int(Lhs::Flags)&RowMajorBit)==(int(Rhs::Flags)&RowMajorBit), Flags = (int(LhsFlags) | int(RhsFlags)) & ( HereditaryBits @@ -81,13 +79,24 @@ struct ei_traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > }; }; +template<typename BinaryOp, typename Lhs, typename Rhs, typename StorageType> +class CwiseBinaryOpImpl; + template<typename BinaryOp, typename Lhs, typename Rhs> class CwiseBinaryOp : ei_no_assignment_operator, - public MatrixBase<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > + public CwiseBinaryOpImpl< + BinaryOp, Lhs, Rhs, + typename ei_promote_storage_type<typename ei_traits<Lhs>::StorageType, + typename ei_traits<Rhs>::StorageType>::ret> { public: - EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseBinaryOp) + typedef typename CwiseBinaryOpImpl< + BinaryOp, Lhs, Rhs, + typename ei_promote_storage_type<typename ei_traits<Lhs>::StorageType, + typename ei_traits<Rhs>::StorageType>::ret>::Base Base; + EIGEN_GENERIC_PUBLIC_INTERFACE_NEW(CwiseBinaryOp) + typedef typename ei_traits<CwiseBinaryOp>::LhsNested LhsNested; typedef typename ei_traits<CwiseBinaryOp>::RhsNested RhsNested; typedef typename ei_traits<CwiseBinaryOp>::_LhsNested _LhsNested; @@ -115,54 +124,53 @@ class CwiseBinaryOp : ei_no_assignment_operator, EIGEN_STRONG_INLINE int rows() const { return m_lhs.rows(); } EIGEN_STRONG_INLINE int cols() const { return m_lhs.cols(); } + const _LhsNested& lhs() const { return m_lhs; } + const _RhsNested& rhs() const { return m_rhs; } + const BinaryOp& functor() const { return m_functor; } + + protected: + const LhsNested m_lhs; + const RhsNested m_rhs; + const BinaryOp m_functor; +}; + +template<typename BinaryOp, typename Lhs, typename Rhs> +class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Dense> + : public Lhs::template MakeBase< CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::Type +{ + public: + + typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived; + typedef typename Lhs::template MakeBase< CwiseBinaryOp<BinaryOp, Lhs, Rhs> >::Type Base; + _EIGEN_DENSE_PUBLIC_INTERFACE( Derived ) + EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const { - return m_functor(m_lhs.coeff(row, col), m_rhs.coeff(row, col)); + return derived().functor()(derived().lhs().coeff(row, col), + derived().rhs().coeff(row, col)); } template<int LoadMode> EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const { - return m_functor.packetOp(m_lhs.template packet<LoadMode>(row, col), m_rhs.template packet<LoadMode>(row, col)); + return derived().functor().packetOp(derived().lhs().template packet<LoadMode>(row, col), + derived().rhs().template packet<LoadMode>(row, col)); } EIGEN_STRONG_INLINE const Scalar coeff(int index) const { - return m_functor(m_lhs.coeff(index), m_rhs.coeff(index)); + return derived().functor()(derived().lhs().coeff(index), + derived().rhs().coeff(index)); } template<int LoadMode> EIGEN_STRONG_INLINE PacketScalar packet(int index) const { - return m_functor.packetOp(m_lhs.template packet<LoadMode>(index), m_rhs.template packet<LoadMode>(index)); + return derived().functor().packetOp(derived().lhs().template packet<LoadMode>(index), + derived().rhs().template packet<LoadMode>(index)); } - - const _LhsNested& lhs() const { return m_lhs; } - const _RhsNested& rhs() const { return m_rhs; } - const BinaryOp& functor() const { return m_functor; } - - protected: - const LhsNested m_lhs; - const RhsNested m_rhs; - const BinaryOp m_functor; }; -/**\returns an expression of the difference of \c *this and \a other - * - * \note If you want to substract a given scalar from all coefficients, see Cwise::operator-(). - * - * \sa class CwiseBinaryOp, MatrixBase::operator-=(), Cwise::operator-() - */ -template<typename Derived> -template<typename OtherDerived> -EIGEN_STRONG_INLINE const CwiseBinaryOp<ei_scalar_difference_op<typename ei_traits<Derived>::Scalar>, - Derived, OtherDerived> -MatrixBase<Derived>::operator-(const MatrixBase<OtherDerived> &other) const -{ - return CwiseBinaryOp<ei_scalar_difference_op<Scalar>, - Derived, OtherDerived>(derived(), other.derived()); -} - /** replaces \c *this by \c *this - \a other. * * \returns a reference to \c *this @@ -172,23 +180,9 @@ template<typename OtherDerived> EIGEN_STRONG_INLINE Derived & MatrixBase<Derived>::operator-=(const MatrixBase<OtherDerived> &other) { - return *this = *this - other; -} - -/** \relates MatrixBase - * - * \returns an expression of the sum of \c *this and \a other - * - * \note If you want to add a given scalar to all coefficients, see Cwise::operator+(). - * - * \sa class CwiseBinaryOp, MatrixBase::operator+=(), Cwise::operator+() - */ -template<typename Derived> -template<typename OtherDerived> -EIGEN_STRONG_INLINE const CwiseBinaryOp<ei_scalar_sum_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived> -MatrixBase<Derived>::operator+(const MatrixBase<OtherDerived> &other) const -{ - return CwiseBinaryOp<ei_scalar_sum_op<Scalar>, Derived, OtherDerived>(derived(), other.derived()); + SelfCwiseBinaryOp<ei_scalar_difference_op<Scalar>, Derived> tmp(derived()); + tmp = other; + return derived(); } /** replaces \c *this by \c *this + \a other. @@ -200,114 +194,9 @@ template<typename OtherDerived> EIGEN_STRONG_INLINE Derived & MatrixBase<Derived>::operator+=(const MatrixBase<OtherDerived>& other) { - return *this = *this + other; -} - -/** \returns an expression of the Schur product (coefficient wise product) of *this and \a other - * - * Example: \include Cwise_product.cpp - * Output: \verbinclude Cwise_product.out - * - * \sa class CwiseBinaryOp, operator/(), square() - */ -template<typename ExpressionType> -template<typename OtherDerived> -EIGEN_STRONG_INLINE const EIGEN_CWISE_PRODUCT_RETURN_TYPE -Cwise<ExpressionType>::operator*(const MatrixBase<OtherDerived> &other) const -{ - return EIGEN_CWISE_PRODUCT_RETURN_TYPE(_expression(), other.derived()); -} - -/** \returns an expression of the coefficient-wise quotient of *this and \a other - * - * Example: \include Cwise_quotient.cpp - * Output: \verbinclude Cwise_quotient.out - * - * \sa class CwiseBinaryOp, operator*(), inverse() - */ -template<typename ExpressionType> -template<typename OtherDerived> -EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op) -Cwise<ExpressionType>::operator/(const MatrixBase<OtherDerived> &other) const -{ - return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)(_expression(), other.derived()); -} - -/** Replaces this expression by its coefficient-wise product with \a other. - * - * Example: \include Cwise_times_equal.cpp - * Output: \verbinclude Cwise_times_equal.out - * - * \sa operator*(), operator/=() - */ -template<typename ExpressionType> -template<typename OtherDerived> -inline ExpressionType& Cwise<ExpressionType>::operator*=(const MatrixBase<OtherDerived> &other) -{ - return m_matrix.const_cast_derived() = *this * other; -} - -/** Replaces this expression by its coefficient-wise quotient by \a other. - * - * Example: \include Cwise_slash_equal.cpp - * Output: \verbinclude Cwise_slash_equal.out - * - * \sa operator/(), operator*=() - */ -template<typename ExpressionType> -template<typename OtherDerived> -inline ExpressionType& Cwise<ExpressionType>::operator/=(const MatrixBase<OtherDerived> &other) -{ - return m_matrix.const_cast_derived() = *this / other; -} - -/** \returns an expression of the coefficient-wise min of *this and \a other - * - * Example: \include Cwise_min.cpp - * Output: \verbinclude Cwise_min.out - * - * \sa class CwiseBinaryOp - */ -template<typename ExpressionType> -template<typename OtherDerived> -EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op) -Cwise<ExpressionType>::min(const MatrixBase<OtherDerived> &other) const -{ - return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op)(_expression(), other.derived()); -} - -/** \returns an expression of the coefficient-wise max of *this and \a other - * - * Example: \include Cwise_max.cpp - * Output: \verbinclude Cwise_max.out - * - * \sa class CwiseBinaryOp - */ -template<typename ExpressionType> -template<typename OtherDerived> -EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op) -Cwise<ExpressionType>::max(const MatrixBase<OtherDerived> &other) const -{ - return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op)(_expression(), 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 - * of the custom operator (see class CwiseBinaryOp for an example) - * - * Here is an example illustrating the use of custom functors: - * \include class_CwiseBinaryOp.cpp - * Output: \verbinclude class_CwiseBinaryOp.out - * - * \sa class CwiseBinaryOp, MatrixBase::operator+, MatrixBase::operator-, Cwise::operator*, Cwise::operator/ - */ -template<typename Derived> -template<typename CustomBinaryOp, typename OtherDerived> -EIGEN_STRONG_INLINE const CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived> -MatrixBase<Derived>::binaryExpr(const MatrixBase<OtherDerived> &other, const CustomBinaryOp& func) const -{ - return CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>(derived(), other.derived(), func); + SelfCwiseBinaryOp<ei_scalar_sum_op<Scalar>, Derived> tmp(derived()); + tmp = other.derived(); + return derived(); } #endif // EIGEN_CWISE_BINARY_OP_H diff --git a/Eigen/src/Core/CwiseNullaryOp.h b/Eigen/src/Core/CwiseNullaryOp.h index 7c1984be6..c326ebae2 100644 --- a/Eigen/src/Core/CwiseNullaryOp.h +++ b/Eigen/src/Core/CwiseNullaryOp.h @@ -38,7 +38,7 @@ * However, if you want to write a function returning such an expression, you * will need to use this class. * - * \sa class CwiseUnaryOp, class CwiseBinaryOp, MatrixBase::NullaryExpr() + * \sa class CwiseUnaryOp, class CwiseBinaryOp, DenseBase::NullaryExpr() */ template<typename NullaryOp, typename MatrixType> struct ei_traits<CwiseNullaryOp<NullaryOp, MatrixType> > : ei_traits<MatrixType> @@ -121,7 +121,7 @@ class CwiseNullaryOp : ei_no_assignment_operator, template<typename Derived> template<typename CustomNullaryOp> EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived> -MatrixBase<Derived>::NullaryExpr(int rows, int cols, const CustomNullaryOp& func) +DenseBase<Derived>::NullaryExpr(int rows, int cols, const CustomNullaryOp& func) { return CwiseNullaryOp<CustomNullaryOp, Derived>(rows, cols, func); } @@ -144,7 +144,7 @@ MatrixBase<Derived>::NullaryExpr(int rows, int cols, const CustomNullaryOp& func template<typename Derived> template<typename CustomNullaryOp> EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived> -MatrixBase<Derived>::NullaryExpr(int size, const CustomNullaryOp& func) +DenseBase<Derived>::NullaryExpr(int size, const CustomNullaryOp& func) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) if(RowsAtCompileTime == 1) return CwiseNullaryOp<CustomNullaryOp, Derived>(1, size, func); @@ -153,7 +153,7 @@ MatrixBase<Derived>::NullaryExpr(int size, const CustomNullaryOp& func) /** \returns an expression of a matrix defined by a custom functor \a func * - * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you + * This variant is only for fixed-size DenseBase types. For dynamic-size types, you * need to use the variants taking size arguments. * * The template parameter \a CustomNullaryOp is the type of the functor. @@ -163,7 +163,7 @@ MatrixBase<Derived>::NullaryExpr(int size, const CustomNullaryOp& func) template<typename Derived> template<typename CustomNullaryOp> EIGEN_STRONG_INLINE const CwiseNullaryOp<CustomNullaryOp, Derived> -MatrixBase<Derived>::NullaryExpr(const CustomNullaryOp& func) +DenseBase<Derived>::NullaryExpr(const CustomNullaryOp& func) { return CwiseNullaryOp<CustomNullaryOp, Derived>(RowsAtCompileTime, ColsAtCompileTime, func); } @@ -171,7 +171,7 @@ MatrixBase<Derived>::NullaryExpr(const CustomNullaryOp& func) /** \returns an expression of a constant matrix of value \a value * * The parameters \a rows and \a cols are the number of rows and of columns of - * the returned matrix. Must be compatible with this MatrixBase type. + * the returned matrix. Must be compatible with this DenseBase type. * * This variant is meant to be used for dynamic-size matrix types. For fixed-size types, * it is redundant to pass \a rows and \a cols as arguments, so Zero() should be used @@ -182,8 +182,8 @@ MatrixBase<Derived>::NullaryExpr(const CustomNullaryOp& func) * \sa class CwiseNullaryOp */ template<typename Derived> -EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType -MatrixBase<Derived>::Constant(int rows, int cols, const Scalar& value) +EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType +DenseBase<Derived>::Constant(int rows, int cols, const Scalar& value) { return NullaryExpr(rows, cols, ei_scalar_constant_op<Scalar>(value)); } @@ -191,7 +191,7 @@ MatrixBase<Derived>::Constant(int rows, int cols, const Scalar& value) /** \returns an expression of a constant matrix of value \a value * * The parameter \a size is the size of the returned vector. - * Must be compatible with this MatrixBase type. + * Must be compatible with this DenseBase type. * * \only_for_vectors * @@ -204,15 +204,15 @@ MatrixBase<Derived>::Constant(int rows, int cols, const Scalar& value) * \sa class CwiseNullaryOp */ template<typename Derived> -EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType -MatrixBase<Derived>::Constant(int size, const Scalar& value) +EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType +DenseBase<Derived>::Constant(int size, const Scalar& value) { return NullaryExpr(size, ei_scalar_constant_op<Scalar>(value)); } /** \returns an expression of a constant matrix of value \a value * - * This variant is only for fixed-size MatrixBase types. For dynamic-size types, you + * This variant is only for fixed-size DenseBase types. For dynamic-size types, you * need to use the variants taking size arguments. * * The template parameter \a CustomNullaryOp is the type of the functor. @@ -220,8 +220,8 @@ MatrixBase<Derived>::Constant(int size, const Scalar& value) * \sa class CwiseNullaryOp */ template<typename Derived> -EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType -MatrixBase<Derived>::Constant(const Scalar& value) +EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType +DenseBase<Derived>::Constant(const Scalar& value) { EIGEN_STATIC_ASSERT_FIXED_SIZE(Derived) return NullaryExpr(RowsAtCompileTime, ColsAtCompileTime, ei_scalar_constant_op<Scalar>(value)); @@ -229,12 +229,12 @@ MatrixBase<Derived>::Constant(const Scalar& value) /** \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */ template<typename Derived> -bool MatrixBase<Derived>::isApproxToConstant +bool DenseBase<Derived>::isApproxToConstant (const Scalar& value, RealScalar prec) const { for(int j = 0; j < cols(); ++j) for(int i = 0; i < rows(); ++i) - if(!ei_isApprox(coeff(i, j), value, prec)) + if(!ei_isApprox(this->coeff(i, j), value, prec)) return false; return true; } @@ -243,7 +243,7 @@ bool MatrixBase<Derived>::isApproxToConstant * * \returns true if all coefficients in this matrix are approximately equal to \a value, to within precision \a prec */ template<typename Derived> -bool MatrixBase<Derived>::isConstant +bool DenseBase<Derived>::isConstant (const Scalar& value, RealScalar prec) const { return isApproxToConstant(value, prec); @@ -254,7 +254,7 @@ bool MatrixBase<Derived>::isConstant * \sa setConstant(), Constant(), class CwiseNullaryOp */ template<typename Derived> -EIGEN_STRONG_INLINE void MatrixBase<Derived>::fill(const Scalar& value) +EIGEN_STRONG_INLINE void DenseBase<Derived>::fill(const Scalar& value) { setConstant(value); } @@ -264,7 +264,7 @@ EIGEN_STRONG_INLINE void MatrixBase<Derived>::fill(const Scalar& value) * \sa fill(), setConstant(int,const Scalar&), setConstant(int,int,const Scalar&), setZero(), setOnes(), Constant(), class CwiseNullaryOp, setZero(), setOnes() */ template<typename Derived> -EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setConstant(const Scalar& value) +EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setConstant(const Scalar& value) { return derived() = Constant(rows(), cols(), value); } @@ -278,9 +278,9 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setConstant(const Scalar& valu * * \sa MatrixBase::setConstant(const Scalar&), setConstant(int,int,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&) */ -template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> -EIGEN_STRONG_INLINE Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& -Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setConstant(int size, const Scalar& value) +template<typename Derived, template<typename> class _Base, int _Options> +EIGEN_STRONG_INLINE Derived& +DenseStorageBase<Derived,_Base,_Options>::setConstant(int size, const Scalar& value) { resize(size); return setConstant(value); @@ -296,9 +296,9 @@ Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setConstant(int siz * * \sa MatrixBase::setConstant(const Scalar&), setConstant(int,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&) */ -template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> -EIGEN_STRONG_INLINE Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& -Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setConstant(int rows, int cols, const Scalar& value) +template<typename Derived, template<typename> class _Base, int _Options> +EIGEN_STRONG_INLINE Derived& +DenseStorageBase<Derived,_Base,_Options>::setConstant(int rows, int cols, const Scalar& value) { resize(rows, cols); return setConstant(value); @@ -322,8 +322,8 @@ Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setConstant(int row * \sa Zero(), Zero(int) */ template<typename Derived> -EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType -MatrixBase<Derived>::Zero(int rows, int cols) +EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType +DenseBase<Derived>::Zero(int rows, int cols) { return Constant(rows, cols, Scalar(0)); } @@ -345,8 +345,8 @@ MatrixBase<Derived>::Zero(int rows, int cols) * \sa Zero(), Zero(int,int) */ template<typename Derived> -EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType -MatrixBase<Derived>::Zero(int size) +EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType +DenseBase<Derived>::Zero(int size) { return Constant(size, Scalar(0)); } @@ -362,8 +362,8 @@ MatrixBase<Derived>::Zero(int size) * \sa Zero(int), Zero(int,int) */ template<typename Derived> -EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType -MatrixBase<Derived>::Zero() +EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType +DenseBase<Derived>::Zero() { return Constant(Scalar(0)); } @@ -377,11 +377,11 @@ MatrixBase<Derived>::Zero() * \sa class CwiseNullaryOp, Zero() */ template<typename Derived> -bool MatrixBase<Derived>::isZero(RealScalar prec) const +bool DenseBase<Derived>::isZero(RealScalar prec) const { for(int j = 0; j < cols(); ++j) for(int i = 0; i < rows(); ++i) - if(!ei_isMuchSmallerThan(coeff(i, j), static_cast<Scalar>(1), prec)) + if(!ei_isMuchSmallerThan(this->coeff(i, j), static_cast<Scalar>(1), prec)) return false; return true; } @@ -394,7 +394,7 @@ bool MatrixBase<Derived>::isZero(RealScalar prec) const * \sa class CwiseNullaryOp, Zero() */ template<typename Derived> -EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setZero() +EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setZero() { return setConstant(Scalar(0)); } @@ -406,11 +406,11 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setZero() * Example: \include Matrix_setZero_int.cpp * Output: \verbinclude Matrix_setZero_int.out * - * \sa MatrixBase::setZero(), setZero(int,int), class CwiseNullaryOp, MatrixBase::Zero() + * \sa DenseBase::setZero(), setZero(int,int), class CwiseNullaryOp, DenseBase::Zero() */ -template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> -EIGEN_STRONG_INLINE Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& -Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setZero(int size) +template<typename Derived, template<typename> class _Base, int _Options> +EIGEN_STRONG_INLINE Derived& +DenseStorageBase<Derived,_Base,_Options>::setZero(int size) { resize(size); return setConstant(Scalar(0)); @@ -424,11 +424,11 @@ Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setZero(int size) * Example: \include Matrix_setZero_int_int.cpp * Output: \verbinclude Matrix_setZero_int_int.out * - * \sa MatrixBase::setZero(), setZero(int), class CwiseNullaryOp, MatrixBase::Zero() + * \sa DenseBase::setZero(), setZero(int), class CwiseNullaryOp, DenseBase::Zero() */ -template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> -EIGEN_STRONG_INLINE Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& -Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setZero(int rows, int cols) +template<typename Derived, template<typename> class _Base, int _Options> +EIGEN_STRONG_INLINE Derived& +DenseStorageBase<Derived,_Base,_Options>::setZero(int rows, int cols) { resize(rows, cols); return setConstant(Scalar(0)); @@ -451,8 +451,8 @@ Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setZero(int rows, i * \sa Ones(), Ones(int), isOnes(), class Ones */ template<typename Derived> -EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType -MatrixBase<Derived>::Ones(int rows, int cols) +EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType +DenseBase<Derived>::Ones(int rows, int cols) { return Constant(rows, cols, Scalar(1)); } @@ -474,8 +474,8 @@ MatrixBase<Derived>::Ones(int rows, int cols) * \sa Ones(), Ones(int,int), isOnes(), class Ones */ template<typename Derived> -EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType -MatrixBase<Derived>::Ones(int size) +EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType +DenseBase<Derived>::Ones(int size) { return Constant(size, Scalar(1)); } @@ -491,8 +491,8 @@ MatrixBase<Derived>::Ones(int size) * \sa Ones(int), Ones(int,int), isOnes(), class Ones */ template<typename Derived> -EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ConstantReturnType -MatrixBase<Derived>::Ones() +EIGEN_STRONG_INLINE const typename DenseBase<Derived>::ConstantReturnType +DenseBase<Derived>::Ones() { return Constant(Scalar(1)); } @@ -506,7 +506,7 @@ MatrixBase<Derived>::Ones() * \sa class CwiseNullaryOp, Ones() */ template<typename Derived> -bool MatrixBase<Derived>::isOnes +bool DenseBase<Derived>::isOnes (RealScalar prec) const { return isApproxToConstant(Scalar(1), prec); @@ -520,7 +520,7 @@ bool MatrixBase<Derived>::isOnes * \sa class CwiseNullaryOp, Ones() */ template<typename Derived> -EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setOnes() +EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setOnes() { return setConstant(Scalar(1)); } @@ -534,9 +534,9 @@ EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>::setOnes() * * \sa MatrixBase::setOnes(), setOnes(int,int), class CwiseNullaryOp, MatrixBase::Ones() */ -template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> -EIGEN_STRONG_INLINE Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& -Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setOnes(int size) +template<typename Derived, template<typename> class _Base, int _Options> +EIGEN_STRONG_INLINE Derived& +DenseStorageBase<Derived,_Base,_Options>::setOnes(int size) { resize(size); return setConstant(Scalar(1)); @@ -552,9 +552,9 @@ Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setOnes(int size) * * \sa MatrixBase::setOnes(), setOnes(int), class CwiseNullaryOp, MatrixBase::Ones() */ -template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> -EIGEN_STRONG_INLINE Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& -Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setOnes(int rows, int cols) +template<typename Derived, template<typename> class _Base, int _Options> +EIGEN_STRONG_INLINE Derived& +DenseStorageBase<Derived,_Base,_Options>::setOnes(int rows, int cols) { resize(rows, cols); return setConstant(Scalar(1)); @@ -620,12 +620,12 @@ bool MatrixBase<Derived>::isIdentity { if(i == j) { - if(!ei_isApprox(coeff(i, j), static_cast<Scalar>(1), prec)) + if(!ei_isApprox(this->coeff(i, j), static_cast<Scalar>(1), prec)) return false; } else { - if(!ei_isMuchSmallerThan(coeff(i, j), static_cast<RealScalar>(1), prec)) + if(!ei_isMuchSmallerThan(this->coeff(i, j), static_cast<RealScalar>(1), prec)) return false; } } @@ -681,7 +681,7 @@ template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int EIGEN_STRONG_INLINE Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>& Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setIdentity(int rows, int cols) { - resize(rows, cols); + Base::resize(rows, cols); return setIdentity(); } diff --git a/Eigen/src/Core/CwiseUnaryOp.h b/Eigen/src/Core/CwiseUnaryOp.h index 03011800c..b4da532e6 100644 --- a/Eigen/src/Core/CwiseUnaryOp.h +++ b/Eigen/src/Core/CwiseUnaryOp.h @@ -56,13 +56,17 @@ struct ei_traits<CwiseUnaryOp<UnaryOp, MatrixType> > }; }; +template<typename UnaryOp, typename MatrixType, typename StorageType> +class CwiseUnaryOpImpl; + template<typename UnaryOp, typename MatrixType> class CwiseUnaryOp : ei_no_assignment_operator, - public MatrixBase<CwiseUnaryOp<UnaryOp, MatrixType> > + public CwiseUnaryOpImpl<UnaryOp, MatrixType, typename ei_traits<MatrixType>::StorageType> { public: - EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryOp) + typedef typename CwiseUnaryOpImpl<UnaryOp, MatrixType,typename ei_traits<MatrixType>::StorageType>::Base Base; + EIGEN_GENERIC_PUBLIC_INTERFACE_NEW(CwiseUnaryOp) inline CwiseUnaryOp(const MatrixType& mat, const UnaryOp& func = UnaryOp()) : m_matrix(mat), m_functor(func) {} @@ -70,28 +74,6 @@ class CwiseUnaryOp : ei_no_assignment_operator, EIGEN_STRONG_INLINE int rows() const { return m_matrix.rows(); } EIGEN_STRONG_INLINE int cols() const { return m_matrix.cols(); } - EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const - { - return m_functor(m_matrix.coeff(row, col)); - } - - template<int LoadMode> - EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const - { - return m_functor.packetOp(m_matrix.template packet<LoadMode>(row, col)); - } - - EIGEN_STRONG_INLINE const Scalar coeff(int index) const - { - return m_functor(m_matrix.coeff(index)); - } - - template<int LoadMode> - EIGEN_STRONG_INLINE PacketScalar packet(int index) const - { - return m_functor.packetOp(m_matrix.template packet<LoadMode>(index)); - } - /** \internal used for introspection */ const UnaryOp& _functor() const { return m_functor; } @@ -99,179 +81,55 @@ class CwiseUnaryOp : ei_no_assignment_operator, const typename ei_cleantype<typename MatrixType::Nested>::type& _expression() const { return m_matrix; } + const typename ei_cleantype<typename MatrixType::Nested>::type& + nestedExpression() const { return m_matrix; } + + typename ei_cleantype<typename MatrixType::Nested>::type& + nestedExpression() { return m_matrix.const_cast_derived(); } + protected: const typename MatrixType::Nested m_matrix; const UnaryOp m_functor; }; -/** \returns an expression of a custom coefficient-wise unary operator \a func of *this - * - * The template parameter \a CustomUnaryOp is the type of the functor - * of the custom unary operator. - * - * Example: - * \include class_CwiseUnaryOp.cpp - * Output: \verbinclude class_CwiseUnaryOp.out - * - * \sa class CwiseUnaryOp, class CwiseBinarOp, MatrixBase::operator-, Cwise::abs - */ -template<typename Derived> -template<typename CustomUnaryOp> -EIGEN_STRONG_INLINE const CwiseUnaryOp<CustomUnaryOp, Derived> -MatrixBase<Derived>::unaryExpr(const CustomUnaryOp& func) const -{ - return CwiseUnaryOp<CustomUnaryOp, Derived>(derived(), func); -} - -/** \returns an expression of the opposite of \c *this - */ -template<typename Derived> -EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_opposite_op<typename ei_traits<Derived>::Scalar>,Derived> -MatrixBase<Derived>::operator-() const -{ - return derived(); -} - -/** \returns an expression of the coefficient-wise absolute value of \c *this - * - * Example: \include Cwise_abs.cpp - * Output: \verbinclude Cwise_abs.out - * - * \sa abs2() - */ -template<typename ExpressionType> -EIGEN_STRONG_INLINE const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs_op) -Cwise<ExpressionType>::abs() const -{ - return _expression(); -} - -/** \returns an expression of the coefficient-wise squared absolute value of \c *this - * - * Example: \include Cwise_abs2.cpp - * Output: \verbinclude Cwise_abs2.out - * - * \sa abs(), square() - */ -template<typename ExpressionType> -EIGEN_STRONG_INLINE const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs2_op) -Cwise<ExpressionType>::abs2() const -{ - return _expression(); -} - -/** \returns an expression of the complex conjugate of \c *this. - * - * \sa adjoint() */ -template<typename Derived> -EIGEN_STRONG_INLINE typename MatrixBase<Derived>::ConjugateReturnType -MatrixBase<Derived>::conjugate() const -{ - return ConjugateReturnType(derived()); -} - -/** \returns a read-only expression of the real part of \c *this. - * - * \sa imag() */ -template<typename Derived> -EIGEN_STRONG_INLINE typename MatrixBase<Derived>::RealReturnType -MatrixBase<Derived>::real() const { return derived(); } - -/** \returns an read-only expression of the imaginary part of \c *this. - * - * \sa real() */ -template<typename Derived> -EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ImagReturnType -MatrixBase<Derived>::imag() const { return derived(); } - -/** \returns an expression of *this with the \a Scalar type casted to - * \a NewScalar. - * - * The template parameter \a NewScalar is the type we are casting the scalars to. - * - * \sa class CwiseUnaryOp - */ -template<typename Derived> -template<typename NewType> -EIGEN_STRONG_INLINE -typename ei_cast_return_type< - Derived, - const CwiseUnaryOp<ei_scalar_cast_op<typename ei_traits<Derived>::Scalar, NewType>, Derived> - >::type -MatrixBase<Derived>::cast() const -{ - return derived(); -} - -/** \returns an expression of the coefficient-wise exponential of *this. - * - * Example: \include Cwise_exp.cpp - * Output: \verbinclude Cwise_exp.out - * - * \sa pow(), log(), sin(), cos() - */ -template<typename ExpressionType> -inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_exp_op) -Cwise<ExpressionType>::exp() const -{ - return _expression(); -} - -/** \returns an expression of the coefficient-wise logarithm of *this. - * - * Example: \include Cwise_log.cpp - * Output: \verbinclude Cwise_log.out - * - * \sa exp() - */ -template<typename ExpressionType> -inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_log_op) -Cwise<ExpressionType>::log() const -{ - return _expression(); -} +// This is the generic implementation for dense storage. +// It can be used for any matrix types implementing the dense concept. +template<typename UnaryOp, typename MatrixType> +class CwiseUnaryOpImpl<UnaryOp,MatrixType,Dense> + : public MatrixType::template MakeBase< CwiseUnaryOp<UnaryOp, MatrixType> >::Type + { + const typename ei_cleantype<typename MatrixType::Nested>::type& matrix() const + { return derived().nestedExpression(); } + typename ei_cleantype<typename MatrixType::Nested>::type& matrix() + { return derived().nestedExpression(); } + public: -/** \returns an expression of \c *this scaled by the scalar factor \a scalar */ -template<typename Derived> -EIGEN_STRONG_INLINE const typename MatrixBase<Derived>::ScalarMultipleReturnType -MatrixBase<Derived>::operator*(const Scalar& scalar) const -{ - return CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, Derived> - (derived(), ei_scalar_multiple_op<Scalar>(scalar)); -} + typedef CwiseUnaryOp<UnaryOp, MatrixType> Derived; + typedef typename MatrixType::template MakeBase< CwiseUnaryOp<UnaryOp, MatrixType> >::Type Base; + _EIGEN_DENSE_PUBLIC_INTERFACE( Derived ) -/** Overloaded for efficient real matrix times complex scalar value */ -template<typename Derived> -EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_multiple2_op<typename ei_traits<Derived>::Scalar, - std::complex<typename ei_traits<Derived>::Scalar> >, Derived> -MatrixBase<Derived>::operator*(const std::complex<Scalar>& scalar) const -{ - return CwiseUnaryOp<ei_scalar_multiple2_op<Scalar,std::complex<Scalar> >, Derived> - (*static_cast<const Derived*>(this), ei_scalar_multiple2_op<Scalar,std::complex<Scalar> >(scalar)); -} + EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const + { + return derived()._functor()(matrix().coeff(row, col)); + } -/** \returns an expression of \c *this divided by the scalar value \a scalar */ -template<typename Derived> -EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived> -MatrixBase<Derived>::operator/(const Scalar& scalar) const -{ - return CwiseUnaryOp<ei_scalar_quotient1_op<Scalar>, Derived> - (derived(), ei_scalar_quotient1_op<Scalar>(scalar)); -} + template<int LoadMode> + EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const + { + return derived()._functor().packetOp(matrix().template packet<LoadMode>(row, col)); + } -template<typename Derived> -EIGEN_STRONG_INLINE Derived& -MatrixBase<Derived>::operator*=(const Scalar& other) -{ - return *this = *this * other; -} + EIGEN_STRONG_INLINE const Scalar coeff(int index) const + { + return derived()._functor()(matrix().coeff(index)); + } -template<typename Derived> -EIGEN_STRONG_INLINE Derived& -MatrixBase<Derived>::operator/=(const Scalar& other) -{ - return *this = *this / other; -} + template<int LoadMode> + EIGEN_STRONG_INLINE PacketScalar packet(int index) const + { + return derived()._functor().packetOp(matrix().template packet<LoadMode>(index)); + } +}; #endif // EIGEN_CWISE_UNARY_OP_H diff --git a/Eigen/src/Core/CwiseUnaryView.h b/Eigen/src/Core/CwiseUnaryView.h index 580344379..b21fa56c6 100644 --- a/Eigen/src/Core/CwiseUnaryView.h +++ b/Eigen/src/Core/CwiseUnaryView.h @@ -52,12 +52,17 @@ struct ei_traits<CwiseUnaryView<ViewOp, MatrixType> > }; }; +template<typename ViewOp, typename MatrixType, typename StorageType> +class CwiseUnaryViewImpl; + template<typename ViewOp, typename MatrixType> -class CwiseUnaryView : public MatrixBase<CwiseUnaryView<ViewOp, MatrixType> > +class CwiseUnaryView : ei_no_assignment_operator, + public CwiseUnaryViewImpl<ViewOp, MatrixType, typename ei_traits<MatrixType>::StorageType> { public: - EIGEN_GENERIC_PUBLIC_INTERFACE(CwiseUnaryView) + typedef typename CwiseUnaryViewImpl<ViewOp, MatrixType,typename ei_traits<MatrixType>::StorageType>::Base Base; + EIGEN_GENERIC_PUBLIC_INTERFACE_NEW(CwiseUnaryView) inline CwiseUnaryView(const MatrixType& mat, const ViewOp& func = ViewOp()) : m_matrix(mat), m_functor(func) {} @@ -67,63 +72,55 @@ class CwiseUnaryView : public MatrixBase<CwiseUnaryView<ViewOp, MatrixType> > EIGEN_STRONG_INLINE int rows() const { return m_matrix.rows(); } EIGEN_STRONG_INLINE int cols() const { return m_matrix.cols(); } + /** \internal used for introspection */ + const ViewOp& _functor() const { return m_functor; } + + const typename ei_cleantype<typename MatrixType::Nested>::type& + nestedExpression() const { return m_matrix; } + + typename ei_cleantype<typename MatrixType::Nested>::type& + nestedExpression() { return m_matrix.const_cast_derived(); } + + protected: + // FIXME changed from MatrixType::Nested because of a weird compilation error with sun CC + const typename ei_nested<MatrixType>::type m_matrix; + const ViewOp m_functor; +}; + +template<typename ViewOp, typename MatrixType> +class CwiseUnaryViewImpl<ViewOp,MatrixType,Dense> : public MatrixBase<CwiseUnaryView<ViewOp, MatrixType> > +{ + const typename ei_cleantype<typename MatrixType::Nested>::type& matrix() const + { return derived().nestedExpression(); } + typename ei_cleantype<typename MatrixType::Nested>::type& matrix() + { return derived().nestedExpression(); } + + public: + + typedef CwiseUnaryView<ViewOp, MatrixType> Derived; + EIGEN_DENSE_PUBLIC_INTERFACE( Derived ) + EIGEN_STRONG_INLINE const Scalar coeff(int row, int col) const { - return m_functor(m_matrix.coeff(row, col)); + return derived()._functor()(matrix().coeff(row, col)); } EIGEN_STRONG_INLINE const Scalar coeff(int index) const { - return m_functor(m_matrix.coeff(index)); + return derived()._functor()(matrix().coeff(index)); } EIGEN_STRONG_INLINE Scalar& coeffRef(int row, int col) { - return m_functor(m_matrix.const_cast_derived().coeffRef(row, col)); + return derived()._functor()(matrix().const_cast_derived().coeffRef(row, col)); } EIGEN_STRONG_INLINE Scalar& coeffRef(int index) { - return m_functor(m_matrix.const_cast_derived().coeffRef(index)); + return derived()._functor()(matrix().const_cast_derived().coeffRef(index)); } - - protected: - // FIXME changed from MatrixType::Nested because of a weird compilation error with sun CC - const typename ei_nested<MatrixType>::type m_matrix; - const ViewOp m_functor; }; -/** \returns an expression of a custom coefficient-wise unary operator \a func of *this - * - * The template parameter \a CustomUnaryOp is the type of the functor - * of the custom unary operator. - * - * Example: - * \include class_CwiseUnaryOp.cpp - * Output: \verbinclude class_CwiseUnaryOp.out - * - * \sa class CwiseUnaryOp, class CwiseBinarOp, MatrixBase::operator-, Cwise::abs - */ -template<typename Derived> -template<typename CustomViewOp> -EIGEN_STRONG_INLINE const CwiseUnaryView<CustomViewOp, Derived> -MatrixBase<Derived>::unaryViewExpr(const CustomViewOp& func) const -{ - return CwiseUnaryView<CustomViewOp, Derived>(derived(), func); -} - -/** \returns a non const expression of the real part of \c *this. - * - * \sa imag() */ -template<typename Derived> -EIGEN_STRONG_INLINE typename MatrixBase<Derived>::NonConstRealReturnType -MatrixBase<Derived>::real() { return derived(); } -/** \returns a non const expression of the imaginary part of \c *this. - * - * \sa real() */ -template<typename Derived> -EIGEN_STRONG_INLINE typename MatrixBase<Derived>::NonConstImagReturnType -MatrixBase<Derived>::imag() { return derived(); } #endif // EIGEN_CWISE_UNARY_VIEW_H diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h new file mode 100644 index 000000000..a7e74b81d --- /dev/null +++ b/Eigen/src/Core/DenseBase.h @@ -0,0 +1,523 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com> +// Copyright (C) 2008-2009 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_DENSEBASE_H +#define EIGEN_DENSEBASE_H + +/** \class DenseBase + * + * \brief Base class for all dense matrices, vectors, and arrays + * + * This class is the base that is inherited by all dense objects (matrix, vector, arrays, and expression + * types). The common Eigen API for dense object is contained in this class. + * + * \param Derived is the derived type, e.g. a matrix type, or an expression, etc. + */ +template<typename Derived> class DenseBase +#ifndef EIGEN_PARSED_BY_DOXYGEN +// : public AnyMatrixBase<Derived> + : public ei_special_scalar_op_base<Derived,typename ei_traits<Derived>::Scalar, + typename NumTraits<typename ei_traits<Derived>::Scalar>::Real> +#endif // not EIGEN_PARSED_BY_DOXYGEN +{ + public: +#ifndef EIGEN_PARSED_BY_DOXYGEN + using ei_special_scalar_op_base<Derived,typename ei_traits<Derived>::Scalar, + typename NumTraits<typename ei_traits<Derived>::Scalar>::Real>::operator*; + + class InnerIterator; + + typedef typename ei_traits<Derived>::Scalar Scalar; + typedef typename ei_packet_traits<Scalar>::type PacketScalar; + + using AnyMatrixBase<Derived>::derived; + using AnyMatrixBase<Derived>::const_cast_derived; +#endif // not EIGEN_PARSED_BY_DOXYGEN + + enum { + + RowsAtCompileTime = ei_traits<Derived>::RowsAtCompileTime, + /**< The number of rows at compile-time. This is just a copy of the value provided + * by the \a Derived type. If a value is not known at compile-time, + * it is set to the \a Dynamic constant. + * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */ + + ColsAtCompileTime = ei_traits<Derived>::ColsAtCompileTime, + /**< The number of columns at compile-time. This is just a copy of the value provided + * by the \a Derived type. If a value is not known at compile-time, + * it is set to the \a Dynamic constant. + * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */ + + + SizeAtCompileTime = (ei_size_at_compile_time<ei_traits<Derived>::RowsAtCompileTime, + ei_traits<Derived>::ColsAtCompileTime>::ret), + /**< 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, + * this value is set to \a Dynamic. + * + * This value is useful to know when evaluating an expression, in order to determine + * whether it is possible to avoid doing a dynamic memory allocation. + * + * \sa RowsAtCompileTime, MaxColsAtCompileTime, MaxSizeAtCompileTime + */ + + MaxColsAtCompileTime = ei_traits<Derived>::MaxColsAtCompileTime, + /**< This value is equal to the maximum possible number of columns that this expression + * might have. If this expression might have an arbitrarily high number of columns, + * this value is set to \a Dynamic. + * + * This value is useful to know when evaluating an expression, in order to determine + * whether it is possible to avoid doing a dynamic memory allocation. + * + * \sa ColsAtCompileTime, MaxRowsAtCompileTime, MaxSizeAtCompileTime + */ + + MaxSizeAtCompileTime = (ei_size_at_compile_time<ei_traits<Derived>::MaxRowsAtCompileTime, + ei_traits<Derived>::MaxColsAtCompileTime>::ret), + /**< This value is equal to the maximum possible number of coefficients that this expression + * might have. If this expression might have an arbitrarily high number of coefficients, + * this value is set to \a Dynamic. + * + * This value is useful to know when evaluating an expression, in order to determine + * whether it is possible to avoid doing a dynamic memory allocation. + * + * \sa SizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime + */ + + IsVectorAtCompileTime = ei_traits<Derived>::RowsAtCompileTime == 1 + || ei_traits<Derived>::ColsAtCompileTime == 1, + /**< This is set to true if either the number of rows or the number of + * columns is known at compile-time to be equal to 1. Indeed, in that case, + * we are dealing with a column-vector (if there is only one column) or with + * a row-vector (if there is only one row). */ + + Flags = ei_traits<Derived>::Flags, + /**< This stores expression \ref flags flags which may or may not be inherited by new expressions + * constructed from this one. See the \ref flags "list of flags". + */ + + CoeffReadCost = ei_traits<Derived>::CoeffReadCost, + /**< This is a rough measure of how expensive it is to read one coefficient from + * this expression. + */ + +#ifndef EIGEN_PARSED_BY_DOXYGEN + _HasDirectAccess = (int(Flags)&DirectAccessBit) ? 1 : 0 // workaround sunCC +#endif + }; + +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** This is the "real scalar" type; if the \a Scalar type is already real numbers + * (e.g. int, float or double) then \a RealScalar is just the same as \a Scalar. If + * \a Scalar is \a std::complex<T> then RealScalar is \a T. + * + * \sa class NumTraits + */ + typedef typename NumTraits<Scalar>::Real RealScalar; +#endif // not EIGEN_PARSED_BY_DOXYGEN + + /** \returns the number of rows. \sa cols(), RowsAtCompileTime */ + inline int rows() const { return derived().rows(); } + /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/ + inline int cols() const { return derived().cols(); } + /** \returns the number of coefficients, which is rows()*cols(). + * \sa rows(), cols(), SizeAtCompileTime. */ + inline int size() const { return rows() * cols(); } + /** \returns the number of nonzero coefficients which is in practice the number + * of stored coefficients. */ + inline int nonZeros() const { return size(); } + /** \returns true if either the number of rows or the number of columns is equal to 1. + * In other words, this function returns + * \code rows()==1 || cols()==1 \endcode + * \sa rows(), cols(), IsVectorAtCompileTime. */ + inline bool isVector() const { return rows()==1 || cols()==1; } + /** \returns the size of the storage major dimension, + * i.e., the number of columns for a columns major matrix, and the number of rows otherwise */ + int outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); } + /** \returns the size of the inner dimension according to the storage order, + * i.e., the number of rows for a columns major matrix, and the number of cols otherwise */ + int innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); } + + /** Only plain matrices, not expressions may be resized; therefore the only useful resize method is + * Matrix::resize(). The present method only asserts that the new size equals the old size, and does + * nothing else. + */ + void resize(int size) + { + ei_assert(size == this->size() + && "MatrixBase::resize() does not actually allow to resize."); + } + /** Only plain matrices, not expressions may be resized; therefore the only useful resize method is + * Matrix::resize(). The present method only asserts that the new size equals the old size, and does + * nothing else. + */ + void resize(int rows, int cols) + { + ei_assert(rows == this->rows() && cols == this->cols() + && "MatrixBase::resize() does not actually allow to resize."); + } + +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** \internal the return type of coeff() + */ + typedef typename ei_meta_if<_HasDirectAccess, const Scalar&, Scalar>::ret CoeffReturnType; + + /** \internal Represents a matrix with all coefficients equal to one another*/ + typedef CwiseNullaryOp<ei_scalar_constant_op<Scalar>,Derived> ConstantReturnType; + /** \internal the return type of MatrixBase::eigenvalues() */ + typedef Matrix<typename NumTraits<typename ei_traits<Derived>::Scalar>::Real, ei_traits<Derived>::ColsAtCompileTime, 1> EigenvaluesReturnType; + /** \internal expression tyepe of a column */ + typedef Block<Derived, ei_traits<Derived>::RowsAtCompileTime, 1> ColXpr; + /** \internal expression tyepe of a column */ + typedef Block<Derived, 1, ei_traits<Derived>::ColsAtCompileTime> RowXpr; +#endif // not EIGEN_PARSED_BY_DOXYGEN + + /** Copies \a other into *this. \returns a reference to *this. */ + template<typename OtherDerived> + Derived& operator=(const DenseBase<OtherDerived>& other); + + /** Special case of the template operator=, in order to prevent the compiler + * from generating a default operator= (issue hit with g++ 4.1) + */ + Derived& operator=(const DenseBase& other); + + template<typename OtherDerived> + Derived& operator=(const AnyMatrixBase<OtherDerived> &other); + + template<typename OtherDerived> + Derived& operator+=(const AnyMatrixBase<OtherDerived> &other); + + template<typename OtherDerived> + Derived& operator-=(const AnyMatrixBase<OtherDerived> &other); + + template<typename OtherDerived> + Derived& operator=(const ReturnByValue<OtherDerived>& func); + +#ifndef EIGEN_PARSED_BY_DOXYGEN + /** Copies \a other into *this without evaluating other. \returns a reference to *this. */ + template<typename OtherDerived> + Derived& lazyAssign(const DenseBase<OtherDerived>& other); +#endif // not EIGEN_PARSED_BY_DOXYGEN + + CommaInitializer<Derived> operator<< (const Scalar& s); + + template<typename OtherDerived> + CommaInitializer<Derived> operator<< (const DenseBase<OtherDerived>& other); + + const CoeffReturnType coeff(int row, int col) const; + const CoeffReturnType operator()(int row, int col) const; + + Scalar& coeffRef(int row, int col); + Scalar& operator()(int row, int col); + + const CoeffReturnType coeff(int index) const; + const CoeffReturnType operator[](int index) const; + const CoeffReturnType operator()(int index) const; + + Scalar& coeffRef(int index); + Scalar& operator[](int index); + Scalar& operator()(int index); + +#ifndef EIGEN_PARSED_BY_DOXYGEN + template<typename OtherDerived> + void copyCoeff(int row, int col, const DenseBase<OtherDerived>& other); + template<typename OtherDerived> + void copyCoeff(int index, const DenseBase<OtherDerived>& other); + template<typename OtherDerived, int StoreMode, int LoadMode> + void copyPacket(int row, int col, const DenseBase<OtherDerived>& other); + template<typename OtherDerived, int StoreMode, int LoadMode> + void copyPacket(int index, const DenseBase<OtherDerived>& other); +#endif // not EIGEN_PARSED_BY_DOXYGEN + + template<int LoadMode> + PacketScalar packet(int row, int col) const; + template<int StoreMode> + void writePacket(int row, int col, const PacketScalar& x); + + template<int LoadMode> + PacketScalar packet(int index) const; + template<int StoreMode> + void writePacket(int index, const PacketScalar& x); + + template<typename OtherDerived> + Derived& operator+=(const DenseBase<OtherDerived>& other); + template<typename OtherDerived> + Derived& operator-=(const DenseBase<OtherDerived>& other); + + Eigen::Transpose<Derived> transpose(); + const Eigen::Transpose<Derived> transpose() const; + void transposeInPlace(); +#ifndef EIGEN_NO_DEBUG + protected: + template<typename OtherDerived> + void checkTransposeAliasing(const OtherDerived& other) const; + public: +#endif + + RowXpr row(int i); + const RowXpr row(int i) const; + + ColXpr col(int i); + const ColXpr col(int i) const; + + typename BlockReturnType<Derived>::Type block(int startRow, int startCol, int blockRows, int blockCols); + const typename BlockReturnType<Derived>::Type + block(int startRow, int startCol, int blockRows, int blockCols) const; + + VectorBlock<Derived> segment(int start, int size); + const VectorBlock<Derived> segment(int start, int size) const; + + VectorBlock<Derived> start(int size); + const VectorBlock<Derived> start(int size) const; + + VectorBlock<Derived> end(int size); + const VectorBlock<Derived> end(int size) const; + + typename BlockReturnType<Derived>::Type corner(CornerType type, int cRows, int cCols); + const typename BlockReturnType<Derived>::Type corner(CornerType type, int cRows, int cCols) const; + + template<int BlockRows, int BlockCols> + typename BlockReturnType<Derived, BlockRows, BlockCols>::Type block(int startRow, int startCol); + template<int BlockRows, int BlockCols> + const typename BlockReturnType<Derived, BlockRows, BlockCols>::Type block(int startRow, int startCol) const; + + template<int CRows, int CCols> + typename BlockReturnType<Derived, CRows, CCols>::Type corner(CornerType type); + template<int CRows, int CCols> + const typename BlockReturnType<Derived, CRows, CCols>::Type corner(CornerType type) const; + + template<int Size> VectorBlock<Derived,Size> start(void); + template<int Size> const VectorBlock<Derived,Size> start() const; + + template<int Size> VectorBlock<Derived,Size> end(); + template<int Size> const VectorBlock<Derived,Size> end() const; + + template<int Size> VectorBlock<Derived,Size> segment(int start); + template<int Size> const VectorBlock<Derived,Size> segment(int start) const; + + Diagonal<Derived,0> diagonal(); + const Diagonal<Derived,0> diagonal() const; + + template<int Index> Diagonal<Derived,Index> diagonal(); + template<int Index> const Diagonal<Derived,Index> diagonal() const; + + Diagonal<Derived, Dynamic> diagonal(int index); + const Diagonal<Derived, Dynamic> diagonal(int index) const; + + template<unsigned int Mode> TriangularView<Derived, Mode> part(); + template<unsigned int Mode> const TriangularView<Derived, Mode> part() const; + + template<unsigned int Mode> TriangularView<Derived, Mode> triangularView(); + template<unsigned int Mode> const TriangularView<Derived, Mode> triangularView() const; + + template<unsigned int UpLo> SelfAdjointView<Derived, UpLo> selfadjointView(); + template<unsigned int UpLo> const SelfAdjointView<Derived, UpLo> selfadjointView() const; + + static const ConstantReturnType + Constant(int rows, int cols, const Scalar& value); + static const ConstantReturnType + Constant(int size, const Scalar& value); + static const ConstantReturnType + Constant(const Scalar& value); + + template<typename CustomNullaryOp> + static const CwiseNullaryOp<CustomNullaryOp, Derived> + NullaryExpr(int rows, int cols, const CustomNullaryOp& func); + template<typename CustomNullaryOp> + static const CwiseNullaryOp<CustomNullaryOp, Derived> + NullaryExpr(int size, const CustomNullaryOp& func); + template<typename CustomNullaryOp> + static const CwiseNullaryOp<CustomNullaryOp, Derived> + NullaryExpr(const CustomNullaryOp& func); + + static const ConstantReturnType Zero(int rows, int cols); + static const ConstantReturnType Zero(int size); + static const ConstantReturnType Zero(); + static const ConstantReturnType Ones(int rows, int cols); + static const ConstantReturnType Ones(int size); + static const ConstantReturnType Ones(); + + void fill(const Scalar& value); + Derived& setConstant(const Scalar& value); + Derived& setZero(); + Derived& setOnes(); + Derived& setRandom(); + + + template<typename OtherDerived> + bool isApprox(const DenseBase<OtherDerived>& other, + RealScalar prec = dummy_precision<Scalar>()) const; + bool isMuchSmallerThan(const RealScalar& other, + RealScalar prec = dummy_precision<Scalar>()) const; + template<typename OtherDerived> + bool isMuchSmallerThan(const DenseBase<OtherDerived>& other, + RealScalar prec = dummy_precision<Scalar>()) const; + + bool isApproxToConstant(const Scalar& value, RealScalar prec = dummy_precision<Scalar>()) const; + bool isConstant(const Scalar& value, RealScalar prec = dummy_precision<Scalar>()) const; + bool isZero(RealScalar prec = dummy_precision<Scalar>()) const; + bool isOnes(RealScalar prec = dummy_precision<Scalar>()) const; + + // FIXME + EIGEN_STRONG_INLINE Derived& operator*=(const Scalar& other) + { + SelfCwiseBinaryOp<ei_scalar_product_op<Scalar>, Derived> tmp(derived()); + typedef typename Derived::PlainMatrixType PlainMatrixType; + tmp = PlainMatrixType::Constant(rows(),cols(),other); + return derived(); + } + EIGEN_STRONG_INLINE Derived& operator/=(const Scalar& other) + { + SelfCwiseBinaryOp<typename ei_meta_if<NumTraits<Scalar>::HasFloatingPoint,ei_scalar_product_op<Scalar>,ei_scalar_quotient_op<Scalar> >::ret, Derived> tmp(derived()); + typedef typename Derived::PlainMatrixType PlainMatrixType; + tmp = PlainMatrixType::Constant(rows(),cols(), NumTraits<Scalar>::HasFloatingPoint ? Scalar(1)/other : other); + return derived(); + } + + // FIXME +// template<typename OtherDerived> +// inline bool operator==(const DenseBase<OtherDerived>& other) const +// { return cwiseEqual(other).all(); } +// +// template<typename OtherDerived> +// inline bool operator!=(const DenseBase<OtherDerived>& other) const +// { return cwiseNotEqual(other).all(); } + + + /** \returns the matrix or vector obtained by evaluating this expression. + * + * Notice that in the case of a plain matrix or vector (not an expression) this function just returns + * a const reference, in order to avoid a useless copy. + */ + EIGEN_STRONG_INLINE const typename ei_eval<Derived>::type eval() const + { return typename ei_eval<Derived>::type(derived()); } + + template<typename OtherDerived> + void swap(DenseBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other); + + /** \returns number of elements to skip to pass from one row (resp. column) to another + * for a row-major (resp. column-major) matrix. + * Combined with coeffRef() and the \ref flags flags, it allows a direct access to the data + * of the underlying matrix. + */ + inline int stride() const { return derived().stride(); } + + inline const NestByValue<Derived> nestByValue() const; + inline const ForceAlignedAccess<Derived> forceAlignedAccess() const; + inline ForceAlignedAccess<Derived> forceAlignedAccess(); + template<bool Enable> inline const typename ei_meta_if<Enable,ForceAlignedAccess<Derived>,Derived&>::ret forceAlignedAccessIf() const; + template<bool Enable> inline typename ei_meta_if<Enable,ForceAlignedAccess<Derived>,Derived&>::ret forceAlignedAccessIf(); + + Scalar sum() const; + Scalar mean() const; + Scalar trace() const; + + Scalar prod() 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) const; + typename ei_traits<Derived>::Scalar maxCoeff(int* row, int* col) const; + + typename ei_traits<Derived>::Scalar minCoeff(int* index) const; + typename ei_traits<Derived>::Scalar maxCoeff(int* index) 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; + + inline const WithFormat<Derived> format(const IOFormat& fmt) const; + +/////////// Array module /////////// + + bool all(void) const; + bool any(void) const; + int count() const; + + const VectorwiseOp<Derived,Horizontal> rowwise() const; + VectorwiseOp<Derived,Horizontal> rowwise(); + const VectorwiseOp<Derived,Vertical> colwise() const; + VectorwiseOp<Derived,Vertical> colwise(); + + static const CwiseNullaryOp<ei_scalar_random_op<Scalar>,Derived> Random(int rows, int cols); + static const CwiseNullaryOp<ei_scalar_random_op<Scalar>,Derived> Random(int size); + static const CwiseNullaryOp<ei_scalar_random_op<Scalar>,Derived> Random(); + + template<typename ThenDerived,typename ElseDerived> + const Select<Derived,ThenDerived,ElseDerived> + select(const DenseBase<ThenDerived>& thenMatrix, + const DenseBase<ElseDerived>& elseMatrix) const; + + template<typename ThenDerived> + inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType> + select(const DenseBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const; + + template<typename ElseDerived> + inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived > + select(typename ElseDerived::Scalar thenScalar, const DenseBase<ElseDerived>& elseMatrix) const; + + template<int p> RealScalar lpNorm() const; + + template<int RowFactor, int ColFactor> + const Replicate<Derived,RowFactor,ColFactor> replicate() const; + const Replicate<Derived,Dynamic,Dynamic> replicate(int rowFacor,int colFactor) const; + + Eigen::Reverse<Derived, BothDirections> reverse(); + const Eigen::Reverse<Derived, BothDirections> reverse() const; + void reverseInPlace(); + + #ifdef EIGEN_DENSEBASE_PLUGIN + #include EIGEN_DENSEBASE_PLUGIN + #endif + + protected: + /** Default constructor. Do nothing. */ + DenseBase() + { + /* Just checks for self-consistency of the flags. + * Only do it when debugging Eigen, as this borders on paranoiac and could slow compilation down + */ +#ifdef EIGEN_INTERNAL_DEBUGGING + EIGEN_STATIC_ASSERT(ei_are_flags_consistent<Flags>::ret, + INVALID_MATRIXBASE_TEMPLATE_PARAMETERS) +#endif + } + + private: + explicit DenseBase(int); + DenseBase(int,int); + template<typename OtherDerived> explicit DenseBase(const DenseBase<OtherDerived>&); +}; + +#endif // EIGEN_DENSEBASE_H diff --git a/Eigen/src/Core/DenseStorageBase.h b/Eigen/src/Core/DenseStorageBase.h new file mode 100644 index 000000000..7dc8d38c4 --- /dev/null +++ b/Eigen/src/Core/DenseStorageBase.h @@ -0,0 +1,601 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr> +// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> +// +// 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_DENSESTORAGEBASE_H +#define EIGEN_DENSESTORAGEBASE_H + +#ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO +# define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=Scalar(0); +#else +# define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED +#endif + +template <typename Derived, typename OtherDerived, bool IsVector = static_cast<bool>(Derived::IsVectorAtCompileTime)> struct ei_conservative_resize_like_impl; +template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> struct ei_matrix_swap_impl; + +template<typename Derived, template<typename> class _Base, int _Options> +class DenseStorageBase : public _Base<Derived> +{ + public: + enum { Options = _Options }; + typedef _Base<Derived> Base; + typedef typename Base::PlainMatrixType PlainMatrixType; + typedef typename Base::Scalar Scalar; + typedef typename Base::PacketScalar PacketScalar; + using Base::RowsAtCompileTime; + using Base::ColsAtCompileTime; + using Base::SizeAtCompileTime; + using Base::MaxRowsAtCompileTime; + using Base::MaxColsAtCompileTime; + using Base::MaxSizeAtCompileTime; + using Base::IsVectorAtCompileTime; + using Base::Flags; + + friend class Eigen::Map<Derived, Unaligned>; + typedef class Eigen::Map<Derived, Unaligned> UnalignedMapType; + friend class Eigen::Map<Derived, Aligned>; + typedef class Eigen::Map<Derived, Aligned> AlignedMapType; + + protected: + ei_matrix_storage<Scalar, MaxSizeAtCompileTime, RowsAtCompileTime, ColsAtCompileTime, Options> m_storage; + + public: + enum { NeedsToAlign = (!(Options&DontAlign)) + && SizeAtCompileTime!=Dynamic && ((sizeof(Scalar)*SizeAtCompileTime)%16)==0 }; + EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) + + Base& base() { return *static_cast<Base*>(this); } + const Base& base() const { return *static_cast<const Base*>(this); } + + EIGEN_STRONG_INLINE int rows() const { return m_storage.rows(); } + EIGEN_STRONG_INLINE int cols() const { return m_storage.cols(); } + + /** Returns the leading dimension (for matrices) or the increment (for vectors) to be used with data(). + * + * More precisely: + * - for a column major matrix it returns the number of elements between two successive columns + * - for a row major matrix it returns the number of elements between two successive rows + * - for a vector it returns the number of elements between two successive coefficients + * This function has to be used together with the MapBase::data() function. + * + * \sa data() */ + EIGEN_STRONG_INLINE int stride() const + { + if(IsVectorAtCompileTime) + return 1; + else + return (Flags & RowMajorBit) ? m_storage.cols() : m_storage.rows(); + } + + EIGEN_STRONG_INLINE const Scalar& coeff(int row, int col) const + { + if(Flags & RowMajorBit) + return m_storage.data()[col + row * m_storage.cols()]; + else // column-major + return m_storage.data()[row + col * m_storage.rows()]; + } + + EIGEN_STRONG_INLINE const Scalar& coeff(int index) const + { + return m_storage.data()[index]; + } + + EIGEN_STRONG_INLINE Scalar& coeffRef(int row, int col) + { + if(Flags & RowMajorBit) + return m_storage.data()[col + row * m_storage.cols()]; + else // column-major + return m_storage.data()[row + col * m_storage.rows()]; + } + + EIGEN_STRONG_INLINE Scalar& coeffRef(int index) + { + return m_storage.data()[index]; + } + + template<int LoadMode> + EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const + { + return ei_ploadt<Scalar, LoadMode> + (m_storage.data() + (Flags & RowMajorBit + ? col + row * m_storage.cols() + : row + col * m_storage.rows())); + } + + template<int LoadMode> + EIGEN_STRONG_INLINE PacketScalar packet(int index) const + { + return ei_ploadt<Scalar, LoadMode>(m_storage.data() + index); + } + + template<int StoreMode> + EIGEN_STRONG_INLINE void writePacket(int row, int col, const PacketScalar& x) + { + ei_pstoret<Scalar, PacketScalar, StoreMode> + (m_storage.data() + (Flags & RowMajorBit + ? col + row * m_storage.cols() + : row + col * m_storage.rows()), x); + } + + template<int StoreMode> + EIGEN_STRONG_INLINE void writePacket(int index, const PacketScalar& x) + { + ei_pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, x); + } + + /** \returns a const pointer to the data array of this matrix */ + EIGEN_STRONG_INLINE const Scalar *data() const + { return m_storage.data(); } + + /** \returns a pointer to the data array of this matrix */ + EIGEN_STRONG_INLINE Scalar *data() + { return m_storage.data(); } + + /** Resizes \c *this to a \a rows x \a cols matrix. + * + * This method is intended for dynamic-size matrices, although it is legal to call it on any + * matrix as long as fixed dimensions are left unchanged. If you only want to change the number + * of rows and/or of columns, you can use resize(NoChange_t, int), resize(int, NoChange_t). + * + * If the current number of coefficients of \c *this exactly matches the + * product \a rows * \a cols, then no memory allocation is performed and + * the current values are left unchanged. In all other cases, including + * shrinking, the data is reallocated and all previous values are lost. + * + * Example: \include Matrix_resize_int_int.cpp + * Output: \verbinclude Matrix_resize_int_int.out + * + * \sa resize(int) for vectors, resize(NoChange_t, int), resize(int, NoChange_t) + */ + inline void resize(int rows, int cols) + { + ei_assert((MaxRowsAtCompileTime == Dynamic || MaxRowsAtCompileTime >= rows) + && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) + && (MaxColsAtCompileTime == Dynamic || MaxColsAtCompileTime >= cols) + && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)); + #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO + int size = rows*cols; + bool size_changed = size != this->size(); + m_storage.resize(size, rows, cols); + if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + #else + m_storage.resize(rows*cols, rows, cols); + #endif + } + + /** Resizes \c *this to a vector of length \a size + * + * \only_for_vectors. This method does not work for + * partially dynamic matrices when the static dimension is anything other + * than 1. For example it will not work with Matrix<double, 2, Dynamic>. + * + * Example: \include Matrix_resize_int.cpp + * Output: \verbinclude Matrix_resize_int.out + * + * \sa resize(int,int), resize(NoChange_t, int), resize(int, NoChange_t) + */ + inline void resize(int size) + { + EIGEN_STATIC_ASSERT_VECTOR_ONLY(DenseStorageBase) + ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size); + #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO + bool size_changed = size != this->size(); + #endif + if(RowsAtCompileTime == 1) + m_storage.resize(size, 1, size); + else + m_storage.resize(size, size, 1); + #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO + if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + #endif + } + + /** Resizes the matrix, changing only the number of columns. For the parameter of type NoChange_t, just pass the special value \c NoChange + * as in the example below. + * + * Example: \include Matrix_resize_NoChange_int.cpp + * Output: \verbinclude Matrix_resize_NoChange_int.out + * + * \sa resize(int,int) + */ + inline void resize(NoChange_t, int cols) + { + resize(rows(), cols); + } + + /** Resizes the matrix, changing only the number of rows. For the parameter of type NoChange_t, just pass the special value \c NoChange + * as in the example below. + * + * Example: \include Matrix_resize_int_NoChange.cpp + * Output: \verbinclude Matrix_resize_int_NoChange.out + * + * \sa resize(int,int) + */ + inline void resize(int rows, NoChange_t) + { + resize(rows, cols()); + } + + /** Resizes \c *this to have the same dimensions as \a other. + * Takes care of doing all the checking that's needed. + * + * Note that copying a row-vector into a vector (and conversely) is allowed. + * The resizing, if any, is then done in the appropriate way so that row-vectors + * remain row-vectors and vectors remain vectors. + */ + template<typename OtherDerived> + EIGEN_STRONG_INLINE void resizeLike(const DenseBase<OtherDerived>& other) + { + if(RowsAtCompileTime == 1) + { + ei_assert(other.isVector()); + resize(1, other.size()); + } + else if(ColsAtCompileTime == 1) + { + ei_assert(other.isVector()); + resize(other.size(), 1); + } + else resize(other.rows(), other.cols()); + } + + /** Resizes \c *this to a \a rows x \a cols matrix while leaving old values of \c *this untouched. + * + * This method is intended for dynamic-size matrices. If you only want to change the number + * of rows and/or of columns, you can use conservativeResize(NoChange_t, int), + * conservativeResize(int, NoChange_t). + * + * The top-left part of the resized matrix will be the same as the overlapping top-left corner + * of \c *this. In case values need to be appended to the matrix they will be uninitialized. + */ + EIGEN_STRONG_INLINE void conservativeResize(int rows, int cols) + { + // FIXME THIS IS VERY BAD !!! + conservativeResizeLike(PlainMatrixType(rows, cols)); + } + + EIGEN_STRONG_INLINE void conservativeResize(int rows, NoChange_t) + { + // Note: see the comment in conservativeResize(int,int) + conservativeResize(rows, cols()); + } + + EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, int cols) + { + // Note: see the comment in conservativeResize(int,int) + conservativeResize(rows(), cols); + } + + /** Resizes \c *this to a vector of length \a size while retaining old values of *this. + * + * \only_for_vectors. This method does not work for + * partially dynamic matrices when the static dimension is anything other + * than 1. For example it will not work with Matrix<double, 2, Dynamic>. + * + * When values are appended, they will be uninitialized. + */ + EIGEN_STRONG_INLINE void conservativeResize(int size) + { + // FIXME THIS IS VERY BAD (unless we mark PlainMatrixType(size) as a temporary to simply swap it)!!! + conservativeResizeLike(PlainMatrixType(size)); + } + + template<typename OtherDerived> + EIGEN_STRONG_INLINE void conservativeResizeLike(const DenseBase<OtherDerived>& other) + { + ei_conservative_resize_like_impl<Derived, OtherDerived>::run(*this, other); + } + + /** This is a special case of the templated operator=. Its purpose is to + * prevent a default operator= from hiding the templated operator=. + */ + EIGEN_STRONG_INLINE Derived& operator=(const DenseStorageBase& other) + { + return _set(other); + } + + /** \sa MatrixBase::lazyAssign() */ + template<typename OtherDerived> + EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other) + { + _resize_to_match(other); + return Base::lazyAssign(other.derived()); + } + + template<typename OtherDerived> + EIGEN_STRONG_INLINE Derived& operator=(const ReturnByValue<OtherDerived>& func) + { + resize(func.rows(), func.cols()); + return Base::operator=(func); + } + + using Base::operator +=; + using Base::operator -=; + using Base::operator *=; + using Base::operator /=; + + EIGEN_STRONG_INLINE explicit DenseStorageBase() : m_storage() + { +// _check_template_params(); +// EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + } + +#ifndef EIGEN_PARSED_BY_DOXYGEN + // FIXME is it still needed ? + /** \internal */ + DenseStorageBase(ei_constructor_without_unaligned_array_assert) + : m_storage(ei_constructor_without_unaligned_array_assert()) + { +// _check_template_params(); EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + } +#endif + + EIGEN_STRONG_INLINE DenseStorageBase(int size, int rows, int cols) + : m_storage(size, rows, cols) + { +// _check_template_params(); +// EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + } + + /** \sa MatrixBase::operator=(const AnyMatrixBase<OtherDerived>&) */ + template<typename OtherDerived> + EIGEN_STRONG_INLINE Derived& operator=(const AnyMatrixBase<OtherDerived> &other) + { + resize(other.derived().rows(), other.derived().cols()); + Base::operator=(other.derived()); + return this->derived(); + } + + /** \sa MatrixBase::operator=(const AnyMatrixBase<OtherDerived>&) */ + template<typename OtherDerived> + EIGEN_STRONG_INLINE DenseStorageBase(const AnyMatrixBase<OtherDerived> &other) + : m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) + { + _check_template_params(); + resize(other.rows(), other.cols()); + *this = other; + } + + /** \name Map + * These are convenience functions returning Map objects. The Map() static functions return unaligned Map objects, + * while the AlignedMap() functions return aligned Map objects and thus should be called only with 16-byte-aligned + * \a data pointers. + * + * \see class Map + */ + //@{ + inline static const UnalignedMapType Map(const Scalar* data) + { return UnalignedMapType(data); } + inline static UnalignedMapType Map(Scalar* data) + { return UnalignedMapType(data); } + inline static const UnalignedMapType Map(const Scalar* data, int size) + { return UnalignedMapType(data, size); } + inline static UnalignedMapType Map(Scalar* data, int size) + { return UnalignedMapType(data, size); } + inline static const UnalignedMapType Map(const Scalar* data, int rows, int cols) + { return UnalignedMapType(data, rows, cols); } + inline static UnalignedMapType Map(Scalar* data, int rows, int cols) + { return UnalignedMapType(data, rows, cols); } + + inline static const AlignedMapType MapAligned(const Scalar* data) + { return AlignedMapType(data); } + inline static AlignedMapType MapAligned(Scalar* data) + { return AlignedMapType(data); } + inline static const AlignedMapType MapAligned(const Scalar* data, int size) + { return AlignedMapType(data, size); } + inline static AlignedMapType MapAligned(Scalar* data, int size) + { return AlignedMapType(data, size); } + inline static const AlignedMapType MapAligned(const Scalar* data, int rows, int cols) + { return AlignedMapType(data, rows, cols); } + inline static AlignedMapType MapAligned(Scalar* data, int rows, int cols) + { return AlignedMapType(data, rows, cols); } + //@} + + using Base::setConstant; + Derived& setConstant(int size, const Scalar& value); + Derived& setConstant(int rows, int cols, const Scalar& value); + + using Base::setZero; + Derived& setZero(int size); + Derived& setZero(int rows, int cols); + + using Base::setOnes; + Derived& setOnes(int size); + Derived& setOnes(int rows, int cols); + + using Base::setRandom; + Derived& setRandom(int size); + Derived& setRandom(int rows, int cols); + + #ifdef EIGEN_DENSESTORAGEBASE_PLUGIN + #include EIGEN_DENSESTORAGEBASE_PLUGIN + #endif + + protected: + /** \internal Resizes *this in preparation for assigning \a other to it. + * Takes care of doing all the checking that's needed. + * + * Note that copying a row-vector into a vector (and conversely) is allowed. + * The resizing, if any, is then done in the appropriate way so that row-vectors + * remain row-vectors and vectors remain vectors. + */ + template<typename OtherDerived> + EIGEN_STRONG_INLINE void _resize_to_match(const DenseBase<OtherDerived>& other) + { + #ifdef EIGEN_NO_AUTOMATIC_RESIZING + ei_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size()) + : (rows() == other.rows() && cols() == other.cols()))) + && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined"); + #endif + resizeLike(other); + } + + /** \internal Copies the value of the expression \a other into \c *this with automatic resizing. + * + * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), + * it will be initialized. + * + * Note that copying a row-vector into a vector (and conversely) is allowed. + * The resizing, if any, is then done in the appropriate way so that row-vectors + * remain row-vectors and vectors remain vectors. + * + * \sa operator=(const MatrixBase<OtherDerived>&), _set_noalias() + */ + template<typename OtherDerived> + EIGEN_STRONG_INLINE Derived& _set(const DenseBase<OtherDerived>& other) + { + _set_selector(other.derived(), typename ei_meta_if<static_cast<bool>(int(OtherDerived::Flags) & EvalBeforeAssigningBit), ei_meta_true, ei_meta_false>::ret()); + return this->derived(); + } + + template<typename OtherDerived> + EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const ei_meta_true&) { _set_noalias(other.eval()); } + + template<typename OtherDerived> + EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const ei_meta_false&) { _set_noalias(other); } + + /** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which + * is the case when creating a new matrix) so one can enforce lazy evaluation. + * + * \sa operator=(const MatrixBase<OtherDerived>&), _set() + */ + template<typename OtherDerived> + EIGEN_STRONG_INLINE Derived& _set_noalias(const DenseBase<OtherDerived>& other) + { + _resize_to_match(other); + // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because + // it wouldn't allow to copy a row-vector into a column-vector. + return ei_assign_selector<Derived,OtherDerived,false>::run(this->derived(), other.derived()); + } + + static EIGEN_STRONG_INLINE void _check_template_params() + { + #ifdef EIGEN_DEBUG_MATRIX_CTOR + EIGEN_DEBUG_MATRIX_CTOR; + #endif + + EIGEN_STATIC_ASSERT(((RowsAtCompileTime >= MaxRowsAtCompileTime) + && (ColsAtCompileTime >= MaxColsAtCompileTime) + && (MaxRowsAtCompileTime >= 0) + && (MaxColsAtCompileTime >= 0) + && (RowsAtCompileTime <= Dynamic) + && (ColsAtCompileTime <= Dynamic) + && (MaxRowsAtCompileTime == RowsAtCompileTime || RowsAtCompileTime==Dynamic) + && (MaxColsAtCompileTime == ColsAtCompileTime || ColsAtCompileTime==Dynamic) + && ((MaxRowsAtCompileTime==Dynamic?1:MaxRowsAtCompileTime)*(MaxColsAtCompileTime==Dynamic?1:MaxColsAtCompileTime)<Dynamic) + && (_Options & (DontAlign|RowMajor)) == _Options), + INVALID_MATRIX_TEMPLATE_PARAMETERS) + } + + + template<typename T0, typename T1> + EIGEN_STRONG_INLINE void _init2(int rows, int cols, typename ei_enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0) + { + ei_assert(rows > 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) + && cols > 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)); + m_storage.resize(rows*cols,rows,cols); + EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + } + template<typename T0, typename T1> + EIGEN_STRONG_INLINE void _init2(const Scalar& x, const Scalar& y, typename ei_enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0) + { + EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(DenseStorageBase, 2) + m_storage.data()[0] = x; + m_storage.data()[1] = y; + } + + template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> + friend struct ei_matrix_swap_impl; + + /** \internal generic implemention of swap for dense storage since for dynamic-sized matrices of same type it is enough to swap the + * data pointers. + */ + template<typename OtherDerived> + void _swap(DenseBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other) + { + enum { SwapPointers = ei_is_same_type<Derived, OtherDerived>::ret && Base::SizeAtCompileTime==Dynamic }; + ei_matrix_swap_impl<Derived, OtherDerived, bool(SwapPointers)>::run(this->derived(), other.const_cast_derived()); + } +}; + + + +template <typename Derived, typename OtherDerived, bool IsVector> +struct ei_conservative_resize_like_impl +{ + static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other) + { + if (_this.rows() == other.rows() && _this.cols() == other.cols()) return; + + // Note: Here is space for improvement. Basically, for conservativeResize(int,int), + // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the + // dimensions is dynamic, one could use either conservativeResize(int rows, NoChange_t) or + // conservativeResize(NoChange_t, int cols). For these methods new static asserts like + // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good. + EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived) + EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived) + + typename Derived::PlainMatrixType tmp(other); + const int common_rows = std::min(tmp.rows(), _this.rows()); + const int common_cols = std::min(tmp.cols(), _this.cols()); + tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols); + _this.derived().swap(tmp); + } +}; + +template <typename Derived, typename OtherDerived> +struct ei_conservative_resize_like_impl<Derived,OtherDerived,true> +{ + static void run(DenseBase<Derived>& _this, const DenseBase<OtherDerived>& other) + { + if (_this.rows() == other.rows() && _this.cols() == other.cols()) return; + + // segment(...) will check whether Derived/OtherDerived are vectors! + typename Derived::PlainMatrixType tmp(other); + const int common_size = std::min<int>(_this.size(),tmp.size()); + tmp.segment(0,common_size) = _this.segment(0,common_size); + _this.derived().swap(tmp); + } +}; + +template<typename MatrixTypeA, typename MatrixTypeB, bool SwapPointers> +struct ei_matrix_swap_impl +{ + static inline void run(MatrixTypeA& a, MatrixTypeB& b) + { + a.base().swap(b); + } +}; + +template<typename MatrixTypeA, typename MatrixTypeB> +struct ei_matrix_swap_impl<MatrixTypeA, MatrixTypeB, true> +{ + static inline void run(MatrixTypeA& a, MatrixTypeB& b) + { + a.m_storage.swap(b.m_storage); + } +}; + +#endif // EIGEN_DENSESTORAGEBASE_H diff --git a/Eigen/src/Core/Diagonal.h b/Eigen/src/Core/Diagonal.h index f2bc8566e..344dbca40 100644 --- a/Eigen/src/Core/Diagonal.h +++ b/Eigen/src/Core/Diagonal.h @@ -44,8 +44,8 @@ */ template<typename MatrixType, int Index> struct ei_traits<Diagonal<MatrixType,Index> > + : ei_traits<MatrixType> { - typedef typename MatrixType::Scalar Scalar; typedef typename ei_nested<MatrixType>::type MatrixTypeNested; typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested; enum { diff --git a/Eigen/src/Core/DiagonalMatrix.h b/Eigen/src/Core/DiagonalMatrix.h index 360f03dd2..bd23b2e09 100644 --- a/Eigen/src/Core/DiagonalMatrix.h +++ b/Eigen/src/Core/DiagonalMatrix.h @@ -67,6 +67,12 @@ class DiagonalBase : public AnyMatrixBase<Derived> template<typename MatrixDerived> const DiagonalProduct<MatrixDerived, Derived, OnTheLeft> operator*(const MatrixBase<MatrixDerived> &matrix) const; + + inline const DiagonalWrapper<NestByValue<CwiseUnaryOp<ei_scalar_inverse_op<Scalar>, DiagonalVectorType> > > + inverse() const + { + return diagonal().cwiseInverse().nestByValue(); + } }; template<typename Derived> diff --git a/Eigen/src/Core/DiagonalProduct.h b/Eigen/src/Core/DiagonalProduct.h index fb3b11bdd..87068d9ba 100644 --- a/Eigen/src/Core/DiagonalProduct.h +++ b/Eigen/src/Core/DiagonalProduct.h @@ -28,6 +28,7 @@ template<typename MatrixType, typename DiagonalType, int ProductOrder> struct ei_traits<DiagonalProduct<MatrixType, DiagonalType, ProductOrder> > + : ei_traits<MatrixType> { typedef typename ei_scalar_product_traits<typename MatrixType::Scalar, typename DiagonalType::Scalar>::ReturnType Scalar; enum { diff --git a/Eigen/src/Core/Dot.h b/Eigen/src/Core/Dot.h index a8983d4ce..f0c520b1f 100644 --- a/Eigen/src/Core/Dot.h +++ b/Eigen/src/Core/Dot.h @@ -279,7 +279,7 @@ MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const template<typename Derived> inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const { - return ei_real((*this).cwise().abs2().sum()); + return ei_real((*this).cwiseAbs2().sum()); } /** \returns the \em l2 norm of *this, i.e., for vectors, the square root of the dot product of *this with itself. diff --git a/Eigen/src/Core/ForceAlignedAccess.h b/Eigen/src/Core/ForceAlignedAccess.h new file mode 100644 index 000000000..b3fbb3c5c --- /dev/null +++ b/Eigen/src/Core/ForceAlignedAccess.h @@ -0,0 +1,151 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 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_FORCEALIGNEDACCESS_H +#define EIGEN_FORCEALIGNEDACCESS_H + +/** \class ForceAlignedAccess + * + * \brief Enforce aligned packet loads and stores regardless of what is requested + * + * \param ExpressionType the type of the object of which we are forcing aligned packet access + * + * This class is the return type of MatrixBase::forceAlignedAccess() + * and most of the time this is the only way it is used. + * + * \sa MatrixBase::forceAlignedAccess() + */ +template<typename ExpressionType> +struct ei_traits<ForceAlignedAccess<ExpressionType> > : public ei_traits<ExpressionType> +{}; + +template<typename ExpressionType> class ForceAlignedAccess + : public MatrixBase<ForceAlignedAccess<ExpressionType> > +{ + public: + + EIGEN_GENERIC_PUBLIC_INTERFACE(ForceAlignedAccess) + + inline ForceAlignedAccess(const ExpressionType& matrix) : m_expression(matrix) {} + + inline int rows() const { return m_expression.rows(); } + inline int cols() const { return m_expression.cols(); } + inline int stride() const { return m_expression.stride(); } + + inline const CoeffReturnType coeff(int row, int col) const + { + return m_expression.coeff(row, col); + } + + inline Scalar& coeffRef(int row, int col) + { + return m_expression.const_cast_derived().coeffRef(row, col); + } + + inline const CoeffReturnType coeff(int index) const + { + return m_expression.coeff(index); + } + + inline Scalar& coeffRef(int index) + { + return m_expression.const_cast_derived().coeffRef(index); + } + + template<int LoadMode> + inline const PacketScalar packet(int row, int col) const + { + return m_expression.template packet<Aligned>(row, col); + } + + template<int LoadMode> + inline void writePacket(int row, int col, const PacketScalar& x) + { + m_expression.const_cast_derived().template writePacket<Aligned>(row, col, x); + } + + template<int LoadMode> + inline const PacketScalar packet(int index) const + { + return m_expression.template packet<Aligned>(index); + } + + template<int LoadMode> + inline void writePacket(int index, const PacketScalar& x) + { + m_expression.const_cast_derived().template writePacket<Aligned>(index, x); + } + + operator const ExpressionType&() const { return m_expression; } + + protected: + const ExpressionType& m_expression; + + private: + ForceAlignedAccess& operator=(const ForceAlignedAccess&); +}; + +/** \returns an expression of *this with forced aligned access + * \sa forceAlignedAccessIf(),class ForceAlignedAccess + */ +template<typename Derived> +inline const ForceAlignedAccess<Derived> +MatrixBase<Derived>::forceAlignedAccess() const +{ + return ForceAlignedAccess<Derived>(derived()); +} + +/** \returns an expression of *this with forced aligned access + * \sa forceAlignedAccessIf(), class ForceAlignedAccess + */ +template<typename Derived> +inline ForceAlignedAccess<Derived> +MatrixBase<Derived>::forceAlignedAccess() +{ + return ForceAlignedAccess<Derived>(derived()); +} + +/** \returns an expression of *this with forced aligned access if \a Enable is true. + * \sa forceAlignedAccess(), class ForceAlignedAccess + */ +template<typename Derived> +template<bool Enable> +inline const typename ei_meta_if<Enable,ForceAlignedAccess<Derived>,Derived&>::ret +MatrixBase<Derived>::forceAlignedAccessIf() const +{ + return derived(); +} + +/** \returns an expression of *this with forced aligned access if \a Enable is true. + * \sa forceAlignedAccess(), class ForceAlignedAccess + */ +template<typename Derived> +template<bool Enable> +inline typename ei_meta_if<Enable,ForceAlignedAccess<Derived>,Derived&>::ret +MatrixBase<Derived>::forceAlignedAccessIf() +{ + return derived(); +} + +#endif // EIGEN_FORCEALIGNEDACCESS_H diff --git a/Eigen/src/Core/Fuzzy.h b/Eigen/src/Core/Fuzzy.h index e10446398..dfa042377 100644 --- a/Eigen/src/Core/Fuzzy.h +++ b/Eigen/src/Core/Fuzzy.h @@ -47,14 +47,17 @@ */ template<typename Derived> template<typename OtherDerived> -bool MatrixBase<Derived>::isApprox( - const MatrixBase<OtherDerived>& other, +bool DenseBase<Derived>::isApprox( + const DenseBase<OtherDerived>& other, RealScalar prec ) const { const typename ei_nested<Derived,2>::type nested(derived()); const typename ei_nested<OtherDerived,2>::type otherNested(other.derived()); - return (nested - otherNested).cwise().abs2().sum() <= prec * prec * std::min(nested.cwise().abs2().sum(), otherNested.cwise().abs2().sum()); +// std::cerr << typeid(Derived).name() << " => " << typeid(typename ei_nested<Derived,2>::type).name() << "\n"; +// std::cerr << typeid(OtherDerived).name() << " => " << typeid(typename ei_nested<OtherDerived,2>::type).name() << "\n"; +// return false; + return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * std::min(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum()); } /** \returns \c true if the norm of \c *this is much smaller than \a other, @@ -68,15 +71,15 @@ bool MatrixBase<Derived>::isApprox( * the value of the reference scalar \a other should come from the Hilbert-Schmidt norm * of a reference matrix of same dimensions. * - * \sa isApprox(), isMuchSmallerThan(const MatrixBase<OtherDerived>&, RealScalar) const + * \sa isApprox(), isMuchSmallerThan(const DenseBase<OtherDerived>&, RealScalar) const */ template<typename Derived> -bool MatrixBase<Derived>::isMuchSmallerThan( +bool DenseBase<Derived>::isMuchSmallerThan( const typename NumTraits<Scalar>::Real& other, RealScalar prec ) const { - return cwise().abs2().sum() <= prec * prec * other * other; + return derived().cwiseAbs2().sum() <= prec * prec * other * other; } /** \returns \c true if the norm of \c *this is much smaller than the norm of \a other, @@ -91,12 +94,12 @@ bool MatrixBase<Derived>::isMuchSmallerThan( */ template<typename Derived> template<typename OtherDerived> -bool MatrixBase<Derived>::isMuchSmallerThan( - const MatrixBase<OtherDerived>& other, +bool DenseBase<Derived>::isMuchSmallerThan( + const DenseBase<OtherDerived>& other, RealScalar prec ) const { - return this->cwise().abs2().sum() <= prec * prec * other.cwise().abs2().sum(); + return derived().cwiseAbs2().sum() <= prec * prec * other.derived().cwiseAbs2().sum(); } #else @@ -122,8 +125,8 @@ struct ei_fuzzy_selector; */ template<typename Derived> template<typename OtherDerived> -bool MatrixBase<Derived>::isApprox( - const MatrixBase<OtherDerived>& other, +bool DenseBase<Derived>::isApprox( + const DenseBase<OtherDerived>& other, RealScalar prec ) const { @@ -138,10 +141,10 @@ bool MatrixBase<Derived>::isApprox( * \f[ \Vert v \Vert \leqslant p\,\vert x\vert. \f] * For matrices, the comparison is done on all columns. * - * \sa isApprox(), isMuchSmallerThan(const MatrixBase<OtherDerived>&, RealScalar) const + * \sa isApprox(), isMuchSmallerThan(const DenseBase<OtherDerived>&, RealScalar) const */ template<typename Derived> -bool MatrixBase<Derived>::isMuchSmallerThan( +bool DenseBase<Derived>::isMuchSmallerThan( const typename NumTraits<Scalar>::Real& other, RealScalar prec ) const @@ -161,8 +164,8 @@ bool MatrixBase<Derived>::isMuchSmallerThan( */ template<typename Derived> template<typename OtherDerived> -bool MatrixBase<Derived>::isMuchSmallerThan( - const MatrixBase<OtherDerived>& other, +bool DenseBase<Derived>::isMuchSmallerThan( + const DenseBase<OtherDerived>& other, RealScalar prec ) const { diff --git a/Eigen/src/Core/GenericPacketMath.h b/Eigen/src/Core/GenericPacketMath.h index 77e5641ff..ae1720eca 100644 --- a/Eigen/src/Core/GenericPacketMath.h +++ b/Eigen/src/Core/GenericPacketMath.h @@ -34,6 +34,22 @@ * of generic vectorized code. */ +#ifndef EIGEN_DEBUG_ALIGNED_LOAD +#define EIGEN_DEBUG_ALIGNED_LOAD +#endif + +#ifndef EIGEN_DEBUG_UNALIGNED_LOAD +#define EIGEN_DEBUG_UNALIGNED_LOAD +#endif + +#ifndef EIGEN_DEBUG_ALIGNED_STORE +#define EIGEN_DEBUG_ALIGNED_STORE +#endif + +#ifndef EIGEN_DEBUG_UNALIGNED_STORE +#define EIGEN_DEBUG_UNALIGNED_STORE +#endif + struct ei_default_packet_traits { enum { @@ -44,13 +60,13 @@ struct ei_default_packet_traits HasAbs = 1, HasMin = 1, HasMax = 1, - + HasDiv = 0, HasSqrt = 0, HasExp = 0, HasLog = 0, HasPow = 0, - + HasSin = 0, HasCos = 0, HasTan = 0, @@ -128,7 +144,7 @@ ei_pxor(const Packet& a, const Packet& b) { return a ^ b; } /** \internal \returns the bitwise andnot of \a a and \a b */ template<typename Packet> inline Packet ei_pandnot(const Packet& a, const Packet& b) { return a & (!b); } - + /** \internal \returns a packet version of \a *from, from must be 16 bytes aligned */ template<typename Scalar> inline typename ei_packet_traits<Scalar>::type ei_pload(const Scalar* from) { return *from; } diff --git a/Eigen/src/Core/IO.h b/Eigen/src/Core/IO.h index a44802ed2..d132064a6 100644 --- a/Eigen/src/Core/IO.h +++ b/Eigen/src/Core/IO.h @@ -52,7 +52,7 @@ enum { StreamPrecision = -1, * Example: \include IOFormat.cpp * Output: \verbinclude IOFormat.out * - * \sa MatrixBase::format(), class WithFormat + * \sa DenseBase::format(), class WithFormat */ struct IOFormat { @@ -86,12 +86,12 @@ struct IOFormat * \param ExpressionType the type of the object on which IO stream operations are performed * * This class represents an expression with stream operators controlled by a given IOFormat. - * It is the return type of MatrixBase::format() + * It is the return type of DenseBase::format() * and most of the time this is the only way it is used. * * See class IOFormat for some examples. * - * \sa MatrixBase::format(), class IOFormat + * \sa DenseBase::format(), class IOFormat */ template<typename ExpressionType> class WithFormat @@ -121,7 +121,7 @@ class WithFormat */ template<typename Derived> inline const WithFormat<Derived> -MatrixBase<Derived>::format(const IOFormat& fmt) const +DenseBase<Derived>::format(const IOFormat& fmt) const { return WithFormat<Derived>(derived(), fmt); } @@ -133,9 +133,9 @@ std::ostream & ei_print_matrix(std::ostream & s, const Derived& _m, const IOForm { const typename Derived::Nested m = _m; typedef typename Derived::Scalar Scalar; - + int width = 0; - + std::streamsize explicit_precision; if(fmt.precision == StreamPrecision) { @@ -151,7 +151,7 @@ std::ostream & ei_print_matrix(std::ostream & s, const Derived& _m, const IOForm { explicit_precision = fmt.precision; } - + bool align_cols = !(fmt.flags & DontAlignCols); if(align_cols) { @@ -190,21 +190,21 @@ std::ostream & ei_print_matrix(std::ostream & s, const Derived& _m, const IOForm return s; } -/** \relates MatrixBase +/** \relates DenseBase * * Outputs the matrix, to the given stream. * - * If you wish to print the matrix with a format different than the default, use MatrixBase::format(). + * If you wish to print the matrix with a format different than the default, use DenseBase::format(). * * It is also possible to change the default format by defining EIGEN_DEFAULT_IO_FORMAT before including Eigen headers. * If not defined, this will automatically be defined to Eigen::IOFormat(), that is the Eigen::IOFormat with default parameters. * - * \sa MatrixBase::format() + * \sa DenseBase::format() */ template<typename Derived> std::ostream & operator << (std::ostream & s, - const MatrixBase<Derived> & m) + const DenseBase<Derived> & m) { return ei_print_matrix(s, m.eval(), EIGEN_DEFAULT_IO_FORMAT); } diff --git a/Eigen/src/Core/Map.h b/Eigen/src/Core/Map.h index dba7e20e4..18fafdece 100644 --- a/Eigen/src/Core/Map.h +++ b/Eigen/src/Core/Map.h @@ -31,8 +31,8 @@ * \brief A matrix or vector expression mapping an existing array of data. * * \param MatrixType the equivalent matrix type of the mapped data - * \param PointerAlignment specifies whether the pointer is \c Aligned, or \c Unaligned. - * The default is \c Unaligned. + * \param Options specifies whether the pointer is \c Aligned, or \c Unaligned. + * The default is \c Unaligned. * * This class represents a matrix or vector expression mapping an existing array of data. * It can be used to let Eigen interface without any overhead with non-Eigen data structures, @@ -46,40 +46,28 @@ * * This class is the return type of Matrix::Map() but can also be used directly. * - * \b Note \b to \b Eigen \b developers: The template parameter \c PointerAlignment - * can also be or-ed with \c EnforceAlignedAccess in order to enforce aligned read - * in expressions such as \code A += B; \endcode. See class MapBase for further details. - * * \sa Matrix::Map() */ template<typename MatrixType, int Options> struct ei_traits<Map<MatrixType, Options> > : public ei_traits<MatrixType> { enum { - PacketAccess = Options & EnforceAlignedAccess, Flags = (Options&Aligned)==Aligned ? ei_traits<MatrixType>::Flags | AlignedBit : ei_traits<MatrixType>::Flags & ~AlignedBit }; - typedef typename ei_meta_if<int(PacketAccess)==EnforceAlignedAccess, - Map<MatrixType, Options>&, - Map<MatrixType, Options|EnforceAlignedAccess> >::ret AlignedDerivedType; }; template<typename MatrixType, int Options> class Map - : public MapBase<Map<MatrixType, Options> > + : public MapBase<Map<MatrixType, Options>, + typename MatrixType::template MakeBase< Map<MatrixType, Options> >::Type> { public: - _EIGEN_GENERIC_PUBLIC_INTERFACE(Map, MapBase<Map>) - typedef typename ei_traits<Map>::AlignedDerivedType AlignedDerivedType; + typedef MapBase<Map,typename MatrixType::template MakeBase<Map>::Type> Base; + _EIGEN_GENERIC_PUBLIC_INTERFACE(Map) inline int stride() const { return this->innerSize(); } - AlignedDerivedType _convertToEnforceAlignedAccess() - { - return AlignedDerivedType(Base::m_data, Base::m_rows.value(), Base::m_cols.value()); - } - inline Map(const Scalar* data) : Base(data) {} inline Map(const Scalar* data, int size) : Base(data, size) {} diff --git a/Eigen/src/Core/MapBase.h b/Eigen/src/Core/MapBase.h index 8770732de..0067fbe16 100644 --- a/Eigen/src/Core/MapBase.h +++ b/Eigen/src/Core/MapBase.h @@ -30,37 +30,21 @@ * * \brief Base class for Map and Block expression with direct access * - * Expression classes inheriting MapBase must define the constant \c PacketAccess, - * and type \c AlignedDerivedType in their respective ei_traits<> specialization structure. - * The value of \c PacketAccess can be either \b AsRequested, or set to \b EnforceAlignedAccess which - * enforces both aligned loads and stores. - * - * \c EnforceAlignedAccess is automatically set in expressions such as - * \code A += B; \endcode where A is either a Block or a Map. Here, - * this expression is transfomed into \code A = A_with_EnforceAlignedAccess + B; \endcode - * avoiding unaligned loads from A. Indeed, since Eigen's packet evaluation mechanism - * automatically align to the destination matrix, we know that loads to A will be aligned too. - * - * The type \c AlignedDerivedType should correspond to the equivalent expression type - * with \c PacketAccess set to \c EnforceAlignedAccess. - * * \sa class Map, class Block */ -template<typename Derived> class MapBase - : public MatrixBase<Derived> +template<typename Derived, typename Base> class MapBase + : public Base { public: - typedef MatrixBase<Derived> Base; +// typedef MatrixBase<Derived> Base; enum { IsRowMajor = (int(ei_traits<Derived>::Flags) & RowMajorBit) ? 1 : 0, - PacketAccess = ei_traits<Derived>::PacketAccess, RowsAtCompileTime = ei_traits<Derived>::RowsAtCompileTime, ColsAtCompileTime = ei_traits<Derived>::ColsAtCompileTime, SizeAtCompileTime = Base::SizeAtCompileTime }; - typedef typename ei_traits<Derived>::AlignedDerivedType AlignedDerivedType; typedef typename ei_traits<Derived>::Scalar Scalar; typedef typename Base::PacketScalar PacketScalar; using Base::derived; @@ -85,21 +69,6 @@ template<typename Derived> class MapBase * \sa MapBase::stride() */ inline const Scalar* data() const { return m_data; } - template<bool IsEnforceAlignedAccess,typename Dummy> struct force_aligned_impl { - static AlignedDerivedType run(MapBase& a) { return a.derived(); } - }; - - template<typename Dummy> struct force_aligned_impl<false,Dummy> { - static AlignedDerivedType run(MapBase& a) { return a.derived()._convertToEnforceAlignedAccess(); } - }; - - /** \returns an expression equivalent to \c *this but having the \c PacketAccess constant - * set to \c EnforceAlignedAccess. Must be reimplemented by the derived class. */ - AlignedDerivedType forceAligned() - { - return force_aligned_impl<int(PacketAccess)==int(EnforceAlignedAccess),Derived>::run(*this); - } - inline const Scalar& coeff(int row, int col) const { if(IsRowMajor) @@ -137,7 +106,7 @@ template<typename Derived> class MapBase template<int LoadMode> inline PacketScalar packet(int row, int col) const { - return ei_ploadt<Scalar, int(PacketAccess) == EnforceAlignedAccess ? Aligned : LoadMode> + return ei_ploadt<Scalar, LoadMode> (m_data + (IsRowMajor ? col + row * stride() : row + col * stride())); } @@ -145,13 +114,13 @@ template<typename Derived> class MapBase template<int LoadMode> inline PacketScalar packet(int index) const { - return ei_ploadt<Scalar, int(PacketAccess) == EnforceAlignedAccess ? Aligned : LoadMode>(m_data + index); + return ei_ploadt<Scalar, LoadMode>(m_data + index); } template<int StoreMode> inline void writePacket(int row, int col, const PacketScalar& x) { - ei_pstoret<Scalar, PacketScalar, int(PacketAccess) == EnforceAlignedAccess ? Aligned : StoreMode> + ei_pstoret<Scalar, PacketScalar, StoreMode> (const_cast<Scalar*>(m_data) + (IsRowMajor ? col + row * stride() : row + col * stride()), x); } @@ -159,7 +128,7 @@ template<typename Derived> class MapBase template<int StoreMode> inline void writePacket(int index, const PacketScalar& x) { - ei_pstoret<Scalar, PacketScalar, int(PacketAccess) == EnforceAlignedAccess ? Aligned : StoreMode> + ei_pstoret<Scalar, PacketScalar, StoreMode> (const_cast<Scalar*>(m_data) + index, x); } @@ -197,32 +166,6 @@ template<typename Derived> class MapBase using Base::operator=; using Base::operator*=; - // FIXME it seems VS does not allow to do "using Base::operator+=" - // and to overload operator+= at the same time, therefore we have to - // explicitly add these two overloads. - // Maybe there exists a better solution though. - template<typename ProductDerived, typename Lhs,typename Rhs> - Derived& operator+=(const Flagged<ProductBase<ProductDerived,Lhs,Rhs>, 0, EvalBeforeAssigningBit>& other) - { return Base::operator+=(other); } - - template<typename ProductDerived, typename Lhs,typename Rhs> - Derived& operator-=(const Flagged<ProductBase<ProductDerived,Lhs,Rhs>, 0, EvalBeforeAssigningBit>& other) - { return Base::operator-=(other); } - - template<typename OtherDerived> - Derived& operator+=(const MatrixBase<OtherDerived>& other) - { return derived() = forceAligned() + other; } - - template<typename OtherDerived> - Derived& operator-=(const MatrixBase<OtherDerived>& other) - { return derived() = forceAligned() - other; } - - Derived& operator*=(const Scalar& other) - { return derived() = forceAligned() * other; } - - Derived& operator/=(const Scalar& other) - { return derived() = forceAligned() / other; } - protected: void checkDataAlignment() const @@ -230,7 +173,7 @@ template<typename Derived> class MapBase ei_assert( ((!(ei_traits<Derived>::Flags&AlignedBit)) || ((std::size_t(m_data)&0xf)==0)) && "data is not aligned"); } - + const Scalar* EIGEN_RESTRICT m_data; const ei_int_if_dynamic<RowsAtCompileTime> m_rows; const ei_int_if_dynamic<ColsAtCompileTime> m_cols; diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h index c2680b71c..24c618549 100644 --- a/Eigen/src/Core/Matrix.h +++ b/Eigen/src/Core/Matrix.h @@ -2,6 +2,7 @@ // for linear algebra. // // Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> +// Copyright (C) 2008-2009 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 @@ -25,14 +26,6 @@ #ifndef EIGEN_MATRIX_H #define EIGEN_MATRIX_H -#ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO -# define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED for(int i=0;i<base().size();++i) coeffRef(i)=Scalar(0); -#else -# define EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED -#endif - -template <typename Derived, typename OtherDerived, bool IsVector = static_cast<bool>(Derived::IsVectorAtCompileTime)> struct ei_conservative_resize_like_impl; - /** \class Matrix * * \brief The matrix class, also used for vectors and row-vectors @@ -118,6 +111,8 @@ template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int struct ei_traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > { typedef _Scalar Scalar; + typedef Dense StorageType; + typedef DenseStorageMatrix DenseStorageType; enum { RowsAtCompileTime = _Rows, ColsAtCompileTime = _Cols, @@ -130,265 +125,32 @@ struct ei_traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> class Matrix - : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > + : public DenseStorageBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, MatrixBase, _Options> { public: - EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix) + + typedef DenseStorageBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, MatrixBase, _Options> Base; + _EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix) enum { Options = _Options }; typedef typename Base::PlainMatrixType PlainMatrixType; - friend class Eigen::Map<Matrix, Unaligned>; - typedef class Eigen::Map<Matrix, Unaligned> UnalignedMapType; - friend class Eigen::Map<Matrix, Aligned>; - typedef class Eigen::Map<Matrix, Aligned> AlignedMapType; +// friend class Eigen::Map<Matrix, Unaligned>; +// typedef class Eigen::Map<Matrix, Unaligned> UnalignedMapType; +// friend class Eigen::Map<Matrix, Aligned>; +// typedef class Eigen::Map<Matrix, Aligned> AlignedMapType; protected: - ei_matrix_storage<Scalar, MaxSizeAtCompileTime, RowsAtCompileTime, ColsAtCompileTime, Options> m_storage; + using Base::m_storage; +// ei_matrix_storage<Scalar, MaxSizeAtCompileTime, RowsAtCompileTime, ColsAtCompileTime, Options> m_storage; public: enum { NeedsToAlign = (!(Options&DontAlign)) && SizeAtCompileTime!=Dynamic && ((sizeof(Scalar)*SizeAtCompileTime)%16)==0 }; EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) - Base& base() { return *static_cast<Base*>(this); } - const Base& base() const { return *static_cast<const Base*>(this); } - - EIGEN_STRONG_INLINE int rows() const { return m_storage.rows(); } - EIGEN_STRONG_INLINE int cols() const { return m_storage.cols(); } - - /** Returns the leading dimension (for matrices) or the increment (for vectors) to be used with data(). - * - * More precisely: - * - for a column major matrix it returns the number of elements between two successive columns - * - for a row major matrix it returns the number of elements between two successive rows - * - for a vector it returns the number of elements between two successive coefficients - * This function has to be used together with the MapBase::data() function. - * - * \sa Matrix::data() */ - EIGEN_STRONG_INLINE int stride() const - { - if(IsVectorAtCompileTime) - return 1; - else - return (Flags & RowMajorBit) ? m_storage.cols() : m_storage.rows(); - } - - EIGEN_STRONG_INLINE const Scalar& coeff(int row, int col) const - { - if(Flags & RowMajorBit) - return m_storage.data()[col + row * m_storage.cols()]; - else // column-major - return m_storage.data()[row + col * m_storage.rows()]; - } - - EIGEN_STRONG_INLINE const Scalar& coeff(int index) const - { - return m_storage.data()[index]; - } - - EIGEN_STRONG_INLINE Scalar& coeffRef(int row, int col) - { - if(Flags & RowMajorBit) - return m_storage.data()[col + row * m_storage.cols()]; - else // column-major - return m_storage.data()[row + col * m_storage.rows()]; - } - - EIGEN_STRONG_INLINE Scalar& coeffRef(int index) - { - return m_storage.data()[index]; - } - - template<int LoadMode> - EIGEN_STRONG_INLINE PacketScalar packet(int row, int col) const - { - return ei_ploadt<Scalar, LoadMode> - (m_storage.data() + (Flags & RowMajorBit - ? col + row * m_storage.cols() - : row + col * m_storage.rows())); - } - - template<int LoadMode> - EIGEN_STRONG_INLINE PacketScalar packet(int index) const - { - return ei_ploadt<Scalar, LoadMode>(m_storage.data() + index); - } - - template<int StoreMode> - EIGEN_STRONG_INLINE void writePacket(int row, int col, const PacketScalar& x) - { - ei_pstoret<Scalar, PacketScalar, StoreMode> - (m_storage.data() + (Flags & RowMajorBit - ? col + row * m_storage.cols() - : row + col * m_storage.rows()), x); - } - - template<int StoreMode> - EIGEN_STRONG_INLINE void writePacket(int index, const PacketScalar& x) - { - ei_pstoret<Scalar, PacketScalar, StoreMode>(m_storage.data() + index, x); - } - - /** \returns a const pointer to the data array of this matrix */ - EIGEN_STRONG_INLINE const Scalar *data() const - { return m_storage.data(); } - - /** \returns a pointer to the data array of this matrix */ - EIGEN_STRONG_INLINE Scalar *data() - { return m_storage.data(); } - - /** Resizes \c *this to a \a rows x \a cols matrix. - * - * This method is intended for dynamic-size matrices, although it is legal to call it on any - * matrix as long as fixed dimensions are left unchanged. If you only want to change the number - * of rows and/or of columns, you can use resize(NoChange_t, int), resize(int, NoChange_t). - * - * If the current number of coefficients of \c *this exactly matches the - * product \a rows * \a cols, then no memory allocation is performed and - * the current values are left unchanged. In all other cases, including - * shrinking, the data is reallocated and all previous values are lost. - * - * Example: \include Matrix_resize_int_int.cpp - * Output: \verbinclude Matrix_resize_int_int.out - * - * \sa resize(int) for vectors, resize(NoChange_t, int), resize(int, NoChange_t) - */ - inline void resize(int rows, int cols) - { - ei_assert((MaxRowsAtCompileTime == Dynamic || MaxRowsAtCompileTime >= rows) - && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) - && (MaxColsAtCompileTime == Dynamic || MaxColsAtCompileTime >= cols) - && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)); - #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO - int size = rows*cols; - bool size_changed = size != this->size(); - m_storage.resize(size, rows, cols); - if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED - #else - m_storage.resize(rows*cols, rows, cols); - #endif - } - - /** Resizes \c *this to a vector of length \a size - * - * \only_for_vectors. This method does not work for - * partially dynamic matrices when the static dimension is anything other - * than 1. For example it will not work with Matrix<double, 2, Dynamic>. - * - * Example: \include Matrix_resize_int.cpp - * Output: \verbinclude Matrix_resize_int.out - * - * \sa resize(int,int), resize(NoChange_t, int), resize(int, NoChange_t) - */ - inline void resize(int size) - { - EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix) - ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size); - #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO - bool size_changed = size != this->size(); - #endif - if(RowsAtCompileTime == 1) - m_storage.resize(size, 1, size); - else - m_storage.resize(size, size, 1); - #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO - if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED - #endif - } - - /** Resizes the matrix, changing only the number of columns. For the parameter of type NoChange_t, just pass the special value \c NoChange - * as in the example below. - * - * Example: \include Matrix_resize_NoChange_int.cpp - * Output: \verbinclude Matrix_resize_NoChange_int.out - * - * \sa resize(int,int) - */ - inline void resize(NoChange_t, int cols) - { - resize(rows(), cols); - } - - /** Resizes the matrix, changing only the number of rows. For the parameter of type NoChange_t, just pass the special value \c NoChange - * as in the example below. - * - * Example: \include Matrix_resize_int_NoChange.cpp - * Output: \verbinclude Matrix_resize_int_NoChange.out - * - * \sa resize(int,int) - */ - inline void resize(int rows, NoChange_t) - { - resize(rows, cols()); - } - - /** Resizes *this to have the same dimensions as \a other. - * Takes care of doing all the checking that's needed. - * - * Note that copying a row-vector into a vector (and conversely) is allowed. - * The resizing, if any, is then done in the appropriate way so that row-vectors - * remain row-vectors and vectors remain vectors. - */ - template<typename OtherDerived> - EIGEN_STRONG_INLINE void resizeLike(const MatrixBase<OtherDerived>& other) - { - if(RowsAtCompileTime == 1) - { - ei_assert(other.isVector()); - resize(1, other.size()); - } - else if(ColsAtCompileTime == 1) - { - ei_assert(other.isVector()); - resize(other.size(), 1); - } - else resize(other.rows(), other.cols()); - } - - /** Resizes \c *this to a \a rows x \a cols matrix while leaving old values of *this untouched. - * - * This method is intended for dynamic-size matrices. If you only want to change the number - * of rows and/or of columns, you can use conservativeResize(NoChange_t, int), - * conservativeResize(int, NoChange_t). - * - * The top-left part of the resized matrix will be the same as the overlapping top-left corner - * of *this. In case values need to be appended to the matrix they will be uninitialized. - */ - EIGEN_STRONG_INLINE void conservativeResize(int rows, int cols) - { - conservativeResizeLike(PlainMatrixType(rows, cols)); - } - - EIGEN_STRONG_INLINE void conservativeResize(int rows, NoChange_t) - { - // Note: see the comment in conservativeResize(int,int) - conservativeResize(rows, cols()); - } - - EIGEN_STRONG_INLINE void conservativeResize(NoChange_t, int cols) - { - // Note: see the comment in conservativeResize(int,int) - conservativeResize(rows(), cols); - } - - /** Resizes \c *this to a vector of length \a size while retaining old values of *this. - * - * \only_for_vectors. This method does not work for - * partially dynamic matrices when the static dimension is anything other - * than 1. For example it will not work with Matrix<double, 2, Dynamic>. - * - * When values are appended, they will be uninitialized. - */ - EIGEN_STRONG_INLINE void conservativeResize(int size) - { - conservativeResizeLike(PlainMatrixType(size)); - } - - template<typename OtherDerived> - EIGEN_STRONG_INLINE void conservativeResizeLike(const MatrixBase<OtherDerived>& other) - { - ei_conservative_resize_like_impl<Matrix, OtherDerived>::run(*this, other); - } + using Base::base; + using Base::coeff; + using Base::coeffRef; /** Copies the value of the expression \a other into \c *this with automatic resizing. * @@ -402,7 +164,7 @@ class Matrix template<typename OtherDerived> EIGEN_STRONG_INLINE Matrix& operator=(const MatrixBase<OtherDerived>& other) { - return _set(other); + return Base::_set(other); } /** This is a special case of the templated operator=. Its purpose is to @@ -410,24 +172,10 @@ class Matrix */ EIGEN_STRONG_INLINE Matrix& operator=(const Matrix& other) { - return _set(other); - } - - /** \sa MatrixBase::lazyAssign() */ - template<typename OtherDerived> - EIGEN_STRONG_INLINE Matrix& lazyAssign(const MatrixBase<OtherDerived>& other) - { - _resize_to_match(other); - return Base::lazyAssign(other.derived()); - } - - template<typename OtherDerived> - EIGEN_STRONG_INLINE Matrix& operator=(const ReturnByValue<OtherDerived>& func) - { - resize(func.rows(), func.cols()); - return Base::operator=(func); + return Base::_set(other); } + using Base::operator =; using Base::operator +=; using Base::operator -=; using Base::operator *=; @@ -443,17 +191,18 @@ class Matrix * * \sa resize(int,int) */ - EIGEN_STRONG_INLINE explicit Matrix() : m_storage() + EIGEN_STRONG_INLINE explicit Matrix() : Base() { - _check_template_params(); + Base::_check_template_params(); EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED } #ifndef EIGEN_PARSED_BY_DOXYGEN + // FIXME is it still needed /** \internal */ Matrix(ei_constructor_without_unaligned_array_assert) - : m_storage(ei_constructor_without_unaligned_array_assert()) - { _check_template_params(); EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED } + : Base(ei_constructor_without_unaligned_array_assert()) + { Base::_check_template_params(); EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED } #endif /** Constructs a vector or row-vector with given dimension. \only_for_vectors @@ -463,9 +212,9 @@ class Matrix * constructor Matrix() instead. */ EIGEN_STRONG_INLINE explicit Matrix(int dim) - : m_storage(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim) + : Base(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim) { - _check_template_params(); + Base::_check_template_params(); EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix) ei_assert(dim > 0); ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim); @@ -476,8 +225,8 @@ class Matrix template<typename T0, typename T1> EIGEN_STRONG_INLINE Matrix(const T0& x, const T1& y) { - _check_template_params(); - _init2<T0,T1>(x, y); + Base::_check_template_params(); + Base::template _init2<T0,T1>(x, y); } #else /** constructs an uninitialized matrix with \a rows rows and \a cols columns. @@ -493,7 +242,7 @@ class Matrix /** constructs an initialized 3D vector with given coefficients */ EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z) { - _check_template_params(); + Base::_check_template_params(); EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 3) m_storage.data()[0] = x; m_storage.data()[1] = y; @@ -502,7 +251,7 @@ class Matrix /** constructs an initialized 4D vector with given coefficients */ EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w) { - _check_template_params(); + Base::_check_template_params(); EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 4) m_storage.data()[0] = x; m_storage.data()[1] = y; @@ -515,43 +264,34 @@ class Matrix /** Constructor copying the value of the expression \a other */ template<typename OtherDerived> EIGEN_STRONG_INLINE Matrix(const MatrixBase<OtherDerived>& other) - : m_storage(other.rows() * other.cols(), other.rows(), other.cols()) + : Base(other.rows() * other.cols(), other.rows(), other.cols()) { - _check_template_params(); - _set_noalias(other); + Base::_check_template_params(); + Base::_set_noalias(other); } /** Copy constructor */ EIGEN_STRONG_INLINE Matrix(const Matrix& other) - : Base(), m_storage(other.rows() * other.cols(), other.rows(), other.cols()) + : Base(other.rows() * other.cols(), other.rows(), other.cols()) { - _check_template_params(); - _set_noalias(other); + Base::_check_template_params(); + Base::_set_noalias(other); } /** Copy constructor with in-place evaluation */ template<typename OtherDerived> EIGEN_STRONG_INLINE Matrix(const ReturnByValue<OtherDerived>& other) { - _check_template_params(); - resize(other.rows(), other.cols()); + Base::_check_template_params(); + Base::resize(other.rows(), other.cols()); other.evalTo(*this); } /** \sa MatrixBase::operator=(const AnyMatrixBase<OtherDerived>&) */ template<typename OtherDerived> - EIGEN_STRONG_INLINE Matrix& operator=(const AnyMatrixBase<OtherDerived> &other) - { - resize(other.derived().rows(), other.derived().cols()); - Base::operator=(other.derived()); - return *this; - } - - /** \sa MatrixBase::operator=(const AnyMatrixBase<OtherDerived>&) */ - template<typename OtherDerived> EIGEN_STRONG_INLINE Matrix(const AnyMatrixBase<OtherDerived> &other) - : m_storage(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) + : Base(other.derived().rows() * other.derived().cols(), other.derived().rows(), other.derived().cols()) { - _check_template_params(); - resize(other.rows(), other.cols()); + Base::_check_template_params(); + Base::resize(other.rows(), other.cols()); *this = other; } @@ -559,58 +299,8 @@ class Matrix * data pointers. */ template<typename OtherDerived> - void swap(MatrixBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other); - - /** \name Map - * These are convenience functions returning Map objects. The Map() static functions return unaligned Map objects, - * while the AlignedMap() functions return aligned Map objects and thus should be called only with 16-byte-aligned - * \a data pointers. - * - * \see class Map - */ - //@{ - inline static const UnalignedMapType Map(const Scalar* data) - { return UnalignedMapType(data); } - inline static UnalignedMapType Map(Scalar* data) - { return UnalignedMapType(data); } - inline static const UnalignedMapType Map(const Scalar* data, int size) - { return UnalignedMapType(data, size); } - inline static UnalignedMapType Map(Scalar* data, int size) - { return UnalignedMapType(data, size); } - inline static const UnalignedMapType Map(const Scalar* data, int rows, int cols) - { return UnalignedMapType(data, rows, cols); } - inline static UnalignedMapType Map(Scalar* data, int rows, int cols) - { return UnalignedMapType(data, rows, cols); } - - inline static const AlignedMapType MapAligned(const Scalar* data) - { return AlignedMapType(data); } - inline static AlignedMapType MapAligned(Scalar* data) - { return AlignedMapType(data); } - inline static const AlignedMapType MapAligned(const Scalar* data, int size) - { return AlignedMapType(data, size); } - inline static AlignedMapType MapAligned(Scalar* data, int size) - { return AlignedMapType(data, size); } - inline static const AlignedMapType MapAligned(const Scalar* data, int rows, int cols) - { return AlignedMapType(data, rows, cols); } - inline static AlignedMapType MapAligned(Scalar* data, int rows, int cols) - { return AlignedMapType(data, rows, cols); } - //@} - - using Base::setConstant; - Matrix& setConstant(int size, const Scalar& value); - Matrix& setConstant(int rows, int cols, const Scalar& value); - - using Base::setZero; - Matrix& setZero(int size); - Matrix& setZero(int rows, int cols); - - using Base::setOnes; - Matrix& setOnes(int size); - Matrix& setOnes(int rows, int cols); - - using Base::setRandom; - Matrix& setRandom(int size); - Matrix& setRandom(int rows, int cols); + void swap(MatrixBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other) + { this->_swap(other.derived()); } using Base::setIdentity; Matrix& setIdentity(int rows, int cols); @@ -626,168 +316,8 @@ class Matrix #ifdef EIGEN_MATRIX_PLUGIN #include EIGEN_MATRIX_PLUGIN #endif - - private: - /** \internal Resizes *this in preparation for assigning \a other to it. - * Takes care of doing all the checking that's needed. - * - * Note that copying a row-vector into a vector (and conversely) is allowed. - * The resizing, if any, is then done in the appropriate way so that row-vectors - * remain row-vectors and vectors remain vectors. - */ - template<typename OtherDerived> - EIGEN_STRONG_INLINE void _resize_to_match(const MatrixBase<OtherDerived>& other) - { - #ifdef EIGEN_NO_AUTOMATIC_RESIZING - ei_assert((this->size()==0 || (IsVectorAtCompileTime ? (this->size() == other.size()) - : (rows() == other.rows() && cols() == other.cols()))) - && "Size mismatch. Automatic resizing is disabled because EIGEN_NO_AUTOMATIC_RESIZING is defined"); - #endif - resizeLike(other); - } - - /** \internal Copies the value of the expression \a other into \c *this with automatic resizing. - * - * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), - * it will be initialized. - * - * Note that copying a row-vector into a vector (and conversely) is allowed. - * The resizing, if any, is then done in the appropriate way so that row-vectors - * remain row-vectors and vectors remain vectors. - * - * \sa operator=(const MatrixBase<OtherDerived>&), _set_noalias() - */ - template<typename OtherDerived> - EIGEN_STRONG_INLINE Matrix& _set(const MatrixBase<OtherDerived>& other) - { - _set_selector(other.derived(), typename ei_meta_if<static_cast<bool>(int(OtherDerived::Flags) & EvalBeforeAssigningBit), ei_meta_true, ei_meta_false>::ret()); - return *this; - } - - template<typename OtherDerived> - EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const ei_meta_true&) { _set_noalias(other.eval()); } - - template<typename OtherDerived> - EIGEN_STRONG_INLINE void _set_selector(const OtherDerived& other, const ei_meta_false&) { _set_noalias(other); } - - /** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which - * is the case when creating a new matrix) so one can enforce lazy evaluation. - * - * \sa operator=(const MatrixBase<OtherDerived>&), _set() - */ - template<typename OtherDerived> - EIGEN_STRONG_INLINE Matrix& _set_noalias(const MatrixBase<OtherDerived>& other) - { - _resize_to_match(other); - // the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because - // it wouldn't allow to copy a row-vector into a column-vector. - return ei_assign_selector<Matrix,OtherDerived,false>::run(*this, other.derived()); - } - - static EIGEN_STRONG_INLINE void _check_template_params() - { - #ifdef EIGEN_DEBUG_MATRIX_CTOR - EIGEN_DEBUG_MATRIX_CTOR(Matrix); - #endif - - EIGEN_STATIC_ASSERT(((_Rows >= _MaxRows) - && (_Cols >= _MaxCols) - && (_MaxRows >= 0) - && (_MaxCols >= 0) - && (_Rows <= Dynamic) - && (_Cols <= Dynamic) - && (_MaxRows == _Rows || _Rows==Dynamic) - && (_MaxCols == _Cols || _Cols==Dynamic) - && ((_MaxRows==Dynamic?1:_MaxRows)*(_MaxCols==Dynamic?1:_MaxCols)<Dynamic) - && (_Options & (DontAlign|RowMajor)) == _Options), - INVALID_MATRIX_TEMPLATE_PARAMETERS) - } - - - template<typename T0, typename T1> - EIGEN_STRONG_INLINE void _init2(int rows, int cols, typename ei_enable_if<Base::SizeAtCompileTime!=2,T0>::type* = 0) - { - ei_assert(rows > 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) - && cols > 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)); - m_storage.resize(rows*cols,rows,cols); - EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED - } - template<typename T0, typename T1> - EIGEN_STRONG_INLINE void _init2(const Scalar& x, const Scalar& y, typename ei_enable_if<Base::SizeAtCompileTime==2,T0>::type* = 0) - { - EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 2) - m_storage.data()[0] = x; - m_storage.data()[1] = y; - } - - template<typename MatrixType, typename OtherDerived, bool SwapPointers> - friend struct ei_matrix_swap_impl; }; -template <typename Derived, typename OtherDerived, bool IsVector> -struct ei_conservative_resize_like_impl -{ - static void run(MatrixBase<Derived>& _this, const MatrixBase<OtherDerived>& other) - { - if (_this.rows() == other.rows() && _this.cols() == other.cols()) return; - - // Note: Here is space for improvement. Basically, for conservativeResize(int,int), - // neither RowsAtCompileTime or ColsAtCompileTime must be Dynamic. If only one of the - // dimensions is dynamic, one could use either conservativeResize(int rows, NoChange_t) or - // conservativeResize(NoChange_t, int cols). For these methods new static asserts like - // EIGEN_STATIC_ASSERT_DYNAMIC_ROWS and EIGEN_STATIC_ASSERT_DYNAMIC_COLS would be good. - EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(Derived) - EIGEN_STATIC_ASSERT_DYNAMIC_SIZE(OtherDerived) - - typename MatrixBase<Derived>::PlainMatrixType tmp(other); - const int common_rows = std::min(tmp.rows(), _this.rows()); - const int common_cols = std::min(tmp.cols(), _this.cols()); - tmp.block(0,0,common_rows,common_cols) = _this.block(0,0,common_rows,common_cols); - _this.derived().swap(tmp); - } -}; - -template <typename Derived, typename OtherDerived> -struct ei_conservative_resize_like_impl<Derived,OtherDerived,true> -{ - static void run(MatrixBase<Derived>& _this, const MatrixBase<OtherDerived>& other) - { - if (_this.rows() == other.rows() && _this.cols() == other.cols()) return; - - // segment(...) will check whether Derived/OtherDerived are vectors! - typename MatrixBase<Derived>::PlainMatrixType tmp(other); - const int common_size = std::min<int>(_this.size(),tmp.size()); - tmp.segment(0,common_size) = _this.segment(0,common_size); - _this.derived().swap(tmp); - } -}; - -template<typename MatrixType, typename OtherDerived, bool SwapPointers> -struct ei_matrix_swap_impl -{ - static inline void run(MatrixType& matrix, MatrixBase<OtherDerived>& other) - { - matrix.base().swap(other); - } -}; - -template<typename MatrixType, typename OtherDerived> -struct ei_matrix_swap_impl<MatrixType, OtherDerived, true> -{ - static inline void run(MatrixType& matrix, MatrixBase<OtherDerived>& other) - { - matrix.m_storage.swap(other.derived().m_storage); - } -}; - -template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> -template<typename OtherDerived> -inline void Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::swap(MatrixBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other) -{ - enum { SwapPointers = ei_is_same_type<Matrix, OtherDerived>::ret && Base::SizeAtCompileTime==Dynamic }; - ei_matrix_swap_impl<Matrix, OtherDerived, bool(SwapPointers)>::run(*this, *const_cast<MatrixBase<OtherDerived>*>(&other)); -} - /** \defgroup matrixtypedefs Global matrix typedefs * * \ingroup Core_Module diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 593108522..f7b32a650 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -28,7 +28,7 @@ /** \class MatrixBase * - * \brief Base class for all matrices, vectors, and expressions + * \brief Base class for all dense matrices, vectors, and expressions * * This class is the base that is inherited by all matrix, vector, and expression * types. Most of the Eigen API is contained in this class. Other important classes for @@ -52,98 +52,53 @@ * \endcode */ template<typename Derived> class MatrixBase -#ifndef EIGEN_PARSED_BY_DOXYGEN - : public ei_special_scalar_op_base<Derived,typename ei_traits<Derived>::Scalar, - typename NumTraits<typename ei_traits<Derived>::Scalar>::Real> -#endif // not EIGEN_PARSED_BY_DOXYGEN + : public DenseBase<Derived> { public: #ifndef EIGEN_PARSED_BY_DOXYGEN - using ei_special_scalar_op_base<Derived,typename ei_traits<Derived>::Scalar, - typename NumTraits<typename ei_traits<Derived>::Scalar>::Real>::operator*; + /** The base class for a given storage type. */ + typedef MatrixBase StorageBaseType; + /** Construct the base class type for the derived class OtherDerived */ + template <typename OtherDerived> struct MakeBase { typedef MatrixBase<OtherDerived> Type; }; + +// using DenseBase<Derived>::operator*; class InnerIterator; typedef typename ei_traits<Derived>::Scalar Scalar; typedef typename ei_packet_traits<Scalar>::type PacketScalar; -#endif // not EIGEN_PARSED_BY_DOXYGEN - enum { + typedef DenseBase<Derived> Base; + + using Base::RowsAtCompileTime; + using Base::ColsAtCompileTime; + using Base::SizeAtCompileTime; + using Base::MaxRowsAtCompileTime; + using Base::MaxColsAtCompileTime; + using Base::MaxSizeAtCompileTime; + using Base::IsVectorAtCompileTime; + using Base::Flags; + using Base::CoeffReadCost; + using Base::_HasDirectAccess; + + using Base::derived; + using Base::const_cast_derived; + using Base::rows; + using Base::cols; + using Base::size; + using Base::coeff; + using Base::coeffRef; + using Base::lazyAssign; + using Base::operator=; + using Base::operator+=; + using Base::operator-=; + using Base::operator*=; + using Base::operator/=; + + typedef typename Base::CoeffReturnType CoeffReturnType; +#endif // not EIGEN_PARSED_BY_DOXYGEN - RowsAtCompileTime = ei_traits<Derived>::RowsAtCompileTime, - /**< The number of rows at compile-time. This is just a copy of the value provided - * by the \a Derived type. If a value is not known at compile-time, - * it is set to the \a Dynamic constant. - * \sa MatrixBase::rows(), MatrixBase::cols(), ColsAtCompileTime, SizeAtCompileTime */ - - ColsAtCompileTime = ei_traits<Derived>::ColsAtCompileTime, - /**< The number of columns at compile-time. This is just a copy of the value provided - * by the \a Derived type. If a value is not known at compile-time, - * it is set to the \a Dynamic constant. - * \sa MatrixBase::rows(), MatrixBase::cols(), RowsAtCompileTime, SizeAtCompileTime */ - - - SizeAtCompileTime = (ei_size_at_compile_time<ei_traits<Derived>::RowsAtCompileTime, - ei_traits<Derived>::ColsAtCompileTime>::ret), - /**< 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, - * this value is set to \a Dynamic. - * - * This value is useful to know when evaluating an expression, in order to determine - * whether it is possible to avoid doing a dynamic memory allocation. - * - * \sa RowsAtCompileTime, MaxColsAtCompileTime, MaxSizeAtCompileTime - */ - - MaxColsAtCompileTime = ei_traits<Derived>::MaxColsAtCompileTime, - /**< This value is equal to the maximum possible number of columns that this expression - * might have. If this expression might have an arbitrarily high number of columns, - * this value is set to \a Dynamic. - * - * This value is useful to know when evaluating an expression, in order to determine - * whether it is possible to avoid doing a dynamic memory allocation. - * - * \sa ColsAtCompileTime, MaxRowsAtCompileTime, MaxSizeAtCompileTime - */ - - MaxSizeAtCompileTime = (ei_size_at_compile_time<ei_traits<Derived>::MaxRowsAtCompileTime, - ei_traits<Derived>::MaxColsAtCompileTime>::ret), - /**< This value is equal to the maximum possible number of coefficients that this expression - * might have. If this expression might have an arbitrarily high number of coefficients, - * this value is set to \a Dynamic. - * - * This value is useful to know when evaluating an expression, in order to determine - * whether it is possible to avoid doing a dynamic memory allocation. - * - * \sa SizeAtCompileTime, MaxRowsAtCompileTime, MaxColsAtCompileTime - */ - - IsVectorAtCompileTime = ei_traits<Derived>::RowsAtCompileTime == 1 - || ei_traits<Derived>::ColsAtCompileTime == 1, - /**< This is set to true if either the number of rows or the number of - * columns is known at compile-time to be equal to 1. Indeed, in that case, - * we are dealing with a column-vector (if there is only one column) or with - * a row-vector (if there is only one row). */ - - Flags = ei_traits<Derived>::Flags, - /**< This stores expression \ref flags flags which may or may not be inherited by new expressions - * constructed from this one. See the \ref flags "list of flags". - */ - - CoeffReadCost = ei_traits<Derived>::CoeffReadCost, - /**< This is a rough measure of how expensive it is to read one coefficient from - * this expression. - */ -#ifndef EIGEN_PARSED_BY_DOXYGEN - _HasDirectAccess = (int(Flags)&DirectAccessBit) ? 1 : 0 // workaround sunCC -#endif - }; #ifndef EIGEN_PARSED_BY_DOXYGEN /** This is the "real scalar" type; if the \a Scalar type is already real numbers @@ -159,49 +114,9 @@ template<typename Derived> class MatrixBase EIGEN_ENUM_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType; #endif // not EIGEN_PARSED_BY_DOXYGEN - /** \returns the number of rows. \sa cols(), RowsAtCompileTime */ - inline int rows() const { return derived().rows(); } - /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/ - inline int cols() const { return derived().cols(); } - /** \returns the number of coefficients, which is rows()*cols(). - * \sa rows(), cols(), SizeAtCompileTime. */ - inline int size() const { return rows() * cols(); } /** \returns the size of the main diagonal, which is min(rows(),cols()). * \sa rows(), cols(), SizeAtCompileTime. */ inline int diagonalSize() const { return std::min(rows(),cols()); } - /** \returns the number of nonzero coefficients which is in practice the number - * of stored coefficients. */ - inline int nonZeros() const { return size(); } - /** \returns true if either the number of rows or the number of columns is equal to 1. - * In other words, this function returns - * \code rows()==1 || cols()==1 \endcode - * \sa rows(), cols(), IsVectorAtCompileTime. */ - inline bool isVector() const { return rows()==1 || cols()==1; } - /** \returns the size of the storage major dimension, - * i.e., the number of columns for a columns major matrix, and the number of rows otherwise */ - int outerSize() const { return (int(Flags)&RowMajorBit) ? this->rows() : this->cols(); } - /** \returns the size of the inner dimension according to the storage order, - * i.e., the number of rows for a columns major matrix, and the number of cols otherwise */ - int innerSize() const { return (int(Flags)&RowMajorBit) ? this->cols() : this->rows(); } - - /** Only plain matrices, not expressions may be resized; therefore the only useful resize method is - * Matrix::resize(). The present method only asserts that the new size equals the old size, and does - * nothing else. - */ - void resize(int size) - { - ei_assert(size == this->size() - && "MatrixBase::resize() does not actually allow to resize."); - } - /** Only plain matrices, not expressions may be resized; therefore the only useful resize method is - * Matrix::resize(). The present method only asserts that the new size equals the old size, and does - * nothing else. - */ - void resize(int rows, int cols) - { - ei_assert(rows == this->rows() && cols == this->cols() - && "MatrixBase::resize() does not actually allow to resize."); - } #ifndef EIGEN_PARSED_BY_DOXYGEN /** \internal the plain matrix type corresponding to this expression. Note that is not necessarily @@ -209,43 +124,24 @@ template<typename Derived> class MatrixBase * reference to a matrix, not a matrix! It is however guaranteed that the return type of eval() is either * PlainMatrixType or const PlainMatrixType&. */ - typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType; +// typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType; + typedef Matrix<typename ei_traits<Derived>::Scalar, + ei_traits<Derived>::RowsAtCompileTime, + ei_traits<Derived>::ColsAtCompileTime, + AutoAlign | (ei_traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor), + ei_traits<Derived>::MaxRowsAtCompileTime, + ei_traits<Derived>::MaxColsAtCompileTime + > PlainMatrixType; /** \internal the column-major plain matrix type corresponding to this expression. Note that is not necessarily * exactly the return type of eval(): in the case of plain matrices, the return type of eval() is a const * reference to a matrix, not a matrix! * The only difference from PlainMatrixType is that PlainMatrixType_ColMajor is guaranteed to be column-major. */ - typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType_ColMajor; +// typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType_ColMajor; - /** \internal the return type of coeff() - */ - typedef typename ei_meta_if<_HasDirectAccess, const Scalar&, Scalar>::ret CoeffReturnType; /** \internal Represents a matrix with all coefficients equal to one another*/ typedef CwiseNullaryOp<ei_scalar_constant_op<Scalar>,Derived> ConstantReturnType; - /** \internal Represents a scalar multiple of a matrix */ - typedef CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, Derived> ScalarMultipleReturnType; - /** \internal Represents a quotient of a matrix by a scalar*/ - typedef CwiseUnaryOp<ei_scalar_quotient1_op<Scalar>, Derived> ScalarQuotient1ReturnType; - /** \internal the return type of MatrixBase::conjugate() */ - typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex, - const CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Derived>, - const Derived& - >::ret ConjugateReturnType; - /** \internal the return type of MatrixBase::real() const */ - typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex, - const CwiseUnaryOp<ei_scalar_real_op<Scalar>, Derived>, - const Derived& - >::ret RealReturnType; - /** \internal the return type of MatrixBase::real() */ - typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex, - CwiseUnaryView<ei_scalar_real_op<Scalar>, Derived>, - Derived& - >::ret NonConstRealReturnType; - /** \internal the return type of MatrixBase::imag() const */ - typedef CwiseUnaryOp<ei_scalar_imag_op<Scalar>, Derived> ImagReturnType; - /** \internal the return type of MatrixBase::imag() */ - typedef CwiseUnaryView<ei_scalar_imag_op<Scalar>, Derived> NonConstImagReturnType; /** \internal the return type of MatrixBase::adjoint() */ typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex, CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<Derived> >, @@ -265,91 +161,26 @@ template<typename Derived> class MatrixBase ei_traits<Derived>::ColsAtCompileTime> BasisReturnType; #endif // not EIGEN_PARSED_BY_DOXYGEN - - /** Copies \a other into *this. \returns a reference to *this. */ - template<typename OtherDerived> - Derived& operator=(const MatrixBase<OtherDerived>& other); +#define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::MatrixBase +# include "../plugins/CommonCwiseUnaryOps.h" +# include "../plugins/CommonCwiseBinaryOps.h" +# include "../plugins/MatrixCwiseUnaryOps.h" +# include "../plugins/MatrixCwiseBinaryOps.h" +# ifdef EIGEN_MATRIXBASE_PLUGIN +# include EIGEN_MATRIXBASE_PLUGIN +# endif +#undef EIGEN_CURRENT_STORAGE_BASE_CLASS /** Special case of the template operator=, in order to prevent the compiler * from generating a default operator= (issue hit with g++ 4.1) */ Derived& operator=(const MatrixBase& other); - template<typename OtherDerived> - Derived& operator=(const AnyMatrixBase<OtherDerived> &other); - - template<typename OtherDerived> - Derived& operator+=(const AnyMatrixBase<OtherDerived> &other); - - template<typename OtherDerived> - Derived& operator-=(const AnyMatrixBase<OtherDerived> &other); - - template<typename OtherDerived> - Derived& operator=(const ReturnByValue<OtherDerived>& func); - #ifndef EIGEN_PARSED_BY_DOXYGEN - /** Copies \a other into *this without evaluating other. \returns a reference to *this. */ - template<typename OtherDerived> - Derived& lazyAssign(const MatrixBase<OtherDerived>& other); - - /** \deprecated because .lazy() is deprecated - * Overloaded for cache friendly product evaluation */ - template<typename OtherDerived> - Derived& lazyAssign(const Flagged<OtherDerived, 0, EvalBeforeAssigningBit>& other) - { return lazyAssign(other._expression()); } - template<typename ProductDerived, typename Lhs, typename Rhs> Derived& lazyAssign(const ProductBase<ProductDerived, Lhs,Rhs>& other); - - template<typename ProductDerived, typename Lhs, typename Rhs> - Derived& operator+=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0, - EvalBeforeAssigningBit>& other); - - template<typename ProductDerived, typename Lhs, typename Rhs> - Derived& operator-=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0, - EvalBeforeAssigningBit>& other); -#endif // not EIGEN_PARSED_BY_DOXYGEN - - CommaInitializer<Derived> operator<< (const Scalar& s); - - template<typename OtherDerived> - CommaInitializer<Derived> operator<< (const MatrixBase<OtherDerived>& other); - - const CoeffReturnType coeff(int row, int col) const; - const CoeffReturnType operator()(int row, int col) const; - - Scalar& coeffRef(int row, int col); - Scalar& operator()(int row, int col); - - const CoeffReturnType coeff(int index) const; - const CoeffReturnType operator[](int index) const; - const CoeffReturnType operator()(int index) const; - - Scalar& coeffRef(int index); - Scalar& operator[](int index); - Scalar& operator()(int index); - -#ifndef EIGEN_PARSED_BY_DOXYGEN - template<typename OtherDerived> - void copyCoeff(int row, int col, const MatrixBase<OtherDerived>& other); - template<typename OtherDerived> - void copyCoeff(int index, const MatrixBase<OtherDerived>& other); - template<typename OtherDerived, int StoreMode, int LoadMode> - void copyPacket(int row, int col, const MatrixBase<OtherDerived>& other); - template<typename OtherDerived, int StoreMode, int LoadMode> - void copyPacket(int index, const MatrixBase<OtherDerived>& other); #endif // not EIGEN_PARSED_BY_DOXYGEN - template<int LoadMode> - PacketScalar packet(int row, int col) const; - template<int StoreMode> - void writePacket(int row, int col, const PacketScalar& x); - - template<int LoadMode> - PacketScalar packet(int index) const; - template<int StoreMode> - void writePacket(int index, const PacketScalar& x); - const CoeffReturnType x() const; const CoeffReturnType y() const; const CoeffReturnType z() const; @@ -359,43 +190,11 @@ template<typename Derived> class MatrixBase Scalar& z(); Scalar& w(); - - const CwiseUnaryOp<ei_scalar_opposite_op<typename ei_traits<Derived>::Scalar>,Derived> operator-() const; - - template<typename OtherDerived> - const CwiseBinaryOp<ei_scalar_sum_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived> - operator+(const MatrixBase<OtherDerived> &other) const; - - template<typename OtherDerived> - const CwiseBinaryOp<ei_scalar_difference_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived> - operator-(const MatrixBase<OtherDerived> &other) const; - template<typename OtherDerived> Derived& operator+=(const MatrixBase<OtherDerived>& other); template<typename OtherDerived> Derived& operator-=(const MatrixBase<OtherDerived>& other); - Derived& operator*=(const Scalar& other); - Derived& operator/=(const Scalar& other); - - const ScalarMultipleReturnType operator*(const Scalar& scalar) const; - #ifdef EIGEN_PARSED_BY_DOXYGEN - const ScalarMultipleReturnType operator*(const RealScalar& scalar) const; - #endif - const CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived> - operator/(const Scalar& scalar) const; - - const CwiseUnaryOp<ei_scalar_multiple2_op<Scalar,std::complex<Scalar> >, Derived> - operator*(const std::complex<Scalar>& scalar) const; - - inline friend const ScalarMultipleReturnType - operator*(const Scalar& scalar, const MatrixBase& matrix) - { return matrix*scalar; } - - inline friend const CwiseUnaryOp<ei_scalar_multiple2_op<Scalar,std::complex<Scalar> >, Derived> - operator*(const std::complex<Scalar>& scalar, const MatrixBase& matrix) - { return matrix*scalar; } - template<typename OtherDerived> const typename ProductReturnType<Derived,OtherDerived>::Type operator*(const MatrixBase<OtherDerived> &other) const; @@ -414,14 +213,6 @@ template<typename Derived> class MatrixBase operator*(const DiagonalBase<DiagonalDerived> &diagonal) const; template<typename OtherDerived> - typename ei_plain_matrix_type_column_major<OtherDerived>::type - solveTriangular(const MatrixBase<OtherDerived>& other) const; - - template<typename OtherDerived> - void solveTriangularInPlace(const MatrixBase<OtherDerived>& other) const; - - - template<typename OtherDerived> Scalar dot(const MatrixBase<OtherDerived>& other) const; RealScalar squaredNorm() const; RealScalar norm() const; @@ -431,62 +222,12 @@ template<typename Derived> class MatrixBase const PlainMatrixType normalized() const; void normalize(); - Eigen::Transpose<Derived> transpose(); - const Eigen::Transpose<Derived> transpose() const; - void transposeInPlace(); const AdjointReturnType adjoint() const; void adjointInPlace(); -#ifndef EIGEN_NO_DEBUG - protected: - template<typename OtherDerived> - void checkTransposeAliasing(const OtherDerived& other) const; - public: -#endif - - RowXpr row(int i); - const RowXpr row(int i) const; - - ColXpr col(int i); - const ColXpr col(int i) const; Minor<Derived> minor(int row, int col); const Minor<Derived> minor(int row, int col) const; - typename BlockReturnType<Derived>::Type block(int startRow, int startCol, int blockRows, int blockCols); - const typename BlockReturnType<Derived>::Type - block(int startRow, int startCol, int blockRows, int blockCols) const; - - VectorBlock<Derived> segment(int start, int size); - const VectorBlock<Derived> segment(int start, int size) const; - - VectorBlock<Derived> start(int size); - const VectorBlock<Derived> start(int size) const; - - VectorBlock<Derived> end(int size); - const VectorBlock<Derived> end(int size) const; - - typename BlockReturnType<Derived>::Type corner(CornerType type, int cRows, int cCols); - const typename BlockReturnType<Derived>::Type corner(CornerType type, int cRows, int cCols) const; - - template<int BlockRows, int BlockCols> - typename BlockReturnType<Derived, BlockRows, BlockCols>::Type block(int startRow, int startCol); - template<int BlockRows, int BlockCols> - const typename BlockReturnType<Derived, BlockRows, BlockCols>::Type block(int startRow, int startCol) const; - - template<int CRows, int CCols> - typename BlockReturnType<Derived, CRows, CCols>::Type corner(CornerType type); - template<int CRows, int CCols> - const typename BlockReturnType<Derived, CRows, CCols>::Type corner(CornerType type) const; - - template<int Size> VectorBlock<Derived,Size> start(void); - template<int Size> const VectorBlock<Derived,Size> start() const; - - template<int Size> VectorBlock<Derived,Size> end(); - template<int Size> const VectorBlock<Derived,Size> end() const; - - template<int Size> VectorBlock<Derived,Size> segment(int start); - template<int Size> const VectorBlock<Derived,Size> segment(int start) const; - Diagonal<Derived,0> diagonal(); const Diagonal<Derived,0> diagonal() const; @@ -505,29 +246,6 @@ template<typename Derived> class MatrixBase template<unsigned int UpLo> SelfAdjointView<Derived, UpLo> selfadjointView(); template<unsigned int UpLo> const SelfAdjointView<Derived, UpLo> selfadjointView() const; - static const ConstantReturnType - Constant(int rows, int cols, const Scalar& value); - static const ConstantReturnType - Constant(int size, const Scalar& value); - static const ConstantReturnType - Constant(const Scalar& value); - - template<typename CustomNullaryOp> - static const CwiseNullaryOp<CustomNullaryOp, Derived> - NullaryExpr(int rows, int cols, const CustomNullaryOp& func); - template<typename CustomNullaryOp> - static const CwiseNullaryOp<CustomNullaryOp, Derived> - NullaryExpr(int size, const CustomNullaryOp& func); - template<typename CustomNullaryOp> - static const CwiseNullaryOp<CustomNullaryOp, Derived> - NullaryExpr(const CustomNullaryOp& func); - - static const ConstantReturnType Zero(int rows, int cols); - static const ConstantReturnType Zero(int size); - static const ConstantReturnType Zero(); - static const ConstantReturnType Ones(int rows, int cols); - static const ConstantReturnType Ones(int size); - static const ConstantReturnType Ones(); static const IdentityReturnType Identity(); static const IdentityReturnType Identity(int rows, int cols); static const BasisReturnType Unit(int size, int i); @@ -539,27 +257,8 @@ template<typename Derived> class MatrixBase const DiagonalWrapper<Derived> asDiagonal() const; - void fill(const Scalar& value); - Derived& setConstant(const Scalar& value); - Derived& setZero(); - Derived& setOnes(); - Derived& setRandom(); Derived& setIdentity(); - - template<typename OtherDerived> - bool isApprox(const MatrixBase<OtherDerived>& other, - RealScalar prec = dummy_precision<Scalar>()) const; - bool isMuchSmallerThan(const RealScalar& other, - RealScalar prec = dummy_precision<Scalar>()) const; - template<typename OtherDerived> - bool isMuchSmallerThan(const MatrixBase<OtherDerived>& other, - RealScalar prec = dummy_precision<Scalar>()) const; - - bool isApproxToConstant(const Scalar& value, RealScalar prec = dummy_precision<Scalar>()) const; - bool isConstant(const Scalar& value, RealScalar prec = dummy_precision<Scalar>()) const; - bool isZero(RealScalar prec = dummy_precision<Scalar>()) const; - bool isOnes(RealScalar prec = dummy_precision<Scalar>()) const; bool isIdentity(RealScalar prec = dummy_precision<Scalar>()) const; bool isDiagonal(RealScalar prec = dummy_precision<Scalar>()) const; @@ -571,21 +270,22 @@ template<typename Derived> class MatrixBase RealScalar prec = dummy_precision<Scalar>()) const; bool isUnitary(RealScalar prec = dummy_precision<Scalar>()) const; + /** \returns true if each coefficients of \c *this and \a other are all exactly equal. + * \warning When using floating point scalar values you probably should rather use a + * fuzzy comparison such as isApprox() + * \sa isApprox(), operator!= */ template<typename OtherDerived> inline bool operator==(const MatrixBase<OtherDerived>& other) const - { return (cwise() == other).all(); } + { return cwiseEqual(other).all(); } + /** \returns true if at least one pair of coefficients of \c *this and \a other are not exactly equal to each other. + * \warning When using floating point scalar values you probably should rather use a + * fuzzy comparison such as isApprox() + * \sa isApprox(), operator== */ template<typename OtherDerived> inline bool operator!=(const MatrixBase<OtherDerived>& other) const - { return (cwise() != other).any(); } - + { return cwiseNotEqual(other).all(); } - template<typename NewType> - typename ei_cast_return_type< - Derived, - const CwiseUnaryOp<ei_scalar_cast_op<typename ei_traits<Derived>::Scalar, NewType>, Derived> - >::type - cast() const; /** \returns the matrix or vector obtained by evaluating this expression. * @@ -598,108 +298,28 @@ template<typename Derived> class MatrixBase template<typename OtherDerived> void swap(MatrixBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other); - template<unsigned int Added> - const Flagged<Derived, Added, 0> marked() const; - const Flagged<Derived, 0, EvalBeforeAssigningBit> lazy() const; - - NoAlias<Derived> noalias(); - - /** \returns number of elements to skip to pass from one row (resp. column) to another - * for a row-major (resp. column-major) matrix. - * Combined with coeffRef() and the \ref flags flags, it allows a direct access to the data - * of the underlying matrix. - */ - inline int stride(void) const { return derived().stride(); } + NoAlias<Derived,Eigen::MatrixBase > noalias(); inline const NestByValue<Derived> nestByValue() const; + inline const ForceAlignedAccess<Derived> forceAlignedAccess() const; + inline ForceAlignedAccess<Derived> forceAlignedAccess(); + template<bool Enable> inline const typename ei_meta_if<Enable,ForceAlignedAccess<Derived>,Derived&>::ret forceAlignedAccessIf() const; + template<bool Enable> inline typename ei_meta_if<Enable,ForceAlignedAccess<Derived>,Derived&>::ret forceAlignedAccessIf(); - ConjugateReturnType conjugate() const; - RealReturnType real() const; - NonConstRealReturnType real(); - const ImagReturnType imag() const; - NonConstImagReturnType imag(); - - template<typename CustomUnaryOp> - const CwiseUnaryOp<CustomUnaryOp, Derived> unaryExpr(const CustomUnaryOp& func = CustomUnaryOp()) const; - - template<typename CustomViewOp> - const CwiseUnaryView<CustomViewOp, Derived> unaryViewExpr(const CustomViewOp& func = CustomViewOp()) const; - - template<typename CustomBinaryOp, typename OtherDerived> - const CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived> - binaryExpr(const MatrixBase<OtherDerived> &other, const CustomBinaryOp& func = CustomBinaryOp()) const; - - - Scalar sum() const; Scalar mean() const; Scalar trace() const; - Scalar prod() 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) const; - typename ei_traits<Derived>::Scalar maxCoeff(int* row, int* col) const; - - typename ei_traits<Derived>::Scalar minCoeff(int* index) const; - typename ei_traits<Derived>::Scalar maxCoeff(int* index) 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; - -#ifndef EIGEN_PARSED_BY_DOXYGEN - using AnyMatrixBase<Derived>::derived; - inline Derived& const_cast_derived() const - { return *static_cast<Derived*>(const_cast<MatrixBase*>(this)); } -#endif // not EIGEN_PARSED_BY_DOXYGEN - - const Cwise<Derived> cwise() const; - Cwise<Derived> cwise(); - - inline const WithFormat<Derived> format(const IOFormat& fmt) const; - /////////// Array module /////////// - bool all(void) const; - bool any(void) const; - int count() const; - const VectorwiseOp<Derived,Horizontal> rowwise() const; VectorwiseOp<Derived,Horizontal> rowwise(); const VectorwiseOp<Derived,Vertical> colwise() const; VectorwiseOp<Derived,Vertical> colwise(); - static const CwiseNullaryOp<ei_scalar_random_op<Scalar>,Derived> Random(int rows, int cols); - static const CwiseNullaryOp<ei_scalar_random_op<Scalar>,Derived> Random(int size); - static const CwiseNullaryOp<ei_scalar_random_op<Scalar>,Derived> Random(); - - template<typename ThenDerived,typename ElseDerived> - const Select<Derived,ThenDerived,ElseDerived> - select(const MatrixBase<ThenDerived>& thenMatrix, - const MatrixBase<ElseDerived>& elseMatrix) const; - - template<typename ThenDerived> - inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType> - select(const MatrixBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const; - - template<typename ElseDerived> - inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived > - select(typename ElseDerived::Scalar thenScalar, const MatrixBase<ElseDerived>& elseMatrix) const; - template<int p> RealScalar lpNorm() const; - template<int RowFactor, int ColFactor> - const Replicate<Derived,RowFactor,ColFactor> replicate() const; - const Replicate<Derived,Dynamic,Dynamic> replicate(int rowFacor,int colFactor) const; - - Eigen::Reverse<Derived, BothDirections> reverse(); - const Eigen::Reverse<Derived, BothDirections> reverse() const; - void reverseInPlace(); + ArrayWrapper<Derived> array() { return derived(); } + const ArrayWrapper<Derived> array() const { return derived(); } /////////// LU module /////////// @@ -762,15 +382,6 @@ template<typename Derived> class MatrixBase typedef Homogeneous<Derived,MatrixBase<Derived>::ColsAtCompileTime==1?Vertical:Horizontal> HomogeneousReturnType; const HomogeneousReturnType homogeneous() const; -/////////// Sparse module /////////// - - // dense = sparse * dense - template<typename Derived1, typename Derived2> - Derived& lazyAssign(const SparseProduct<Derived1,Derived2,SparseTimeDenseProduct>& product); - // dense = dense * sparse - template<typename Derived1, typename Derived2> - Derived& lazyAssign(const SparseProduct<Derived1,Derived2,DenseTimeSparseProduct>& product); - ////////// Householder module /////////// void makeHouseholderInPlace(Scalar& tau, RealScalar& beta); @@ -793,9 +404,35 @@ template<typename Derived> class MatrixBase template<typename OtherScalar> void applyOnTheRight(int p, int q, const PlanarRotation<OtherScalar>& j); - #ifdef EIGEN_MATRIXBASE_PLUGIN - #include EIGEN_MATRIXBASE_PLUGIN - #endif +#ifdef EIGEN2_SUPPORT + template<typename ProductDerived, typename Lhs, typename Rhs> + Derived& operator+=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0, + EvalBeforeAssigningBit>& other); + + template<typename ProductDerived, typename Lhs, typename Rhs> + Derived& operator-=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0, + EvalBeforeAssigningBit>& other); + + /** \deprecated because .lazy() is deprecated + * Overloaded for cache friendly product evaluation */ + template<typename OtherDerived> + Derived& lazyAssign(const Flagged<OtherDerived, 0, EvalBeforeAssigningBit>& other) + { return lazyAssign(other._expression()); } + + template<unsigned int Added> + const Flagged<Derived, Added, 0> marked() const; + const Flagged<Derived, 0, EvalBeforeAssigningBit> lazy() const; + + inline const Cwise<Derived> cwise() const; + inline Cwise<Derived> cwise(); + + template<typename OtherDerived> + typename ei_plain_matrix_type_column_major<OtherDerived>::type + solveTriangular(const MatrixBase<OtherDerived>& other) const; + + template<typename OtherDerived> + void solveTriangularInPlace(const MatrixBase<OtherDerived>& other) const; +#endif protected: /** Default constructor. Do nothing. */ diff --git a/Eigen/src/Core/Minor.h b/Eigen/src/Core/Minor.h index eb44f3760..629dbe609 100644 --- a/Eigen/src/Core/Minor.h +++ b/Eigen/src/Core/Minor.h @@ -25,7 +25,7 @@ #ifndef EIGEN_MINOR_H #define EIGEN_MINOR_H -/** \nonstableyet +/** \nonstableyet * \class Minor * * \brief Expression of a minor @@ -40,8 +40,8 @@ */ template<typename MatrixType> struct ei_traits<Minor<MatrixType> > + : ei_traits<MatrixType> { - typedef typename MatrixType::Scalar Scalar; typedef typename ei_nested<MatrixType>::type MatrixTypeNested; typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested; enum { @@ -94,7 +94,7 @@ template<typename MatrixType> class Minor const int m_row, m_col; }; -/** \nonstableyet +/** \nonstableyet * \return an expression of the (\a row, \a col)-minor of *this, * i.e. an expression constructed from *this by removing the specified * row and column. @@ -111,7 +111,7 @@ MatrixBase<Derived>::minor(int row, int col) return Minor<Derived>(derived(), row, col); } -/** \nonstableyet +/** \nonstableyet * This is the const version of minor(). */ template<typename Derived> inline const Minor<Derived> diff --git a/Eigen/src/Core/NoAlias.h b/Eigen/src/Core/NoAlias.h index 66d8d834d..bfea5c91d 100644 --- a/Eigen/src/Core/NoAlias.h +++ b/Eigen/src/Core/NoAlias.h @@ -39,7 +39,7 @@ * * \sa MatrixBase::noalias() */ -template<typename ExpressionType> +template<typename ExpressionType, template <typename> class StorageBase> class NoAlias { public: @@ -48,17 +48,17 @@ class NoAlias /** Behaves like MatrixBase::lazyAssign(other) * \sa MatrixBase::lazyAssign() */ template<typename OtherDerived> - EIGEN_STRONG_INLINE ExpressionType& operator=(const MatrixBase<OtherDerived>& other) + EIGEN_STRONG_INLINE ExpressionType& operator=(const StorageBase<OtherDerived>& other) { return m_expression.lazyAssign(other.derived()); } /** \sa MatrixBase::operator+= */ template<typename OtherDerived> - EIGEN_STRONG_INLINE ExpressionType& operator+=(const MatrixBase<OtherDerived>& other) + EIGEN_STRONG_INLINE ExpressionType& operator+=(const StorageBase<OtherDerived>& other) { return m_expression.lazyAssign(m_expression + other.derived()); } /** \sa MatrixBase::operator-= */ template<typename OtherDerived> - EIGEN_STRONG_INLINE ExpressionType& operator-=(const MatrixBase<OtherDerived>& other) + EIGEN_STRONG_INLINE ExpressionType& operator-=(const StorageBase<OtherDerived>& other) { return m_expression.lazyAssign(m_expression - other.derived()); } #ifndef EIGEN_PARSED_BY_DOXYGEN @@ -77,12 +77,12 @@ class NoAlias /** \returns a pseudo expression of \c *this with an operator= assuming * no aliasing between \c *this and the source expression. - * + * * More precisely, noalias() allows to bypass the EvalBeforeAssignBit flag. * Currently, even though several expressions may alias, only product * expressions have this flag. Therefore, noalias() is only usefull when * the source expression contains a matrix product. - * + * * Here are some examples where noalias is usefull: * \code * D.noalias() = A * B; @@ -104,7 +104,7 @@ class NoAlias * \sa class NoAlias */ template<typename Derived> -NoAlias<Derived> MatrixBase<Derived>::noalias() +NoAlias<Derived,MatrixBase> MatrixBase<Derived>::noalias() { return derived(); } diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index 7066e5743..15f44de89 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -172,7 +172,7 @@ class GeneralProduct<Lhs, Rhs, InnerProduct> EIGEN_STRONG_INLINE Scalar value() const { - return (m_lhs.transpose().cwise()*m_rhs).sum(); + return (m_lhs.transpose().cwiseProduct(m_rhs)).sum(); } template<typename Dest> void scaleAndAddTo(Dest& dst, Scalar alpha) const @@ -399,7 +399,7 @@ template<> struct ei_gemv_selector<OnTheRight,RowMajor,false> // TODO makes sure rhs is sequentially stored in memory, otherwise use a temp const int rows = prod.rows(); for(int i=0; i<rows; ++i) - dest.coeffRef(i) += alpha * (prod.lhs().row(i).cwise() * prod.rhs().transpose()).sum(); + dest.coeffRef(i) += alpha * (prod.lhs().row(i).cwiseProduct(prod.rhs().transpose())).sum(); } }; @@ -427,7 +427,7 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const }; // note to the lost user: // * for a dot product use: v1.dot(v2) - // * for a coeff-wise product use: v1.cwise()*v2 + // * for a coeff-wise product use: v1.cwiseProduct(v2) EIGEN_STATIC_ASSERT(ProductIsValid || !(AreVectors && SameSizes), INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS) EIGEN_STATIC_ASSERT(ProductIsValid || !(SameSizes && !AreVectors), diff --git a/Eigen/src/Core/ProductBase.h b/Eigen/src/Core/ProductBase.h index 33ada4bee..3248e7293 100644 --- a/Eigen/src/Core/ProductBase.h +++ b/Eigen/src/Core/ProductBase.h @@ -29,11 +29,13 @@ * */ template<typename Derived, typename _Lhs, typename _Rhs> -struct ei_traits<ProductBase<Derived,_Lhs,_Rhs> > +struct ei_traits<ProductBase<Derived,_Lhs,_Rhs> > : ei_traits<typename ei_cleantype<_Lhs>::type> { typedef typename ei_cleantype<_Lhs>::type Lhs; typedef typename ei_cleantype<_Rhs>::type Rhs; typedef typename ei_scalar_product_traits<typename Lhs::Scalar, typename Rhs::Scalar>::ReturnType Scalar; + typedef typename ei_promote_storage_type<typename ei_traits<Lhs>::StorageType, + typename ei_traits<Rhs>::StorageType>::ret StorageType; enum { RowsAtCompileTime = ei_traits<Lhs>::RowsAtCompileTime, ColsAtCompileTime = ei_traits<Rhs>::ColsAtCompileTime, @@ -52,8 +54,8 @@ struct ei_nested<ProductBase<Derived,Lhs,Rhs>, N, EvalType> }; #define EIGEN_PRODUCT_PUBLIC_INTERFACE(Derived) \ - typedef ProductBase<Derived, Lhs, Rhs > ProductBaseType; \ - _EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, ProductBaseType) \ + typedef ProductBase<Derived, Lhs, Rhs > Base; \ + _EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \ typedef typename Base::LhsNested LhsNested; \ typedef typename Base::_LhsNested _LhsNested; \ typedef typename Base::LhsBlasTraits LhsBlasTraits; \ @@ -71,7 +73,8 @@ template<typename Derived, typename Lhs, typename Rhs> class ProductBase : public MatrixBase<Derived> { public: - _EIGEN_GENERIC_PUBLIC_INTERFACE(ProductBase,MatrixBase<Derived>) + typedef MatrixBase<Derived> Base; + _EIGEN_GENERIC_PUBLIC_INTERFACE(ProductBase) typedef typename Lhs::Nested LhsNested; typedef typename ei_cleantype<LhsNested>::type _LhsNested; @@ -210,27 +213,9 @@ template<typename Derived> template<typename ProductDerived, typename Lhs, typename Rhs> Derived& MatrixBase<Derived>::lazyAssign(const ProductBase<ProductDerived, Lhs,Rhs>& other) { - other.derived().evalTo(derived()); return derived(); + other.derived().evalTo(derived()); + return derived(); } -/** \internal - * Overloaded to perform an efficient C += (A*B).lazy() */ -template<typename Derived> -template<typename ProductDerived, typename Lhs, typename Rhs> -Derived& MatrixBase<Derived>::operator+=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0, - EvalBeforeAssigningBit>& other) -{ - other._expression().derived().addTo(derived()); return derived(); -} - -/** \internal - * Overloaded to perform an efficient C -= (A*B).lazy() */ -template<typename Derived> -template<typename ProductDerived, typename Lhs, typename Rhs> -Derived& MatrixBase<Derived>::operator-=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0, - EvalBeforeAssigningBit>& other) -{ - other._expression().derived().subTo(derived()); return derived(); -} #endif // EIGEN_PRODUCTBASE_H diff --git a/Eigen/src/Core/Redux.h b/Eigen/src/Core/Redux.h index ae6b01f57..92522f86c 100644 --- a/Eigen/src/Core/Redux.h +++ b/Eigen/src/Core/Redux.h @@ -306,12 +306,12 @@ struct ei_redux_impl<Func, Derived, LinearVectorizedTraversal, CompleteUnrolling * The template parameter \a BinaryOp is the type of the functor \a func which must be * an associative operator. Both current STL and TR1 functor styles are handled. * - * \sa MatrixBase::sum(), MatrixBase::minCoeff(), MatrixBase::maxCoeff(), MatrixBase::colwise(), MatrixBase::rowwise() + * \sa DenseBase::sum(), DenseBase::minCoeff(), DenseBase::maxCoeff(), MatrixBase::colwise(), MatrixBase::rowwise() */ template<typename Derived> template<typename Func> inline typename ei_result_of<Func(typename ei_traits<Derived>::Scalar)>::type -MatrixBase<Derived>::redux(const Func& func) const +DenseBase<Derived>::redux(const Func& func) const { typename Derived::Nested nested(derived()); typedef typename ei_cleantype<typename Derived::Nested>::type ThisNested; @@ -323,7 +323,7 @@ MatrixBase<Derived>::redux(const Func& func) const */ template<typename Derived> EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar -MatrixBase<Derived>::minCoeff() const +DenseBase<Derived>::minCoeff() const { return this->redux(Eigen::ei_scalar_min_op<Scalar>()); } @@ -332,7 +332,7 @@ MatrixBase<Derived>::minCoeff() const */ template<typename Derived> EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar -MatrixBase<Derived>::maxCoeff() const +DenseBase<Derived>::maxCoeff() const { return this->redux(Eigen::ei_scalar_max_op<Scalar>()); } @@ -343,7 +343,7 @@ MatrixBase<Derived>::maxCoeff() const */ template<typename Derived> EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar -MatrixBase<Derived>::sum() const +DenseBase<Derived>::sum() const { return this->redux(Eigen::ei_scalar_sum_op<Scalar>()); } @@ -354,7 +354,7 @@ MatrixBase<Derived>::sum() const */ template<typename Derived> EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar -MatrixBase<Derived>::mean() const +DenseBase<Derived>::mean() const { return this->redux(Eigen::ei_scalar_sum_op<Scalar>()) / this->size(); } @@ -368,7 +368,7 @@ MatrixBase<Derived>::mean() const */ template<typename Derived> EIGEN_STRONG_INLINE typename ei_traits<Derived>::Scalar -MatrixBase<Derived>::prod() const +DenseBase<Derived>::prod() const { return this->redux(Eigen::ei_scalar_product_op<Scalar>()); } diff --git a/Eigen/src/Core/ReturnByValue.h b/Eigen/src/Core/ReturnByValue.h index 1d977ace2..e35493236 100644 --- a/Eigen/src/Core/ReturnByValue.h +++ b/Eigen/src/Core/ReturnByValue.h @@ -72,7 +72,7 @@ template<typename Derived> template<typename Derived> template<typename OtherDerived> -Derived& MatrixBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other) +Derived& DenseBase<Derived>::operator=(const ReturnByValue<OtherDerived>& other) { other.evalTo(derived()); return derived(); diff --git a/Eigen/src/Core/SelfAdjointView.h b/Eigen/src/Core/SelfAdjointView.h index 9b6b3261f..9ab8cb2c1 100644 --- a/Eigen/src/Core/SelfAdjointView.h +++ b/Eigen/src/Core/SelfAdjointView.h @@ -200,15 +200,15 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, SelfAdjoint, Dynami ***************************************************************************/ template<typename Derived> -template<unsigned int Mode> -const SelfAdjointView<Derived, Mode> MatrixBase<Derived>::selfadjointView() const +template<unsigned int UpLo> +const SelfAdjointView<Derived, UpLo> MatrixBase<Derived>::selfadjointView() const { return derived(); } template<typename Derived> -template<unsigned int Mode> -SelfAdjointView<Derived, Mode> MatrixBase<Derived>::selfadjointView() +template<unsigned int UpLo> +SelfAdjointView<Derived, UpLo> MatrixBase<Derived>::selfadjointView() { return derived(); } diff --git a/Eigen/src/Core/SelfCwiseBinaryOp.h b/Eigen/src/Core/SelfCwiseBinaryOp.h new file mode 100644 index 000000000..ad5dc819b --- /dev/null +++ b/Eigen/src/Core/SelfCwiseBinaryOp.h @@ -0,0 +1,117 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 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_SELFCWISEBINARYOP_H +#define EIGEN_SELFCWISEBINARYOP_H + +/** \class SelfCwiseBinaryOp + * + * \internal + * + * \brief Internal helper class for optimizing operators like +=, -= + */ +template<typename BinaryOp, typename MatrixType> +struct ei_traits<SelfCwiseBinaryOp<BinaryOp,MatrixType> > : ei_traits<MatrixType> {}; + +template<typename BinaryOp, typename MatrixType> class SelfCwiseBinaryOp + //: public MatrixBase<SelfCwiseBinaryOp<BinaryOp,MatrixType> > + : public MatrixType::template MakeBase< SelfCwiseBinaryOp<BinaryOp, MatrixType> >::Type +{ + public: + + typedef typename MatrixType::template MakeBase< SelfCwiseBinaryOp<BinaryOp, MatrixType> >::Type Base; + _EIGEN_DENSE_PUBLIC_INTERFACE(SelfCwiseBinaryOp) + +// EIGEN_GENERIC_PUBLIC_INTERFACE(SelfCwiseBinaryOp) + typedef typename ei_packet_traits<Scalar>::type Packet; + + using Base::operator=; + + inline SelfCwiseBinaryOp(MatrixType& xpr, const BinaryOp& func = BinaryOp()) : m_matrix(xpr), m_functor(func) {} + + inline int rows() const { return m_matrix.rows(); } + inline int cols() const { return m_matrix.cols(); } + inline int stride() const { return m_matrix.stride(); } + + // note that this function is needed by assign to correctly align loads/stores + // TODO make Assign use .data() + inline Scalar& coeffRef(int row, int col) + { + return m_matrix.const_cast_derived().coeffRef(row, col); + } + + // note that this function is needed by assign to correctly align loads/stores + // TODO make Assign use .data() + inline Scalar& coeffRef(int index) + { + return m_matrix.const_cast_derived().coeffRef(index); + } + + template<typename OtherDerived> + void copyCoeff(int row, int col, const DenseBase<OtherDerived>& other) + { + OtherDerived& _other = other.const_cast_derived(); + ei_internal_assert(row >= 0 && row < rows() + && col >= 0 && col < cols()); + Scalar& tmp = m_matrix.coeffRef(row,col); + tmp = m_functor(tmp, _other.coeff(row,col)); + } + + template<typename OtherDerived> + void copyCoeff(int index, const DenseBase<OtherDerived>& other) + { + OtherDerived& _other = other.const_cast_derived(); + ei_internal_assert(index >= 0 && index < m_matrix.size()); + Scalar& tmp = m_matrix.coeffRef(index); + tmp = m_functor(tmp, _other.coeff(index)); + } + + template<typename OtherDerived, int StoreMode, int LoadMode> + void copyPacket(int row, int col, const DenseBase<OtherDerived>& other) + { + OtherDerived& _other = other.const_cast_derived(); + ei_internal_assert(row >= 0 && row < rows() + && col >= 0 && col < cols()); + m_matrix.template writePacket<StoreMode>(row, col, + m_functor.packetOp(m_matrix.template packet<StoreMode>(row, col),_other.template packet<LoadMode>(row, col)) ); + } + + template<typename OtherDerived, int StoreMode, int LoadMode> + void copyPacket(int index, const DenseBase<OtherDerived>& other) + { + OtherDerived& _other = other.const_cast_derived(); + ei_internal_assert(index >= 0 && index < m_matrix.size()); + m_matrix.template writePacket<StoreMode>(index, + m_functor.packetOp(m_matrix.template packet<StoreMode>(index),_other.template packet<LoadMode>(index)) ); + } + + protected: + MatrixType& m_matrix; + const BinaryOp& m_functor; + + private: + SelfCwiseBinaryOp& operator=(const SelfCwiseBinaryOp&); +}; + +#endif // EIGEN_SELFCWISEBINARYOP_H diff --git a/Eigen/src/Core/SolveTriangular.h b/Eigen/src/Core/SolveTriangular.h index c7f0cd227..618e29828 100644 --- a/Eigen/src/Core/SolveTriangular.h +++ b/Eigen/src/Core/SolveTriangular.h @@ -78,8 +78,7 @@ struct ei_triangular_solver_selector<Lhs,Rhs,OnTheLeft,Mode,NoUnrolling,RowMajor int i = IsLowerTriangular ? pi+k : pi-k-1; int s = IsLowerTriangular ? pi : i+1; if (k>0) - other.coeffRef(i) -= ((lhs.row(i).segment(s,k).transpose()) - .cwise()*(other.segment(s,k))).sum(); + other.coeffRef(i) -= (lhs.row(i).segment(s,k).transpose().cwiseProduct(other.segment(s,k))).sum(); if(!(Mode & UnitDiagBit)) other.coeffRef(i) /= lhs.coeff(i,i); @@ -180,8 +179,7 @@ struct ei_triangular_solver_unroller<Lhs,Rhs,Mode,Index,Size,false> { static void run(const Lhs& lhs, Rhs& rhs) { if (Index>0) - rhs.coeffRef(I) -= ((lhs.row(I).template segment<Index>(S).transpose()) - .cwise()*(rhs.template segment<Index>(S))).sum(); + rhs.coeffRef(I) -= ((lhs.row(I).template segment<Index>(S).transpose()).cwiseProduct(rhs.template segment<Index>(S))).sum(); if(!(Mode & UnitDiagBit)) rhs.coeffRef(I) /= lhs.coeff(I,I); @@ -205,7 +203,7 @@ struct ei_triangular_solver_selector<Lhs,Rhs,OnTheLeft,Mode,CompleteUnrolling,St * TriangularView methods ***************************************************************************/ -/** "in-place" version of MatrixBase::solveTriangular() where the result is written in \a other +/** "in-place" version of TriangularView::solve() where the result is written in \a other * * \nonstableyet * diff --git a/Eigen/src/Core/StableNorm.h b/Eigen/src/Core/StableNorm.h index f2d1e7240..2874f0fd8 100644 --- a/Eigen/src/Core/StableNorm.h +++ b/Eigen/src/Core/StableNorm.h @@ -28,7 +28,7 @@ template<typename ExpressionType, typename Scalar> inline void ei_stable_norm_kernel(const ExpressionType& bl, Scalar& ssq, Scalar& scale, Scalar& invScale) { - Scalar max = bl.cwise().abs().maxCoeff(); + Scalar max = bl.cwiseAbs().maxCoeff(); if (max>scale) { ssq = ssq * ei_abs2(scale/max); @@ -59,7 +59,7 @@ MatrixBase<Derived>::stableNorm() const RealScalar invScale = 1; RealScalar ssq = 0; // sum of square enum { - Alignment = (int(Flags)&DirectAccessBit) || (int(Flags)&AlignedBit) ? EnforceAlignedAccess : AsRequested + Alignment = (int(Flags)&DirectAccessBit) || (int(Flags)&AlignedBit) ? 1 : 0 }; int n = size(); int bi=0; @@ -67,10 +67,10 @@ MatrixBase<Derived>::stableNorm() const { bi = ei_alignmentOffset(&const_cast_derived().coeffRef(0), n); if (bi>0) - ei_stable_norm_kernel(start(bi), ssq, scale, invScale); + ei_stable_norm_kernel(this->start(bi), ssq, scale, invScale); } for (; bi<n; bi+=blockSize) - ei_stable_norm_kernel(VectorBlock<Derived,Dynamic,Alignment>(derived(),bi,std::min(blockSize, n - bi)), ssq, scale, invScale); + ei_stable_norm_kernel(this->segment(bi,std::min(blockSize, n - bi)).template forceAlignedAccessIf<Alignment>(), ssq, scale, invScale); return scale * ei_sqrt(ssq); } @@ -182,7 +182,7 @@ template<typename Derived> inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real MatrixBase<Derived>::hypotNorm() const { - return this->cwise().abs().redux(ei_scalar_hypot_op<RealScalar>()); + return this->cwiseAbs().redux(ei_scalar_hypot_op<RealScalar>()); } #endif // EIGEN_STABLENORM_H diff --git a/Eigen/src/Core/Swap.h b/Eigen/src/Core/Swap.h index a7cf219f7..010d8bb8b 100644 --- a/Eigen/src/Core/Swap.h +++ b/Eigen/src/Core/Swap.h @@ -32,18 +32,7 @@ * \brief Internal helper class for swapping two expressions */ template<typename ExpressionType> -struct ei_traits<SwapWrapper<ExpressionType> > -{ - typedef typename ExpressionType::Scalar Scalar; - enum { - RowsAtCompileTime = ExpressionType::RowsAtCompileTime, - ColsAtCompileTime = ExpressionType::ColsAtCompileTime, - MaxRowsAtCompileTime = ExpressionType::MaxRowsAtCompileTime, - MaxColsAtCompileTime = ExpressionType::MaxColsAtCompileTime, - Flags = ExpressionType::Flags, - CoeffReadCost = ExpressionType::CoeffReadCost - }; -}; +struct ei_traits<SwapWrapper<ExpressionType> > : ei_traits<ExpressionType> {}; template<typename ExpressionType> class SwapWrapper : public MatrixBase<SwapWrapper<ExpressionType> > diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h index 1e037e618..63d77f134 100644 --- a/Eigen/src/Core/Transpose.h +++ b/Eigen/src/Core/Transpose.h @@ -38,11 +38,12 @@ * \sa MatrixBase::transpose(), MatrixBase::adjoint() */ template<typename MatrixType> -struct ei_traits<Transpose<MatrixType> > +struct ei_traits<Transpose<MatrixType> > : ei_traits<MatrixType> { typedef typename MatrixType::Scalar Scalar; typedef typename ei_nested<MatrixType>::type MatrixTypeNested; typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested; + typedef typename ei_traits<MatrixType>::StorageType StorageType; enum { RowsAtCompileTime = MatrixType::ColsAtCompileTime, ColsAtCompileTime = MatrixType::RowsAtCompileTime, @@ -56,12 +57,15 @@ struct ei_traits<Transpose<MatrixType> > }; }; +template<typename MatrixType, typename StorageType> class TransposeImpl; + template<typename MatrixType> class Transpose - : public MatrixBase<Transpose<MatrixType> > + : public TransposeImpl<MatrixType,typename ei_traits<MatrixType>::StorageType> { public: - EIGEN_GENERIC_PUBLIC_INTERFACE(Transpose) + typedef typename TransposeImpl<MatrixType,typename ei_traits<MatrixType>::StorageType>::Base Base; + EIGEN_GENERIC_PUBLIC_INTERFACE_NEW(Transpose) inline Transpose(const MatrixType& matrix) : m_matrix(matrix) {} @@ -69,60 +73,85 @@ template<typename MatrixType> class Transpose inline int rows() const { return m_matrix.cols(); } inline int cols() const { return m_matrix.rows(); } - inline int stride() const { return m_matrix.stride(); } - inline Scalar* data() { return m_matrix.data(); } - inline const Scalar* data() const { return m_matrix.data(); } + + /** \internal used for introspection */ + const typename ei_cleantype<typename MatrixType::Nested>::type& + _expression() const { return m_matrix; } + + const typename ei_cleantype<typename MatrixType::Nested>::type& + nestedExpression() const { return m_matrix; } + + typename ei_cleantype<typename MatrixType::Nested>::type& + nestedExpression() { return m_matrix.const_cast_derived(); } + + protected: + const typename MatrixType::Nested m_matrix; +}; + + +template<typename MatrixType> class TransposeImpl<MatrixType,Dense> + : public MatrixType::template MakeBase<Transpose<MatrixType> >::Type +{ + const typename ei_cleantype<typename MatrixType::Nested>::type& matrix() const + { return derived().nestedExpression(); } + typename ei_cleantype<typename MatrixType::Nested>::type& matrix() + { return derived().nestedExpression(); } + + public: + + //EIGEN_DENSE_PUBLpename IC_INTERFACE(TransposeImpl,MatrixBase<Transpose<MatrixType> >) + typedef typename MatrixType::template MakeBase<Transpose<MatrixType> >::Type Base; + _EIGEN_DENSE_PUBLIC_INTERFACE(Transpose<MatrixType>) + +// EIGEN_EXPRESSION_IMPL_COMMON(MatrixBase<Transpose<MatrixType> >) + + inline int stride() const { return matrix().stride(); } + inline Scalar* data() { return matrix().data(); } + inline const Scalar* data() const { return matrix().data(); } inline Scalar& coeffRef(int row, int col) { - return m_matrix.const_cast_derived().coeffRef(col, row); + return matrix().const_cast_derived().coeffRef(col, row); } inline Scalar& coeffRef(int index) { - return m_matrix.const_cast_derived().coeffRef(index); + return matrix().const_cast_derived().coeffRef(index); } inline const CoeffReturnType coeff(int row, int col) const { - return m_matrix.coeff(col, row); + return matrix().coeff(col, row); } inline const CoeffReturnType coeff(int index) const { - return m_matrix.coeff(index); + return matrix().coeff(index); } template<int LoadMode> inline const PacketScalar packet(int row, int col) const { - return m_matrix.template packet<LoadMode>(col, row); + return matrix().template packet<LoadMode>(col, row); } template<int LoadMode> inline void writePacket(int row, int col, const PacketScalar& x) { - m_matrix.const_cast_derived().template writePacket<LoadMode>(col, row, x); + matrix().const_cast_derived().template writePacket<LoadMode>(col, row, x); } template<int LoadMode> inline const PacketScalar packet(int index) const { - return m_matrix.template packet<LoadMode>(index); + return matrix().template packet<LoadMode>(index); } template<int LoadMode> inline void writePacket(int index, const PacketScalar& x) { - m_matrix.const_cast_derived().template writePacket<LoadMode>(index, x); + matrix().const_cast_derived().template writePacket<LoadMode>(index, x); } - - /** \internal used for introspection */ - const typename ei_cleantype<typename MatrixType::Nested>::type& - _expression() const { return m_matrix; } - - protected: - const typename MatrixType::Nested m_matrix; }; /** \returns an expression of the transpose of *this. @@ -146,7 +175,7 @@ template<typename MatrixType> class Transpose * \sa transposeInPlace(), adjoint() */ template<typename Derived> inline Transpose<Derived> -MatrixBase<Derived>::transpose() +DenseBase<Derived>::transpose() { return derived(); } @@ -158,7 +187,7 @@ MatrixBase<Derived>::transpose() * \sa transposeInPlace(), adjoint() */ template<typename Derived> inline const Transpose<Derived> -MatrixBase<Derived>::transpose() const +DenseBase<Derived>::transpose() const { return derived(); } @@ -186,7 +215,7 @@ template<typename Derived> inline const typename MatrixBase<Derived>::AdjointReturnType MatrixBase<Derived>::adjoint() const { - return transpose(); + return this->transpose(); } /*************************************************************************** @@ -233,7 +262,7 @@ struct ei_inplace_transpose_selector<MatrixType,false> { // non square matrix * * \sa transpose(), adjoint(), adjointInPlace() */ template<typename Derived> -inline void MatrixBase<Derived>::transposeInPlace() +inline void DenseBase<Derived>::transposeInPlace() { ei_inplace_transpose_selector<Derived>::run(derived()); } @@ -309,7 +338,7 @@ struct ei_check_transpose_aliasing_selector<Scalar,DestIsTranposed,CwiseBinaryOp template<typename Derived> template<typename OtherDerived> -void MatrixBase<Derived>::checkTransposeAliasing(const OtherDerived& other) const +void DenseBase<Derived>::checkTransposeAliasing(const OtherDerived& other) const { ei_assert((!ei_check_transpose_aliasing_selector<Scalar,ei_blas_traits<Derived>::IsTransposed,OtherDerived>::run(ei_extract_data(derived()), other)) && "aliasing detected during tranposition, use transposeInPlace() or evaluate the rhs into a temporary using .eval()"); diff --git a/Eigen/src/Core/VectorBlock.h b/Eigen/src/Core/VectorBlock.h index 65268b626..96af71b36 100644 --- a/Eigen/src/Core/VectorBlock.h +++ b/Eigen/src/Core/VectorBlock.h @@ -32,13 +32,9 @@ * * \param VectorType the type of the object in which we are taking a sub-vector * \param Size size of the sub-vector we are taking at compile time (optional) - * \param _PacketAccess allows to enforce aligned loads and stores if set to ForceAligned. - * The default is AsRequested. This parameter is internaly used by Eigen - * in expressions such as \code mat.segment() += other; \endcode and most of - * the time this is the only way it is used. * * This class represents an expression of either a fixed-size or dynamic-size sub-vector. - * It is the return type of MatrixBase::segment(int,int) and MatrixBase::segment<int>(int) and + * It is the return type of DenseBase::segment(int,int) and DenseBase::segment<int>(int) and * most of the time this is the only way it is used. * * However, if you want to directly maniputate sub-vector expressions, @@ -57,32 +53,29 @@ * \include class_FixedVectorBlock.cpp * Output: \verbinclude class_FixedVectorBlock.out * - * \sa class Block, MatrixBase::segment(int,int,int,int), MatrixBase::segment(int,int) + * \sa class Block, DenseBase::segment(int,int,int,int), DenseBase::segment(int,int) */ -template<typename VectorType, int Size, int _PacketAccess> -struct ei_traits<VectorBlock<VectorType, Size, _PacketAccess> > +template<typename VectorType, int Size> +struct ei_traits<VectorBlock<VectorType, Size> > : public ei_traits<Block<VectorType, ei_traits<VectorType>::RowsAtCompileTime==1 ? 1 : Size, - ei_traits<VectorType>::ColsAtCompileTime==1 ? 1 : Size, - _PacketAccess> > + ei_traits<VectorType>::ColsAtCompileTime==1 ? 1 : Size> > { }; -template<typename VectorType, int Size, int PacketAccess> class VectorBlock +template<typename VectorType, int Size> class VectorBlock : public Block<VectorType, ei_traits<VectorType>::RowsAtCompileTime==1 ? 1 : Size, - ei_traits<VectorType>::ColsAtCompileTime==1 ? 1 : Size, - PacketAccess> + ei_traits<VectorType>::ColsAtCompileTime==1 ? 1 : Size> { typedef Block<VectorType, ei_traits<VectorType>::RowsAtCompileTime==1 ? 1 : Size, - ei_traits<VectorType>::ColsAtCompileTime==1 ? 1 : Size, - PacketAccess> _Base; + ei_traits<VectorType>::ColsAtCompileTime==1 ? 1 : Size> Base; enum { IsColVector = ei_traits<VectorType>::ColsAtCompileTime==1 }; public: - _EIGEN_GENERIC_PUBLIC_INTERFACE(VectorBlock, _Base) + _EIGEN_GENERIC_PUBLIC_INTERFACE(VectorBlock) using Base::operator=; using Base::operator+=; @@ -128,7 +121,7 @@ template<typename VectorType, int Size, int PacketAccess> class VectorBlock * \sa class Block, segment(int) */ template<typename Derived> -inline VectorBlock<Derived> MatrixBase<Derived> +inline VectorBlock<Derived> DenseBase<Derived> ::segment(int start, int size) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) @@ -138,7 +131,7 @@ inline VectorBlock<Derived> MatrixBase<Derived> /** This is the const version of segment(int,int).*/ template<typename Derived> inline const VectorBlock<Derived> -MatrixBase<Derived>::segment(int start, int size) const +DenseBase<Derived>::segment(int start, int size) const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) return VectorBlock<Derived>(derived(), start, size); @@ -161,7 +154,7 @@ MatrixBase<Derived>::segment(int start, int size) const */ template<typename Derived> inline VectorBlock<Derived> -MatrixBase<Derived>::start(int size) +DenseBase<Derived>::start(int size) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) return VectorBlock<Derived>(derived(), 0, size); @@ -170,7 +163,7 @@ MatrixBase<Derived>::start(int size) /** This is the const version of start(int).*/ template<typename Derived> inline const VectorBlock<Derived> -MatrixBase<Derived>::start(int size) const +DenseBase<Derived>::start(int size) const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) return VectorBlock<Derived>(derived(), 0, size); @@ -193,7 +186,7 @@ MatrixBase<Derived>::start(int size) const */ template<typename Derived> inline VectorBlock<Derived> -MatrixBase<Derived>::end(int size) +DenseBase<Derived>::end(int size) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) return VectorBlock<Derived>(derived(), this->size() - size, size); @@ -202,7 +195,7 @@ MatrixBase<Derived>::end(int size) /** This is the const version of end(int).*/ template<typename Derived> inline const VectorBlock<Derived> -MatrixBase<Derived>::end(int size) const +DenseBase<Derived>::end(int size) const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) return VectorBlock<Derived>(derived(), this->size() - size, size); @@ -224,7 +217,7 @@ MatrixBase<Derived>::end(int size) const template<typename Derived> template<int Size> inline VectorBlock<Derived,Size> -MatrixBase<Derived>::segment(int start) +DenseBase<Derived>::segment(int start) { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) return VectorBlock<Derived,Size>(derived(), start); @@ -234,7 +227,7 @@ MatrixBase<Derived>::segment(int start) template<typename Derived> template<int Size> inline const VectorBlock<Derived,Size> -MatrixBase<Derived>::segment(int start) const +DenseBase<Derived>::segment(int start) const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) return VectorBlock<Derived,Size>(derived(), start); @@ -254,7 +247,7 @@ MatrixBase<Derived>::segment(int start) const template<typename Derived> template<int Size> inline VectorBlock<Derived,Size> -MatrixBase<Derived>::start() +DenseBase<Derived>::start() { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) return VectorBlock<Derived,Size>(derived(), 0); @@ -264,7 +257,7 @@ MatrixBase<Derived>::start() template<typename Derived> template<int Size> inline const VectorBlock<Derived,Size> -MatrixBase<Derived>::start() const +DenseBase<Derived>::start() const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) return VectorBlock<Derived,Size>(derived(), 0); @@ -284,7 +277,7 @@ MatrixBase<Derived>::start() const template<typename Derived> template<int Size> inline VectorBlock<Derived,Size> -MatrixBase<Derived>::end() +DenseBase<Derived>::end() { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) return VectorBlock<Derived, Size>(derived(), size() - Size); @@ -294,7 +287,7 @@ MatrixBase<Derived>::end() template<typename Derived> template<int Size> inline const VectorBlock<Derived,Size> -MatrixBase<Derived>::end() const +DenseBase<Derived>::end() const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) return VectorBlock<Derived, Size>(derived(), size() - Size); diff --git a/Eigen/src/Core/Visitor.h b/Eigen/src/Core/Visitor.h index 590efc766..e6f02b79b 100644 --- a/Eigen/src/Core/Visitor.h +++ b/Eigen/src/Core/Visitor.h @@ -79,11 +79,11 @@ struct ei_visitor_impl<Visitor, Derived, Dynamic> * \note compared to one or two \em for \em loops, visitors offer automatic * unrolling for small fixed size matrix. * - * \sa minCoeff(int*,int*), maxCoeff(int*,int*), MatrixBase::redux() + * \sa minCoeff(int*,int*), maxCoeff(int*,int*), DenseBase::redux() */ template<typename Derived> template<typename Visitor> -void MatrixBase<Derived>::visit(Visitor& visitor) const +void DenseBase<Derived>::visit(Visitor& visitor) const { const bool unroll = SizeAtCompileTime * CoeffReadCost + (SizeAtCompileTime-1) * ei_functor_traits<Visitor>::Cost @@ -112,7 +112,7 @@ struct ei_coeff_visitor /** \internal * \brief Visitor computing the min coefficient with its value and coordinates * - * \sa MatrixBase::minCoeff(int*, int*) + * \sa DenseBase::minCoeff(int*, int*) */ template <typename Scalar> struct ei_min_coeff_visitor : ei_coeff_visitor<Scalar> @@ -138,7 +138,7 @@ struct ei_functor_traits<ei_min_coeff_visitor<Scalar> > { /** \internal * \brief Visitor computing the max coefficient with its value and coordinates * - * \sa MatrixBase::maxCoeff(int*, int*) + * \sa DenseBase::maxCoeff(int*, int*) */ template <typename Scalar> struct ei_max_coeff_visitor : ei_coeff_visitor<Scalar> @@ -164,11 +164,11 @@ struct ei_functor_traits<ei_max_coeff_visitor<Scalar> > { /** \returns the minimum of all coefficients of *this * and puts in *row and *col its location. * - * \sa MatrixBase::minCoeff(int*), MatrixBase::maxCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::minCoeff() + * \sa DenseBase::minCoeff(int*), DenseBase::maxCoeff(int*,int*), DenseBase::visitor(), DenseBase::minCoeff() */ template<typename Derived> typename ei_traits<Derived>::Scalar -MatrixBase<Derived>::minCoeff(int* row, int* col) const +DenseBase<Derived>::minCoeff(int* row, int* col) const { ei_min_coeff_visitor<Scalar> minVisitor; this->visit(minVisitor); @@ -180,11 +180,11 @@ MatrixBase<Derived>::minCoeff(int* row, int* col) const /** \returns the minimum of all coefficients of *this * and puts in *index its location. * - * \sa MatrixBase::minCoeff(int*,int*), MatrixBase::maxCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::minCoeff() + * \sa DenseBase::minCoeff(int*,int*), DenseBase::maxCoeff(int*,int*), DenseBase::visitor(), DenseBase::minCoeff() */ template<typename Derived> typename ei_traits<Derived>::Scalar -MatrixBase<Derived>::minCoeff(int* index) const +DenseBase<Derived>::minCoeff(int* index) const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) ei_min_coeff_visitor<Scalar> minVisitor; @@ -196,11 +196,11 @@ MatrixBase<Derived>::minCoeff(int* index) const /** \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() + * \sa DenseBase::minCoeff(int*,int*), DenseBase::visitor(), DenseBase::maxCoeff() */ template<typename Derived> typename ei_traits<Derived>::Scalar -MatrixBase<Derived>::maxCoeff(int* row, int* col) const +DenseBase<Derived>::maxCoeff(int* row, int* col) const { ei_max_coeff_visitor<Scalar> maxVisitor; this->visit(maxVisitor); @@ -212,11 +212,11 @@ MatrixBase<Derived>::maxCoeff(int* row, int* col) const /** \returns the maximum of all coefficients of *this * and puts in *index its location. * - * \sa MatrixBase::maxCoeff(int*,int*), MatrixBase::minCoeff(int*,int*), MatrixBase::visitor(), MatrixBase::maxCoeff() + * \sa DenseBase::maxCoeff(int*,int*), DenseBase::minCoeff(int*,int*), DenseBase::visitor(), DenseBase::maxCoeff() */ template<typename Derived> typename ei_traits<Derived>::Scalar -MatrixBase<Derived>::maxCoeff(int* index) const +DenseBase<Derived>::maxCoeff(int* index) const { EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived) ei_max_coeff_visitor<Scalar> maxVisitor; diff --git a/Eigen/src/Core/arch/SSE/PacketMath.h b/Eigen/src/Core/arch/SSE/PacketMath.h index dbdddb38d..a633c7b7c 100644 --- a/Eigen/src/Core/arch/SSE/PacketMath.h +++ b/Eigen/src/Core/arch/SSE/PacketMath.h @@ -176,14 +176,14 @@ template<> EIGEN_STRONG_INLINE Packet4f ei_pandnot<Packet4f>(const Packet4f& a, template<> EIGEN_STRONG_INLINE Packet2d ei_pandnot<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_andnot_pd(a,b); } template<> EIGEN_STRONG_INLINE Packet4i ei_pandnot<Packet4i>(const Packet4i& a, const Packet4i& b) { return _mm_andnot_si128(a,b); } -template<> EIGEN_STRONG_INLINE Packet4f ei_pload<float>(const float* from) { return _mm_load_ps(from); } -template<> EIGEN_STRONG_INLINE Packet2d ei_pload<double>(const double* from) { return _mm_load_pd(from); } -template<> EIGEN_STRONG_INLINE Packet4i ei_pload<int>(const int* from) { return _mm_load_si128(reinterpret_cast<const Packet4i*>(from)); } +template<> EIGEN_STRONG_INLINE Packet4f ei_pload<float>(const float* from) { EIGEN_DEBUG_ALIGNED_LOAD return _mm_load_ps(from); } +template<> EIGEN_STRONG_INLINE Packet2d ei_pload<double>(const double* from) { EIGEN_DEBUG_ALIGNED_LOAD return _mm_load_pd(from); } +template<> EIGEN_STRONG_INLINE Packet4i ei_pload<int>(const int* from) { EIGEN_DEBUG_ALIGNED_LOAD return _mm_load_si128(reinterpret_cast<const Packet4i*>(from)); } #if (!defined __GNUC__) && (!defined __ICC) -template<> EIGEN_STRONG_INLINE Packet4f ei_ploadu(const float* from) { return _mm_loadu_ps(from); } -template<> EIGEN_STRONG_INLINE Packet2d ei_ploadu<double>(const double* from) { return _mm_loadu_pd(from); } -template<> EIGEN_STRONG_INLINE Packet4i ei_ploadu<int>(const int* from) { return _mm_loadu_si128(reinterpret_cast<const Packet4i*>(from)); } +template<> EIGEN_STRONG_INLINE Packet4f ei_ploadu(const float* from) { return EIGEN_DEBUG_UNALIGNED_LOAD _mm_loadu_ps(from); } +template<> EIGEN_STRONG_INLINE Packet2d ei_ploadu<double>(const double* from) { return EIGEN_DEBUG_UNALIGNED_LOAD _mm_loadu_pd(from); } +template<> EIGEN_STRONG_INLINE Packet4i ei_ploadu<int>(const int* from) { return EIGEN_DEBUG_UNALIGNED_LOAD _mm_loadu_si128(reinterpret_cast<const Packet4i*>(from)); } #else // Fast unaligned loads. Note that here we cannot directly use intrinsics: this would // require pointer casting to incompatible pointer types and leads to invalid code @@ -192,6 +192,7 @@ template<> EIGEN_STRONG_INLINE Packet4i ei_ploadu<int>(const int* from) { return // TODO: do the same for MSVC (ICC is compatible) template<> EIGEN_STRONG_INLINE Packet4f ei_ploadu(const float* from) { + EIGEN_DEBUG_UNALIGNED_LOAD __m128 res; asm volatile ("movsd %[from0], %[r]" : [r] "=x" (res) : [from0] "m" (*from), [dummy] "m" (*(from+1)) ); asm volatile ("movhps %[from2], %[r]" : [r] "+x" (res) : [from2] "m" (*(from+2)), [dummy] "m" (*(from+3)) ); @@ -199,6 +200,7 @@ template<> EIGEN_STRONG_INLINE Packet4f ei_ploadu(const float* from) } template<> EIGEN_STRONG_INLINE Packet2d ei_ploadu(const double* from) { + EIGEN_DEBUG_UNALIGNED_LOAD __m128d res; asm volatile ("movsd %[from0], %[r]" : [r] "=x" (res) : [from0] "m" (*from) ); asm volatile ("movhpd %[from1], %[r]" : [r] "+x" (res) : [from1] "m" (*(from+1)) ); @@ -206,6 +208,7 @@ template<> EIGEN_STRONG_INLINE Packet2d ei_ploadu(const double* from) } template<> EIGEN_STRONG_INLINE Packet4i ei_ploadu(const int* from) { + EIGEN_DEBUG_UNALIGNED_LOAD __m128i res; asm volatile ("movsd %[from0], %[r]" : [r] "=x" (res) : [from0] "m" (*from), [dummy] "m" (*(from+1)) ); asm volatile ("movhps %[from2], %[r]" : [r] "+x" (res) : [from2] "m" (*(from+2)), [dummy] "m" (*(from+3)) ); @@ -213,16 +216,17 @@ template<> EIGEN_STRONG_INLINE Packet4i ei_ploadu(const int* from) } #endif -template<> EIGEN_STRONG_INLINE void ei_pstore<float>(float* to, const Packet4f& from) { _mm_store_ps(to, from); } -template<> EIGEN_STRONG_INLINE void ei_pstore<double>(double* to, const Packet2d& from) { _mm_store_pd(to, from); } -template<> EIGEN_STRONG_INLINE void ei_pstore<int>(int* to, const Packet4i& from) { _mm_store_si128(reinterpret_cast<Packet4i*>(to), from); } +template<> EIGEN_STRONG_INLINE void ei_pstore<float>(float* to, const Packet4f& from) { EIGEN_DEBUG_ALIGNED_STORE _mm_store_ps(to, from); } +template<> EIGEN_STRONG_INLINE void ei_pstore<double>(double* to, const Packet2d& from) { EIGEN_DEBUG_ALIGNED_STORE _mm_store_pd(to, from); } +template<> EIGEN_STRONG_INLINE void ei_pstore<int>(int* to, const Packet4i& from) { EIGEN_DEBUG_ALIGNED_STORE _mm_store_si128(reinterpret_cast<Packet4i*>(to), from); } template<> EIGEN_STRONG_INLINE void ei_pstoreu<double>(double* to, const Packet2d& from) { + EIGEN_DEBUG_UNALIGNED_STORE _mm_storel_pd((to), from); _mm_storeh_pd((to+1), from); } -template<> EIGEN_STRONG_INLINE void ei_pstoreu<float>(float* to, const Packet4f& from) { ei_pstoreu((double*)to, _mm_castps_pd(from)); } -template<> EIGEN_STRONG_INLINE void ei_pstoreu<int>(int* to, const Packet4i& from) { ei_pstoreu((double*)to, _mm_castsi128_pd(from)); } +template<> EIGEN_STRONG_INLINE void ei_pstoreu<float>(float* to, const Packet4f& from) { EIGEN_DEBUG_UNALIGNED_STORE ei_pstoreu((double*)to, _mm_castps_pd(from)); } +template<> EIGEN_STRONG_INLINE void ei_pstoreu<int>(int* to, const Packet4i& from) { EIGEN_DEBUG_UNALIGNED_STORE ei_pstoreu((double*)to, _mm_castsi128_pd(from)); } #if defined(_MSC_VER) && (_MSC_VER <= 1500) && defined(_WIN64) // The temporary variable fixes an internal compilation error. diff --git a/Eigen/src/Core/products/GeneralUnrolled.h b/Eigen/src/Core/products/GeneralUnrolled.h index e8fb760ae..f04c27a95 100644 --- a/Eigen/src/Core/products/GeneralUnrolled.h +++ b/Eigen/src/Core/products/GeneralUnrolled.h @@ -32,7 +32,7 @@ /* Since the all the dimensions of the product are small, here we can rely * on the generic Assign mechanism to evaluate the product per coeff (or packet). - * + * * Note that here the inner-loops should always be unrolled. */ @@ -45,10 +45,13 @@ struct ei_product_packet_impl; template<typename LhsNested, typename RhsNested> struct ei_traits<GeneralProduct<LhsNested,RhsNested,UnrolledProduct> > { + typedef DenseStorageMatrix DenseStorageType; typedef typename ei_cleantype<LhsNested>::type _LhsNested; typedef typename ei_cleantype<RhsNested>::type _RhsNested; typedef typename ei_scalar_product_traits<typename _LhsNested::Scalar, typename _RhsNested::Scalar>::ReturnType Scalar; - + typedef typename ei_promote_storage_type<typename ei_traits<_LhsNested>::StorageType, + typename ei_traits<_RhsNested>::StorageType>::ret StorageType; + enum { LhsCoeffReadCost = _LhsNested::CoeffReadCost, RhsCoeffReadCost = _RhsNested::CoeffReadCost, diff --git a/Eigen/src/Core/products/TriangularMatrixVector.h b/Eigen/src/Core/products/TriangularMatrixVector.h index 291177445..fc3188cd8 100644 --- a/Eigen/src/Core/products/TriangularMatrixVector.h +++ b/Eigen/src/Core/products/TriangularMatrixVector.h @@ -95,7 +95,7 @@ struct ei_product_triangular_vector_selector<Lhs,Rhs,Result,Mode,ConjLhs,ConjRhs int s = IsLowerTriangular ? pi : (HasUnitDiag ? i+1 : i); int r = IsLowerTriangular ? k+1 : actualPanelWidth-k; if ((!HasUnitDiag) || (--r)>0) - res.coeffRef(i) += alpha * (cjLhs.row(i).segment(s,r).cwise() * cjRhs.segment(s,r).transpose()).sum(); + res.coeffRef(i) += alpha * (cjLhs.row(i).segment(s,r).cwiseProduct(cjRhs.segment(s,r).transpose())).sum(); if (HasUnitDiag) res.coeffRef(i) += alpha * cjRhs.coeff(i); } diff --git a/Eigen/src/Core/util/Constants.h b/Eigen/src/Core/util/Constants.h index 1128876f8..8483772df 100644 --- a/Eigen/src/Core/util/Constants.h +++ b/Eigen/src/Core/util/Constants.h @@ -174,16 +174,10 @@ const unsigned int UpperTriangularBit = 0x400; * means the strictly upper triangular part is 0 */ const unsigned int LowerTriangularBit = 0x800; -/** \ingroup flags - * - * means the expression includes sparse matrices and the sparse path has to be taken. */ -const unsigned int SparseBit = 0x1000; - // list of flags that are inherited by default const unsigned int HereditaryBits = RowMajorBit | EvalBeforeNestingBit - | EvalBeforeAssigningBit - | SparseBit; + | EvalBeforeAssigningBit; // Possible values for the Mode parameter of part() const unsigned int UpperTriangular = UpperTriangularBit; @@ -195,11 +189,10 @@ const unsigned int UnitUpperTriangular = UpperTriangularBit | UnitDiagBit; const unsigned int UnitLowerTriangular = LowerTriangularBit | UnitDiagBit; enum { Unaligned=0, Aligned=1 }; -enum { AsRequested=0, EnforceAlignedAccess=2 }; enum { ConditionalJumpCost = 5 }; enum CornerType { TopLeft, TopRight, BottomLeft, BottomRight }; enum DirectionType { Vertical, Horizontal, BothDirections }; -enum ProductEvaluationMode { NormalProduct, CacheFriendlyProduct, SparseTimeSparseProduct, SparseTimeDenseProduct, DenseTimeSparseProduct }; +enum ProductEvaluationMode { NormalProduct, CacheFriendlyProduct }; enum { /** \internal Default traversal, no vectorization, no index-based access */ @@ -264,7 +257,7 @@ namespace { enum { IsDense = 0, - IsSparse = SparseBit, + IsSparse, NoDirectAccess = 0, HasDirectAccess = DirectAccessBit }; @@ -292,4 +285,7 @@ namespace Architecture }; } +enum DenseStorageMatrix {}; +enum DenseStorageArray {}; + #endif // EIGEN_CONSTANTS_H diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index 62e4bb31b..09c6c9528 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -35,20 +35,21 @@ template<typename _Scalar, int _Rows, int _Cols, int _MaxRows = _Rows, int _MaxCols = _Cols> class Matrix; template<typename ExpressionType, unsigned int Added, unsigned int Removed> class Flagged; -template<typename ExpressionType> class NoAlias; +template<typename ExpressionType, template <typename> class StorageBase > class NoAlias; template<typename ExpressionType> class NestByValue; +template<typename ExpressionType> class ForceAlignedAccess; template<typename ExpressionType> class SwapWrapper; template<typename MatrixType> class Minor; -template<typename MatrixType, int BlockRows=Dynamic, int BlockCols=Dynamic, int PacketAccess=AsRequested, - int _DirectAccessStatus = ei_traits<MatrixType>::Flags&DirectAccessBit ? DirectAccessBit - : ei_traits<MatrixType>::Flags&SparseBit> class Block; -template<typename MatrixType, int Size=Dynamic, int PacketAccess=AsRequested> class VectorBlock; +template<typename MatrixType, int BlockRows=Dynamic, int BlockCols=Dynamic, + int _DirectAccessStatus = (ei_traits<MatrixType>::Flags&DirectAccessBit) ? HasDirectAccess : NoDirectAccess> class Block; +template<typename MatrixType, int Size=Dynamic> class VectorBlock; template<typename MatrixType> class Transpose; template<typename MatrixType> class Conjugate; template<typename NullaryOp, typename MatrixType> class CwiseNullaryOp; template<typename UnaryOp, typename MatrixType> class CwiseUnaryOp; template<typename ViewOp, typename MatrixType> class CwiseUnaryView; template<typename BinaryOp, typename Lhs, typename Rhs> class CwiseBinaryOp; +template<typename BinOp, typename MatrixType> class SelfCwiseBinaryOp; template<typename Derived, typename Lhs, typename Rhs> class ProductBase; template<typename Derived> class DiagonalBase; @@ -57,14 +58,14 @@ template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime=SizeA template<typename MatrixType, typename DiagonalType, int ProductOrder> class DiagonalProduct; template<typename MatrixType, int Index> class Diagonal; -template<typename MatrixType, int PacketAccess = AsRequested> class Map; +template<typename MatrixType, int Options=Unaligned> class Map; template<typename Derived> class TriangularBase; template<typename MatrixType, unsigned int Mode> class TriangularView; template<typename MatrixType, unsigned int Mode> class SelfAdjointView; -template<typename ExpressionType> class Cwise; template<typename ExpressionType> class WithFormat; template<typename MatrixType> struct CommaInitializer; template<typename Derived> class ReturnByValue; +template<typename ExpressionType> class ArrayWrapper; template<typename DecompositionType, typename Rhs> struct ei_solve_retval_base; template<typename DecompositionType, typename Rhs> struct ei_solve_retval; @@ -114,6 +115,9 @@ template<typename Scalar1,typename Scalar2> struct ei_scalar_multiple2_op; struct IOFormat; // Array module +template<typename _Scalar, int _Rows, int _Cols, + int _Options = EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION | AutoAlign, + int _MaxRows = _Rows, int _MaxCols = _Cols> class Array; template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType> class Select; template<typename MatrixType, typename BinaryOp, int Direction> class PartialReduxExpr; template<typename ExpressionType, int Direction> class VectorwiseOp; @@ -147,8 +151,8 @@ template<typename Scalar,int Dim> class Translation; template<typename Scalar> class UniformScaling; template<typename MatrixType,int Direction> class Homogeneous; -// Sparse module: -template<typename Lhs, typename Rhs, int ProductMode> class SparseProduct; - +#ifdef EIGEN2_SUPPORT +template<typename ExpressionType> class Cwise; +#endif #endif // EIGEN_FORWARDDECLARATIONS_H diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h index a51b46f02..4ea5013f7 100644 --- a/Eigen/src/Core/util/Macros.h +++ b/Eigen/src/Core/util/Macros.h @@ -263,43 +263,79 @@ using Eigen::ei_cos; #if defined(_MSC_VER) && (!defined(__INTEL_COMPILER)) #define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \ -using Base::operator =; + using Base::operator =; #else #define EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) \ -using Base::operator =; \ -EIGEN_STRONG_INLINE Derived& operator=(const Derived& other) \ -{ \ - Base::operator=(other); \ - return *this; \ -} + using Base::operator =; \ + EIGEN_STRONG_INLINE Derived& operator=(const Derived& other) \ + { \ + Base::operator=(other); \ + return *this; \ + } #endif #define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) \ -using Base::operator +=; \ -using Base::operator -=; \ -using Base::operator *=; \ -using Base::operator /=; \ -EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) - -#define _EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, BaseClass) \ -typedef BaseClass Base; \ -typedef typename Eigen::ei_traits<Derived>::Scalar Scalar; \ -typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; \ -typedef typename Base::PacketScalar PacketScalar; \ -typedef typename Base::CoeffReturnType CoeffReturnType; \ -typedef typename Eigen::ei_nested<Derived>::type Nested; \ -enum { RowsAtCompileTime = Eigen::ei_traits<Derived>::RowsAtCompileTime, \ - ColsAtCompileTime = Eigen::ei_traits<Derived>::ColsAtCompileTime, \ - MaxRowsAtCompileTime = Eigen::ei_traits<Derived>::MaxRowsAtCompileTime, \ - MaxColsAtCompileTime = Eigen::ei_traits<Derived>::MaxColsAtCompileTime, \ - Flags = Eigen::ei_traits<Derived>::Flags, \ - CoeffReadCost = Eigen::ei_traits<Derived>::CoeffReadCost, \ - SizeAtCompileTime = Base::SizeAtCompileTime, \ - MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \ - IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; + using Base::operator +=; \ + using Base::operator -=; \ + using Base::operator *=; \ + using Base::operator /=; \ + EIGEN_INHERIT_ASSIGNMENT_EQUAL_OPERATOR(Derived) + +#define _EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \ + typedef typename Eigen::ei_traits<Derived>::Scalar Scalar; \ + typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; \ + typedef typename Base::PacketScalar PacketScalar; \ + typedef typename Base::CoeffReturnType CoeffReturnType; \ + typedef typename Eigen::ei_nested<Derived>::type Nested; \ + enum { RowsAtCompileTime = Eigen::ei_traits<Derived>::RowsAtCompileTime, \ + ColsAtCompileTime = Eigen::ei_traits<Derived>::ColsAtCompileTime, \ + MaxRowsAtCompileTime = Eigen::ei_traits<Derived>::MaxRowsAtCompileTime, \ + MaxColsAtCompileTime = Eigen::ei_traits<Derived>::MaxColsAtCompileTime, \ + Flags = Eigen::ei_traits<Derived>::Flags, \ + CoeffReadCost = Eigen::ei_traits<Derived>::CoeffReadCost, \ + SizeAtCompileTime = Base::SizeAtCompileTime, \ + MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \ + IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; #define EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) \ -_EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, Eigen::MatrixBase<Derived>) + typedef Eigen::MatrixBase<Derived> Base; \ + _EIGEN_GENERIC_PUBLIC_INTERFACE(Derived) + +#define EIGEN_GENERIC_PUBLIC_INTERFACE_NEW(Derived) \ + typedef typename Eigen::ei_traits<Derived>::Scalar Scalar; \ + typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; \ + typedef typename Base::CoeffReturnType CoeffReturnType; \ + typedef typename Eigen::ei_nested<Derived>::type Nested; \ + enum { RowsAtCompileTime = Eigen::ei_traits<Derived>::RowsAtCompileTime, \ + ColsAtCompileTime = Eigen::ei_traits<Derived>::ColsAtCompileTime, \ + Flags = Eigen::ei_traits<Derived>::Flags, \ + CoeffReadCost = Eigen::ei_traits<Derived>::CoeffReadCost, \ + SizeAtCompileTime = Base::SizeAtCompileTime, \ + MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \ + IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; + + +#define _EIGEN_DENSE_PUBLIC_INTERFACE(Derived) \ + typedef typename Eigen::ei_traits<Derived>::Scalar Scalar; \ + typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; \ + typedef typename Base::PacketScalar PacketScalar; \ + typedef typename Base::CoeffReturnType CoeffReturnType; \ + typedef typename Eigen::ei_nested<Derived>::type Nested; \ + enum { RowsAtCompileTime = Eigen::ei_traits<Derived>::RowsAtCompileTime, \ + ColsAtCompileTime = Eigen::ei_traits<Derived>::ColsAtCompileTime, \ + MaxRowsAtCompileTime = Eigen::ei_traits<Derived>::MaxRowsAtCompileTime, \ + MaxColsAtCompileTime = Eigen::ei_traits<Derived>::MaxColsAtCompileTime, \ + Flags = Eigen::ei_traits<Derived>::Flags, \ + CoeffReadCost = Eigen::ei_traits<Derived>::CoeffReadCost, \ + SizeAtCompileTime = Base::SizeAtCompileTime, \ + MaxSizeAtCompileTime = Base::MaxSizeAtCompileTime, \ + IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; \ + using Base::derived; + +#define EIGEN_DENSE_PUBLIC_INTERFACE(Derived) \ + typedef Eigen::MatrixBase<Derived> Base; \ + _EIGEN_DENSE_PUBLIC_INTERFACE(Derived) + #define EIGEN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b) #define EIGEN_SIZE_MIN(a,b) (((int)a == 1 || (int)b == 1) ? 1 \ @@ -308,4 +344,26 @@ _EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, Eigen::MatrixBase<Derived>) #define EIGEN_ENUM_MAX(a,b) (((int)a >= (int)b) ? (int)a : (int)b) #define EIGEN_LOGICAL_XOR(a,b) (((a) || (b)) && !((a) && (b))) + +#define EIGEN_MAKE_CWISE_BINARY_OP(METHOD,FUNCTOR) \ + template<typename OtherDerived> \ + inline const CwiseBinaryOp<FUNCTOR<Scalar>, Derived, OtherDerived> \ + METHOD(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const \ + { \ + return CwiseBinaryOp<FUNCTOR<Scalar>, Derived, OtherDerived>(derived(), other.derived()); \ + } + +// the expression type of a cwise product +#define EIGEN_CWISE_PRODUCT_RETURN_TYPE(LHS,RHS) \ + CwiseBinaryOp< \ + ei_scalar_product_op< \ + typename ei_scalar_product_traits< \ + typename ei_traits<LHS>::Scalar, \ + typename ei_traits<RHS>::Scalar \ + >::ReturnType \ + >, \ + LHS, \ + RHS \ + > + #endif // EIGEN_MACROS_H diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h index 2a9feaeeb..6d4a5c7bc 100644 --- a/Eigen/src/Core/util/XprHelper.h +++ b/Eigen/src/Core/util/XprHelper.h @@ -105,13 +105,35 @@ template<int _Rows, int _Cols> struct ei_size_at_compile_time enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols }; }; -/* ei_eval : the return type of eval(). For matrices, this is just a const reference - * in order to avoid a useless copy +/* ei_plain_matrix_type : the difference from ei_eval is that ei_plain_matrix_type is always a plain matrix type, + * whereas ei_eval is a const reference in the case of a matrix */ -template<typename T, int Sparseness = ei_traits<T>::Flags&SparseBit> class ei_eval; +// template<typename Derived> class MatrixBase; +// template<typename Derived> class ArrayBase; +// template<typename Object> struct ei_is_matrix_or_array +// { +// struct is_matrix {int a[1];}; +// struct is_array {int a[2];}; +// struct is_none {int a[3];}; +// +// template<typename T> +// static is_matrix testBaseClass(const MatrixBase<T>*); +// template<typename T> +// static is_array testBaseClass(const ArrayBase<T>*); +// // static is_none testBaseClass(...); +// +// enum {BaseClassType = sizeof(testBaseClass(static_cast<const Object*>(0)))}; +// }; -template<typename T> struct ei_eval<T,IsDense> +template<typename T, typename StorageType = typename ei_traits<T>::StorageType> class ei_plain_matrix_type; +template<typename T, typename BaseClassType> struct ei_plain_matrix_type_dense; +template<typename T> struct ei_plain_matrix_type<T,Dense> +{ + typedef typename ei_plain_matrix_type_dense<T,typename ei_traits<T>::DenseStorageType>::type type; +}; + +template<typename T> struct ei_plain_matrix_type_dense<T,DenseStorageMatrix> { typedef Matrix<typename ei_traits<T>::Scalar, ei_traits<T>::RowsAtCompileTime, @@ -122,19 +144,9 @@ template<typename T> struct ei_eval<T,IsDense> > type; }; -// for matrices, no need to evaluate, just use a const reference to avoid a useless copy -template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols> -struct ei_eval<Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>, IsDense> -{ - typedef const Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>& type; -}; - -/* ei_plain_matrix_type : the difference from ei_eval is that ei_plain_matrix_type is always a plain matrix type, - * whereas ei_eval is a const reference in the case of a matrix - */ -template<typename T> struct ei_plain_matrix_type +template<typename T> struct ei_plain_matrix_type_dense<T,DenseStorageArray> { - typedef Matrix<typename ei_traits<T>::Scalar, + typedef Array<typename ei_traits<T>::Scalar, ei_traits<T>::RowsAtCompileTime, ei_traits<T>::ColsAtCompileTime, AutoAlign | (ei_traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor), @@ -143,6 +155,40 @@ template<typename T> struct ei_plain_matrix_type > type; }; +/* ei_eval : the return type of eval(). For matrices, this is just a const reference + * in order to avoid a useless copy + */ + +template<typename T, typename StorageType = typename ei_traits<T>::StorageType> class ei_eval; + +template<typename T> struct ei_eval<T,Dense> +{ + typedef typename ei_plain_matrix_type<T>::type type; +// typedef typename T::PlainMatrixType type; +// typedef T::Matrix<typename ei_traits<T>::Scalar, +// ei_traits<T>::RowsAtCompileTime, +// ei_traits<T>::ColsAtCompileTime, +// AutoAlign | (ei_traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor), +// ei_traits<T>::MaxRowsAtCompileTime, +// ei_traits<T>::MaxColsAtCompileTime +// > type; +}; + +// for matrices, no need to evaluate, just use a const reference to avoid a useless copy +template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols> +struct ei_eval<Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>, Dense> +{ + typedef const Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>& type; +}; + +template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols> +struct ei_eval<Array<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>, Dense> +{ + typedef const Array<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>& type; +}; + + + /* ei_plain_matrix_type_column_major : same as ei_plain_matrix_type but guaranteed to be column-major */ template<typename T> struct ei_plain_matrix_type_column_major @@ -261,7 +307,7 @@ struct ei_special_scalar_op_base<Derived,Scalar,OtherScalar,true> : public AnyM inline friend const CwiseUnaryOp<ei_scalar_multiple2_op<Scalar,OtherScalar>, Derived> operator*(const OtherScalar& scalar, const Derived& matrix) - { return matrix*scalar; } + { return static_cast<const ei_special_scalar_op_base&>(matrix).operator*(scalar); } }; /** \internal Gives the type of a sub-matrix or sub-vector of a matrix of type \a ExpressionType and size \a Size @@ -293,4 +339,11 @@ template<typename XprType, typename CastType> struct ei_cast_return_type const XprType&,CastType>::ret type; }; +template <typename A, typename B> struct ei_promote_storage_type; + +template <typename A> struct ei_promote_storage_type<A,A> +{ + typedef A ret; +}; + #endif // EIGEN_XPRHELPER_H diff --git a/Eigen/src/Core/Cwise.h b/Eigen/src/Eigen2Support/Cwise.h index 4f3d641cb..ab7056a1d 100644 --- a/Eigen/src/Core/Cwise.h +++ b/Eigen/src/Eigen2Support/Cwise.h @@ -31,18 +31,6 @@ #define EIGEN_CWISE_BINOP_RETURN_TYPE(OP) \ CwiseBinaryOp<OP<typename ei_traits<ExpressionType>::Scalar>, ExpressionType, OtherDerived> -#define EIGEN_CWISE_PRODUCT_RETURN_TYPE \ - CwiseBinaryOp< \ - ei_scalar_product_op< \ - typename ei_scalar_product_traits< \ - typename ei_traits<ExpressionType>::Scalar, \ - typename ei_traits<OtherDerived>::Scalar \ - >::ReturnType \ - >, \ - ExpressionType, \ - OtherDerived \ - > - /** \internal * convenient macro to defined the return type of a cwise unary operation */ #define EIGEN_CWISE_UNOP_RETURN_TYPE(OP) \ @@ -86,7 +74,7 @@ template<typename ExpressionType> class Cwise inline const ExpressionType& _expression() const { return m_matrix; } template<typename OtherDerived> - const EIGEN_CWISE_PRODUCT_RETURN_TYPE + const EIGEN_CWISE_PRODUCT_RETURN_TYPE(ExpressionType,OtherDerived) operator*(const MatrixBase<OtherDerived> &other) const; template<typename OtherDerived> @@ -180,6 +168,7 @@ template<typename ExpressionType> class Cwise ExpressionTypeNested m_matrix; }; + /** \returns a Cwise wrapper of *this providing additional coefficient-wise operations * * Example: \include MatrixBase_cwise_const.cpp @@ -188,8 +177,7 @@ template<typename ExpressionType> class Cwise * \sa class Cwise, cwise() */ template<typename Derived> -inline const Cwise<Derived> -MatrixBase<Derived>::cwise() const +inline const Cwise<Derived> MatrixBase<Derived>::cwise() const { return derived(); } @@ -202,8 +190,7 @@ MatrixBase<Derived>::cwise() const * \sa class Cwise, cwise() const */ template<typename Derived> -inline Cwise<Derived> -MatrixBase<Derived>::cwise() +inline Cwise<Derived> MatrixBase<Derived>::cwise() { return derived(); } diff --git a/Eigen/src/Array/CwiseOperators.h b/Eigen/src/Eigen2Support/CwiseOperators.h index 1cd1866e7..ac1dc0a7e 100644 --- a/Eigen/src/Array/CwiseOperators.h +++ b/Eigen/src/Eigen2Support/CwiseOperators.h @@ -25,10 +25,163 @@ #ifndef EIGEN_ARRAY_CWISE_OPERATORS_H #define EIGEN_ARRAY_CWISE_OPERATORS_H +/*************************************************************************** +* The following functions were defined in Core +***************************************************************************/ + + +/** \returns an expression of the coefficient-wise absolute value of \c *this + * + * Example: \include Cwise_abs.cpp + * Output: \verbinclude Cwise_abs.out + * + * \sa abs2() + */ +template<typename ExpressionType> +EIGEN_STRONG_INLINE const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs_op) +Cwise<ExpressionType>::abs() const +{ + return _expression(); +} + +/** \returns an expression of the coefficient-wise squared absolute value of \c *this + * + * Example: \include Cwise_abs2.cpp + * Output: \verbinclude Cwise_abs2.out + * + * \sa abs(), square() + */ +template<typename ExpressionType> +EIGEN_STRONG_INLINE const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs2_op) +Cwise<ExpressionType>::abs2() const +{ + return _expression(); +} + +/** \returns an expression of the coefficient-wise exponential of *this. + * + * Example: \include Cwise_exp.cpp + * Output: \verbinclude Cwise_exp.out + * + * \sa pow(), log(), sin(), cos() + */ +template<typename ExpressionType> +inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_exp_op) +Cwise<ExpressionType>::exp() const +{ + return _expression(); +} + +/** \returns an expression of the coefficient-wise logarithm of *this. + * + * Example: \include Cwise_log.cpp + * Output: \verbinclude Cwise_log.out + * + * \sa exp() + */ +template<typename ExpressionType> +inline const EIGEN_CWISE_UNOP_RETURN_TYPE(ei_scalar_log_op) +Cwise<ExpressionType>::log() const +{ + return _expression(); +} + +/** \returns an expression of the Schur product (coefficient wise product) of *this and \a other + * + * Example: \include Cwise_product.cpp + * Output: \verbinclude Cwise_product.out + * + * \sa class CwiseBinaryOp, operator/(), square() + */ +template<typename ExpressionType> +template<typename OtherDerived> +EIGEN_STRONG_INLINE const EIGEN_CWISE_PRODUCT_RETURN_TYPE(ExpressionType,OtherDerived) +Cwise<ExpressionType>::operator*(const MatrixBase<OtherDerived> &other) const +{ + return EIGEN_CWISE_PRODUCT_RETURN_TYPE(ExpressionType,OtherDerived)(_expression(), other.derived()); +} + +/** \returns an expression of the coefficient-wise quotient of *this and \a other + * + * Example: \include Cwise_quotient.cpp + * Output: \verbinclude Cwise_quotient.out + * + * \sa class CwiseBinaryOp, operator*(), inverse() + */ +template<typename ExpressionType> +template<typename OtherDerived> +EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op) +Cwise<ExpressionType>::operator/(const MatrixBase<OtherDerived> &other) const +{ + return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)(_expression(), other.derived()); +} + +/** Replaces this expression by its coefficient-wise product with \a other. + * + * Example: \include Cwise_times_equal.cpp + * Output: \verbinclude Cwise_times_equal.out + * + * \sa operator*(), operator/=() + */ +template<typename ExpressionType> +template<typename OtherDerived> +inline ExpressionType& Cwise<ExpressionType>::operator*=(const MatrixBase<OtherDerived> &other) +{ + return m_matrix.const_cast_derived() = *this * other; +} + +/** Replaces this expression by its coefficient-wise quotient by \a other. + * + * Example: \include Cwise_slash_equal.cpp + * Output: \verbinclude Cwise_slash_equal.out + * + * \sa operator/(), operator*=() + */ +template<typename ExpressionType> +template<typename OtherDerived> +inline ExpressionType& Cwise<ExpressionType>::operator/=(const MatrixBase<OtherDerived> &other) +{ + return m_matrix.const_cast_derived() = *this / other; +} + +/** \returns an expression of the coefficient-wise min of *this and \a other + * + * Example: \include Cwise_min.cpp + * Output: \verbinclude Cwise_min.out + * + * \sa class CwiseBinaryOp + */ +template<typename ExpressionType> +template<typename OtherDerived> +EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op) +Cwise<ExpressionType>::min(const MatrixBase<OtherDerived> &other) const +{ + return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op)(_expression(), other.derived()); +} + +/** \returns an expression of the coefficient-wise max of *this and \a other + * + * Example: \include Cwise_max.cpp + * Output: \verbinclude Cwise_max.out + * + * \sa class CwiseBinaryOp + */ +template<typename ExpressionType> +template<typename OtherDerived> +EIGEN_STRONG_INLINE const EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op) +Cwise<ExpressionType>::max(const MatrixBase<OtherDerived> &other) const +{ + return EIGEN_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op)(_expression(), other.derived()); +} + +/*************************************************************************** +* The following functions were defined in Array +***************************************************************************/ + // -- unary operators -- /** \array_module - * + * * \returns an expression of the coefficient-wise square root of *this. * * Example: \include Cwise_sqrt.cpp @@ -44,7 +197,7 @@ Cwise<ExpressionType>::sqrt() const } /** \array_module - * + * * \returns an expression of the coefficient-wise cosine of *this. * * Example: \include Cwise_cos.cpp @@ -61,7 +214,7 @@ Cwise<ExpressionType>::cos() const /** \array_module - * + * * \returns an expression of the coefficient-wise sine of *this. * * Example: \include Cwise_sin.cpp @@ -78,7 +231,7 @@ Cwise<ExpressionType>::sin() const /** \array_module - * + * * \returns an expression of the coefficient-wise power of *this to the given exponent. * * Example: \include Cwise_pow.cpp @@ -95,7 +248,7 @@ Cwise<ExpressionType>::pow(const Scalar& exponent) const /** \array_module - * + * * \returns an expression of the coefficient-wise inverse of *this. * * Example: \include Cwise_inverse.cpp @@ -146,7 +299,7 @@ Cwise<ExpressionType>::cube() const // -- binary operators -- /** \array_module - * + * * \returns an expression of the coefficient-wise \< operator of *this and \a other * * Example: \include Cwise_less.cpp @@ -163,7 +316,7 @@ Cwise<ExpressionType>::operator<(const MatrixBase<OtherDerived> &other) const } /** \array_module - * + * * \returns an expression of the coefficient-wise \<= operator of *this and \a other * * Example: \include Cwise_less_equal.cpp @@ -180,7 +333,7 @@ Cwise<ExpressionType>::operator<=(const MatrixBase<OtherDerived> &other) const } /** \array_module - * + * * \returns an expression of the coefficient-wise \> operator of *this and \a other * * Example: \include Cwise_greater.cpp @@ -197,7 +350,7 @@ Cwise<ExpressionType>::operator>(const MatrixBase<OtherDerived> &other) const } /** \array_module - * + * * \returns an expression of the coefficient-wise \>= operator of *this and \a other * * Example: \include Cwise_greater_equal.cpp @@ -214,7 +367,7 @@ Cwise<ExpressionType>::operator>=(const MatrixBase<OtherDerived> &other) const } /** \array_module - * + * * \returns an expression of the coefficient-wise == operator of *this and \a other * * \warning this performs an exact comparison, which is generally a bad idea with floating-point types. @@ -236,7 +389,7 @@ Cwise<ExpressionType>::operator==(const MatrixBase<OtherDerived> &other) const } /** \array_module - * + * * \returns an expression of the coefficient-wise != operator of *this and \a other * * \warning this performs an exact comparison, which is generally a bad idea with floating-point types. @@ -260,7 +413,7 @@ Cwise<ExpressionType>::operator!=(const MatrixBase<OtherDerived> &other) const // comparisons to scalar value /** \array_module - * + * * \returns an expression of the coefficient-wise \< operator of *this and a scalar \a s * * \sa operator<(const MatrixBase<OtherDerived> &) const @@ -274,7 +427,7 @@ Cwise<ExpressionType>::operator<(Scalar s) const } /** \array_module - * + * * \returns an expression of the coefficient-wise \<= operator of *this and a scalar \a s * * \sa operator<=(const MatrixBase<OtherDerived> &) const @@ -288,7 +441,7 @@ Cwise<ExpressionType>::operator<=(Scalar s) const } /** \array_module - * + * * \returns an expression of the coefficient-wise \> operator of *this and a scalar \a s * * \sa operator>(const MatrixBase<OtherDerived> &) const @@ -302,7 +455,7 @@ Cwise<ExpressionType>::operator>(Scalar s) const } /** \array_module - * + * * \returns an expression of the coefficient-wise \>= operator of *this and a scalar \a s * * \sa operator>=(const MatrixBase<OtherDerived> &) const @@ -316,7 +469,7 @@ Cwise<ExpressionType>::operator>=(Scalar s) const } /** \array_module - * + * * \returns an expression of the coefficient-wise == operator of *this and a scalar \a s * * \warning this performs an exact comparison, which is generally a bad idea with floating-point types. @@ -335,7 +488,7 @@ Cwise<ExpressionType>::operator==(Scalar s) const } /** \array_module - * + * * \returns an expression of the coefficient-wise != operator of *this and a scalar \a s * * \warning this performs an exact comparison, which is generally a bad idea with floating-point types. diff --git a/Eigen/src/Core/Flagged.h b/Eigen/src/Eigen2Support/Flagged.h index 754eaf6c5..94e7f9119 100644 --- a/Eigen/src/Core/Flagged.h +++ b/Eigen/src/Eigen2Support/Flagged.h @@ -131,7 +131,7 @@ MatrixBase<Derived>::marked() const } /** \deprecated use MatrixBase::noalias() - * + * * \returns an expression of *this with the EvalBeforeAssigningBit flag removed. * * Example: \include MatrixBase_lazy.cpp @@ -146,4 +146,25 @@ MatrixBase<Derived>::lazy() const return derived(); } + +/** \internal + * Overloaded to perform an efficient C += (A*B).lazy() */ +template<typename Derived> +template<typename ProductDerived, typename Lhs, typename Rhs> +Derived& MatrixBase<Derived>::operator+=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0, + EvalBeforeAssigningBit>& other) +{ + other._expression().derived().addTo(derived()); return derived(); +} + +/** \internal + * Overloaded to perform an efficient C -= (A*B).lazy() */ +template<typename Derived> +template<typename ProductDerived, typename Lhs, typename Rhs> +Derived& MatrixBase<Derived>::operator-=(const Flagged<ProductBase<ProductDerived, Lhs,Rhs>, 0, + EvalBeforeAssigningBit>& other) +{ + other._expression().derived().subTo(derived()); return derived(); +} + #endif // EIGEN_FLAGGED_H diff --git a/Eigen/src/Eigen2Support/Lazy.h b/Eigen/src/Eigen2Support/Lazy.h new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/Eigen/src/Eigen2Support/Lazy.h diff --git a/Eigen/src/Eigen2Support/TriangularSolver.h b/Eigen/src/Eigen2Support/TriangularSolver.h new file mode 100644 index 000000000..e69de29bb --- /dev/null +++ b/Eigen/src/Eigen2Support/TriangularSolver.h diff --git a/Eigen/src/Eigenvalues/ComplexEigenSolver.h b/Eigen/src/Eigenvalues/ComplexEigenSolver.h index 86206ce79..0441d4f02 100644 --- a/Eigen/src/Eigenvalues/ComplexEigenSolver.h +++ b/Eigen/src/Eigenvalues/ComplexEigenSolver.h @@ -133,7 +133,7 @@ void ComplexEigenSolver<MatrixType>::compute(const MatrixType& matrix) for (int i=0; i<n; i++) { int k; - m_eivalues.cwise().abs().end(n-i).minCoeff(&k); + m_eivalues.cwiseAbs().end(n-i).minCoeff(&k); if (k != 0) { k += i; diff --git a/Eigen/src/Eigenvalues/ComplexSchur.h b/Eigen/src/Eigenvalues/ComplexSchur.h index a25af342d..38a1f56dc 100644 --- a/Eigen/src/Eigenvalues/ComplexSchur.h +++ b/Eigen/src/Eigenvalues/ComplexSchur.h @@ -204,7 +204,7 @@ void ComplexSchur<MatrixType>::compute(const MatrixType& matrix, bool skipU) // compute the shift (the normalization by sf is to avoid under/overflow) Matrix<Scalar,2,2> t = m_matT.template block<2,2>(iu-1,iu-1); - sf = t.cwise().abs().sum(); + sf = t.cwiseAbs().sum(); t /= sf; c = t.determinant(); diff --git a/Eigen/src/Eigenvalues/EigenSolver.h b/Eigen/src/Eigenvalues/EigenSolver.h index 73d240de0..c9c239b98 100644 --- a/Eigen/src/Eigenvalues/EigenSolver.h +++ b/Eigen/src/Eigenvalues/EigenSolver.h @@ -225,7 +225,7 @@ void EigenSolver<MatrixType>::orthes(MatrixType& matH, RealVectorType& ort) for (int m = low+1; m <= high-1; ++m) { // Scale column. - RealScalar scale = matH.block(m, m-1, high-m+1, 1).cwise().abs().sum(); + RealScalar scale = matH.block(m, m-1, high-m+1, 1).cwiseAbs().sum(); if (scale != 0.0) { // Compute Householder transformation. @@ -312,7 +312,7 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH) // Store roots isolated by balanc and compute matrix norm // FIXME to be efficient the following would requires a triangular reduxion code - // Scalar norm = matH.upper().cwise().abs().sum() + matH.corner(BottomLeft,n,n).diagonal().cwise().abs().sum(); + // Scalar norm = matH.upper().cwiseAbs().sum() + matH.corner(BottomLeft,n,n).diagonal().cwiseAbs().sum(); Scalar norm = 0.0; for (int j = 0; j < nn; ++j) { @@ -321,7 +321,7 @@ void EigenSolver<MatrixType>::hqr2(MatrixType& matH) { m_eivalues.coeffRef(j) = Complex(matH.coeff(j,j), 0.0); } - norm += matH.row(j).segment(std::max(j-1,0), nn-std::max(j-1,0)).cwise().abs().sum(); + norm += matH.row(j).segment(std::max(j-1,0), nn-std::max(j-1,0)).cwiseAbs().sum(); } // Outer loop over eigenvalue index diff --git a/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h b/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h index 9e155de8f..336976517 100644 --- a/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h +++ b/Eigen/src/Eigenvalues/SelfAdjointEigenSolver.h @@ -112,7 +112,7 @@ template<typename _MatrixType> class SelfAdjointEigenSolver */ MatrixType operatorSqrt() const { - return m_eivec * m_eivalues.cwise().sqrt().asDiagonal() * m_eivec.adjoint(); + return m_eivec * m_eivalues.cwiseSqrt().asDiagonal() * m_eivec.adjoint(); } /** \returns the positive inverse square root of the matrix @@ -121,7 +121,7 @@ template<typename _MatrixType> class SelfAdjointEigenSolver */ MatrixType operatorInverseSqrt() const { - return m_eivec * m_eivalues.cwise().inverse().cwise().sqrt().asDiagonal() * m_eivec.adjoint(); + return m_eivec * m_eivalues.cwiseInverse().cwiseSqrt().asDiagonal() * m_eivec.adjoint(); } @@ -287,7 +287,7 @@ struct ei_operatorNorm_selector { // FIXME if it is really guaranteed that the eigenvalues are already sorted, // then we don't need to compute a maxCoeff() here, comparing the 1st and last ones is enough. - return m.eigenvalues().cwise().abs().maxCoeff(); + return m.eigenvalues().cwiseAbs().maxCoeff(); } }; diff --git a/Eigen/src/Geometry/AlignedBox.h b/Eigen/src/Geometry/AlignedBox.h index 0a716cf31..d47adb7ab 100644 --- a/Eigen/src/Geometry/AlignedBox.h +++ b/Eigen/src/Geometry/AlignedBox.h @@ -67,7 +67,7 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) inline int dim() const { return AmbientDimAtCompileTime==Dynamic ? m_min.size()-1 : AmbientDimAtCompileTime; } /** \returns true if the box is null, i.e, empty. */ - inline bool isNull() const { return (m_min.cwise() > m_max).any(); } + inline bool isNull() const { return (m_min.array() > m_max.array()).any(); } /** Makes \c *this a null/empty box. */ inline void setNull() @@ -90,31 +90,31 @@ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,_AmbientDim) /** \returns true if the point \a p is inside the box \c *this. */ inline bool contains(const VectorType& p) const - { return (m_min.cwise()<=p).all() && (p.cwise()<=m_max).all(); } + { return (m_min.array()<=p.array()).all() && (p.array()<=m_max.array()).all(); } /** \returns true if the box \a b is entirely inside the box \c *this. */ inline bool contains(const AlignedBox& b) const - { return (m_min.cwise()<=b.min()).all() && (b.max().cwise()<=m_max).all(); } + { return (m_min.array()<=b.min().array()).all() && (b.max().array()<=m_max.array()).all(); } /** Extends \c *this such that it contains the point \a p and returns a reference to \c *this. */ inline AlignedBox& extend(const VectorType& p) - { m_min = m_min.cwise().min(p); m_max = m_max.cwise().max(p); return *this; } + { m_min = m_min.cwiseMin(p); m_max = m_max.cwiseMax(p); return *this; } /** Extends \c *this such that it contains the box \a b and returns a reference to \c *this. */ inline AlignedBox& extend(const AlignedBox& b) - { m_min = m_min.cwise().min(b.m_min); m_max = m_max.cwise().max(b.m_max); return *this; } + { m_min = m_min.cwiseMin(b.m_min); m_max = m_max.cwiseMax(b.m_max); return *this; } /** Clamps \c *this by the box \a b and returns a reference to \c *this. */ inline AlignedBox& clamp(const AlignedBox& b) - { m_min = m_min.cwise().max(b.m_min); m_max = m_max.cwise().min(b.m_max); return *this; } + { m_min = m_min.cwiseMax(b.m_min); m_max = m_max.cwiseMin(b.m_max); return *this; } /** Returns an AlignedBox that is the intersection of \a b and \c *this */ inline AlignedBox intersection(const AlignedBox &b) const - { return AlignedBox(m_min.cwise().max(b.m_min), m_max.cwise().min(b.m_max)); } + { return AlignedBox(m_min.cwiseMax(b.m_min), m_max.cwiseMin(b.m_max)); } /** Returns an AlignedBox that is the union of \a b and \c *this */ inline AlignedBox merged(const AlignedBox &b) const - { return AlignedBox(m_min.cwise().min(b.m_min), m_max.cwise().max(b.m_max)); } + { return AlignedBox(m_min.cwiseMin(b.m_min), m_max.cwiseMax(b.m_max)); } /** Translate \c *this by the vector \a t and returns a reference to \c *this. */ inline AlignedBox& translate(const VectorType& t) diff --git a/Eigen/src/Geometry/AngleAxis.h b/Eigen/src/Geometry/AngleAxis.h index 2486df0e6..da698bbfe 100644 --- a/Eigen/src/Geometry/AngleAxis.h +++ b/Eigen/src/Geometry/AngleAxis.h @@ -213,7 +213,7 @@ AngleAxis<Scalar>::toRotationMatrix(void) const res.coeffRef(1,2) = tmp - sin_axis.x(); res.coeffRef(2,1) = tmp + sin_axis.x(); - res.diagonal() = (cos1_axis.cwise() * m_axis).cwise() + c; + res.diagonal() = (cos1_axis.cwiseProduct(m_axis)).array() + c; return res; } diff --git a/Eigen/src/Geometry/Homogeneous.h b/Eigen/src/Geometry/Homogeneous.h index 229fd80b3..a601e29cf 100644 --- a/Eigen/src/Geometry/Homogeneous.h +++ b/Eigen/src/Geometry/Homogeneous.h @@ -41,8 +41,9 @@ */ template<typename MatrixType,int Direction> struct ei_traits<Homogeneous<MatrixType,Direction> > + : ei_traits<MatrixType> { - typedef typename MatrixType::Scalar Scalar; + typedef typename ei_traits<MatrixType>::StorageType StorageType; typedef typename ei_nested<MatrixType>::type MatrixTypeNested; typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested; enum { @@ -192,8 +193,8 @@ VectorwiseOp<ExpressionType,Direction>::hnormalized() const { return HNormalized_Block(_expression(),0,0, Direction==Vertical ? _expression().rows()-1 : _expression().rows(), - Direction==Horizontal ? _expression().cols()-1 : _expression().cols()).cwise()/ - Replicate<HNormalized_Factors, + Direction==Horizontal ? _expression().cols()-1 : _expression().cols()).cwiseQuotient( + Replicate<NestByValue<HNormalized_Factors>, Direction==Vertical ? HNormalized_SizeMinusOne : 1, Direction==Horizontal ? HNormalized_SizeMinusOne : 1> (HNormalized_Factors(_expression(), @@ -202,7 +203,7 @@ VectorwiseOp<ExpressionType,Direction>::hnormalized() const Direction==Vertical ? 1 : _expression().rows(), Direction==Horizontal ? 1 : _expression().cols()), Direction==Vertical ? _expression().rows()-1 : 1, - Direction==Horizontal ? _expression().cols()-1 : 1); + Direction==Horizontal ? _expression().cols()-1 : 1)); } template<typename MatrixType,typename Lhs> diff --git a/Eigen/src/Geometry/OrthoMethods.h b/Eigen/src/Geometry/OrthoMethods.h index d16b72c43..79baeadd5 100644 --- a/Eigen/src/Geometry/OrthoMethods.h +++ b/Eigen/src/Geometry/OrthoMethods.h @@ -143,7 +143,7 @@ struct ei_unitOrthogonal_selector VectorType perp = VectorType::Zero(src.size()); int maxi = 0; int sndi = 0; - src.cwise().abs().maxCoeff(&maxi); + src.cwiseAbs().maxCoeff(&maxi); if (maxi==0) sndi = 1; RealScalar invnm = RealScalar(1)/(Vector2() << src.coeff(sndi),src.coeff(maxi)).finished().norm(); diff --git a/Eigen/src/Geometry/Transform.h b/Eigen/src/Geometry/Transform.h index 363fa9dc4..89df73505 100644 --- a/Eigen/src/Geometry/Transform.h +++ b/Eigen/src/Geometry/Transform.h @@ -612,7 +612,7 @@ Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::scale(const MatrixBase<OtherDerived> &other) { EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) - linearExt() = (linearExt() * other.asDiagonal()).lazy(); + linearExt().noalias() = (linearExt() * other.asDiagonal()); return *this; } @@ -637,7 +637,7 @@ Transform<Scalar,Dim,Mode>& Transform<Scalar,Dim,Mode>::prescale(const MatrixBase<OtherDerived> &other) { EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,int(Dim)) - m_matrix.template block<Dim,HDim>(0,0) = (other.asDiagonal() * m_matrix.template block<Dim,HDim>(0,0)).lazy(); + m_matrix.template block<Dim,HDim>(0,0).noalias() = (other.asDiagonal() * m_matrix.template block<Dim,HDim>(0,0)); return *this; } @@ -1118,7 +1118,7 @@ struct ei_transform_right_product_impl<Other,Mode, Dim,HDim, Dim,Dim> { TransformType res; res.matrix().col(Dim) = tr.matrix().col(Dim); - res.linearExt() = (tr.linearExt() * other).lazy(); + res.linearExt().noalias() = (tr.linearExt() * other); if(Mode==Affine) res.matrix().row(Dim).template start<Dim>() = tr.matrix().row(Dim).template start<Dim>(); return res; @@ -1136,7 +1136,7 @@ struct ei_transform_right_product_impl<Other,Mode, Dim,HDim, Dim,HDim> { TransformType res; const int Rows = Mode==Projective ? HDim : Dim; - res.matrix().template block<Rows,HDim>(0,0) = (tr.linearExt() * other).lazy(); + res.matrix().template block<Rows,HDim>(0,0).noalias() = (tr.linearExt() * other); res.translationExt() += tr.translationExt(); if(Mode!=Affine) res.makeAffine(); @@ -1152,7 +1152,7 @@ struct ei_transform_right_product_impl<Other,Mode, Dim,HDim, HDim,HDim> typedef typename TransformType::MatrixType MatrixType; typedef Transform<typename Other::Scalar,Dim,Projective> ResultType; static ResultType run(const TransformType& tr, const Other& other) - { return ResultType((tr.matrix() * other).lazy()); } + { return ResultType(tr.matrix() * other); } }; // AffineCompact * generic matrix => Projective @@ -1164,7 +1164,7 @@ struct ei_transform_right_product_impl<Other,AffineCompact, Dim,HDim, HDim,HDim> static ResultType run(const TransformType& tr, const Other& other) { ResultType res; - res.affine() = (tr.matrix() * other).lazy(); + res.affine().noalias() = tr.matrix() * other; res.makeAffine(); return res; } @@ -1179,7 +1179,7 @@ struct ei_transform_left_product_impl<Other,Mode,Dim,HDim, HDim,HDim> typedef typename TransformType::MatrixType MatrixType; typedef Transform<typename Other::Scalar,Dim,Projective> ResultType; static ResultType run(const Other& other,const TransformType& tr) - { return ResultType((other * tr.matrix()).lazy()); } + { return ResultType(other * tr.matrix()); } }; // generic HDim x HDim matrix * AffineCompact => Projective @@ -1192,7 +1192,7 @@ struct ei_transform_left_product_impl<Other,AffineCompact,Dim,HDim, HDim,HDim> static ResultType run(const Other& other,const TransformType& tr) { ResultType res; - res.matrix() = (other.template block<HDim,Dim>(0,0) * tr.matrix()).lazy(); + res.matrix().noalias() = other.template block<HDim,Dim>(0,0) * tr.matrix(); res.matrix().col(Dim) += other.col(Dim); return res; } @@ -1208,7 +1208,7 @@ struct ei_transform_left_product_impl<Other,Mode,Dim,HDim, Dim,HDim> static ResultType run(const Other& other,const TransformType& tr) { ResultType res; - res.affine() = (other * tr.matrix()).lazy(); + res.affine().noalias() = other * tr.matrix(); res.matrix().row(Dim) = tr.matrix().row(Dim); return res; } @@ -1224,7 +1224,7 @@ struct ei_transform_left_product_impl<Other,AffineCompact,Dim,HDim, Dim,HDim> static ResultType run(const Other& other,const TransformType& tr) { ResultType res; - res.matrix() = (other.template block<Dim,Dim>(0,0) * tr.matrix()).lazy(); + res.matrix().noalias() = other.template block<Dim,Dim>(0,0) * tr.matrix(); res.translation() += other.col(Dim); return res; } @@ -1242,8 +1242,8 @@ struct ei_transform_left_product_impl<Other,Mode,Dim,HDim, Dim,Dim> TransformType res; if(Mode!=AffineCompact) res.matrix().row(Dim) = tr.matrix().row(Dim); - res.matrix().template corner<Dim,HDim>(TopLeft) - = (other * tr.matrix().template corner<Dim,HDim>(TopLeft)).lazy(); + res.matrix().template corner<Dim,HDim>(TopLeft).noalias() + = other * tr.matrix().template corner<Dim,HDim>(TopLeft); return res; } }; @@ -1259,7 +1259,7 @@ struct ei_transform_transform_product_impl<Transform<Scalar,Dim,Mode>,Transform< typedef TransformType ResultType; static ResultType run(const TransformType& lhs, const TransformType& rhs) { - return ResultType((lhs.matrix() * rhs.matrix()).lazy()); + return ResultType(lhs.matrix() * rhs.matrix()); } }; @@ -1297,7 +1297,7 @@ struct ei_transform_transform_product_impl<Transform<Scalar,Dim,AffineCompact>, typedef Transform<Scalar,Dim,AffineCompact> ResultType; static ResultType run(const Lhs& lhs, const Rhs& rhs) { - return ResultType((lhs.matrix() * rhs.matrix()).lazy()); + return ResultType(lhs.matrix() * rhs.matrix()); } }; diff --git a/Eigen/src/Householder/Householder.h b/Eigen/src/Householder/Householder.h index a54be8c01..1e549633a 100644 --- a/Eigen/src/Householder/Householder.h +++ b/Eigen/src/Householder/Householder.h @@ -102,8 +102,8 @@ void MatrixBase<Derived>::applyHouseholderOnTheLeft( Map<Matrix<Scalar, 1, ColsAtCompileTime, PlainMatrixType::Options, 1, MaxColsAtCompileTime> > tmp(workspace,cols()); Block<Derived, EssentialPart::SizeAtCompileTime, Derived::ColsAtCompileTime> bottom(derived(), 1, 0, rows()-1, cols()); tmp.noalias() = essential.adjoint() * bottom; - tmp += row(0); - row(0) -= tau * tmp; + tmp += this->row(0); + this->row(0) -= tau * tmp; bottom.noalias() -= tau * essential * tmp; } @@ -117,8 +117,8 @@ void MatrixBase<Derived>::applyHouseholderOnTheRight( Map<Matrix<Scalar, RowsAtCompileTime, 1, PlainMatrixType::Options, MaxRowsAtCompileTime, 1> > tmp(workspace,rows()); Block<Derived, Derived::RowsAtCompileTime, EssentialPart::SizeAtCompileTime> right(derived(), 0, 1, rows(), cols()-1); tmp.noalias() = right * essential.conjugate(); - tmp += col(0); - col(0) -= tau * tmp; + tmp += this->col(0); + this->col(0) -= tau * tmp; right.noalias() -= tau * tmp * essential.transpose(); } diff --git a/Eigen/src/Jacobi/Jacobi.h b/Eigen/src/Jacobi/Jacobi.h index eeb81c178..727c97583 100644 --- a/Eigen/src/Jacobi/Jacobi.h +++ b/Eigen/src/Jacobi/Jacobi.h @@ -279,8 +279,8 @@ template<typename Derived> template<typename OtherScalar> inline void MatrixBase<Derived>::applyOnTheLeft(int p, int q, const PlanarRotation<OtherScalar>& j) { - RowXpr x(row(p)); - RowXpr y(row(q)); + RowXpr x(this->row(p)); + RowXpr y(this->row(q)); ei_apply_rotation_in_the_plane(x, y, j); } @@ -294,8 +294,8 @@ template<typename Derived> template<typename OtherScalar> inline void MatrixBase<Derived>::applyOnTheRight(int p, int q, const PlanarRotation<OtherScalar>& j) { - ColXpr x(col(p)); - ColXpr y(col(q)); + ColXpr x(this->col(p)); + ColXpr y(this->col(q)); ei_apply_rotation_in_the_plane(x, y, j.transpose()); } diff --git a/Eigen/src/LU/FullPivLU.h b/Eigen/src/LU/FullPivLU.h index 1358c9490..149af64bc 100644 --- a/Eigen/src/LU/FullPivLU.h +++ b/Eigen/src/LU/FullPivLU.h @@ -14,7 +14,7 @@ // 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 +// // 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. // @@ -89,7 +89,7 @@ template<typename _MatrixType> class FullPivLU * \returns a reference to *this */ FullPivLU& compute(const MatrixType& matrix); - + /** \returns the LU decomposition matrix: the upper-triangular part is U, the * unit-lower-triangular part is L (at least for square matrices; in the non-square * case, special care is needed, see the documentation of class FullPivLU). @@ -101,7 +101,7 @@ template<typename _MatrixType> class FullPivLU ei_assert(m_isInitialized && "LU is not initialized."); return m_lu; } - + /** \returns the number of nonzero pivots in the LU decomposition. * Here nonzero is meant in the exact sense, not in a fuzzy sense. * So that notion isn't really intrinsically interesting, but it is @@ -114,7 +114,7 @@ template<typename _MatrixType> class FullPivLU ei_assert(m_isInitialized && "LU is not initialized."); return m_nonzero_pivots; } - + /** \returns the absolute value of the biggest pivot, i.e. the biggest * diagonal coefficient of U. */ @@ -252,7 +252,7 @@ template<typename _MatrixType> class FullPivLU m_usePrescribedThreshold = true; m_prescribedThreshold = threshold; } - + /** Allows to come back to the default behavior, letting Eigen use its default formula for * determining the threshold. * @@ -265,7 +265,7 @@ template<typename _MatrixType> class FullPivLU { m_usePrescribedThreshold = false; } - + /** Returns the threshold that will be used by certain methods such as rank(). * * See the documentation of setThreshold(const RealScalar&). @@ -278,7 +278,7 @@ template<typename _MatrixType> class FullPivLU // and turns out to be identical to Higham's formula used already in LDLt. : epsilon<Scalar>() * m_lu.diagonalSize(); } - + /** \returns the rank of the matrix of which *this is the LU decomposition. * * \note This method has to determine which pivots should be considered nonzero. @@ -294,7 +294,7 @@ template<typename _MatrixType> class FullPivLU result += (ei_abs(m_lu.coeff(i,i)) > premultiplied_threshold); return result; } - + /** \returns the dimension of the kernel of the matrix of which *this is the LU decomposition. * * \note This method has to determine which pivots should be considered nonzero. @@ -362,7 +362,7 @@ template<typename _MatrixType> class FullPivLU inline int rows() const { return m_lu.rows(); } inline int cols() const { return m_lu.cols(); } - + protected: MatrixType m_lu; PermutationPType m_p; @@ -412,7 +412,7 @@ FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix) int row_of_biggest_in_corner, col_of_biggest_in_corner; RealScalar biggest_in_corner; biggest_in_corner = m_lu.corner(Eigen::BottomRight, rows-k, cols-k) - .cwise().abs() + .cwiseAbs() .maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner); row_of_biggest_in_corner += k; // correct the values! since they were computed in the corner, col_of_biggest_in_corner += k; // need to add k to them. @@ -449,7 +449,7 @@ FullPivLU<MatrixType>& FullPivLU<MatrixType>::compute(const MatrixType& matrix) // Now that the pivot is at the right location, we update the remaining // bottom-right corner by Gaussian elimination. - + if(k<rows-1) m_lu.col(k).end(rows-k-1) /= m_lu.coeff(k,k); if(k<size-1) @@ -503,7 +503,7 @@ struct ei_kernel_retval<FullPivLU<_MatrixType> > dst.setZero(); return; } - + /* Let us use the following lemma: * * Lemma: If the matrix A has the LU decomposition PAQ = LU, @@ -571,7 +571,7 @@ struct ei_image_retval<FullPivLU<_MatrixType> > : ei_image_retval_base<FullPivLU<_MatrixType> > { EIGEN_MAKE_IMAGE_HELPERS(FullPivLU<_MatrixType>) - + enum { MaxSmallDimAtCompileTime = EIGEN_ENUM_MIN( MatrixType::MaxColsAtCompileTime, MatrixType::MaxRowsAtCompileTime) @@ -587,7 +587,7 @@ struct ei_image_retval<FullPivLU<_MatrixType> > dst.setZero(); return; } - + Matrix<int, Dynamic, 1, 0, MaxSmallDimAtCompileTime, 1> pivots(rank()); RealScalar premultiplied_threshold = dec().maxPivot() * dec().threshold(); int p = 0; @@ -608,7 +608,7 @@ struct ei_solve_retval<FullPivLU<_MatrixType>, Rhs> : ei_solve_retval_base<FullPivLU<_MatrixType>, Rhs> { EIGEN_MAKE_SOLVE_HELPERS(FullPivLU<_MatrixType>,Rhs) - + template<typename Dest> void evalTo(Dest& dst) const { /* The decomposition PAQ = LU can be rewritten as A = P^{-1} L U Q^{-1}. diff --git a/Eigen/src/LU/Inverse.h b/Eigen/src/LU/Inverse.h index 91d02164c..ea2330da3 100644 --- a/Eigen/src/LU/Inverse.h +++ b/Eigen/src/LU/Inverse.h @@ -148,7 +148,7 @@ struct ei_compute_inverse<MatrixType, ResultType, 3> cofactors_col0.coeffRef(0) = matrix.minor(0,0).determinant(); cofactors_col0.coeffRef(1) = -matrix.minor(1,0).determinant(); cofactors_col0.coeffRef(2) = matrix.minor(2,0).determinant(); - const Scalar det = (cofactors_col0.cwise()*matrix.col(0)).sum(); + const Scalar det = (cofactors_col0.cwiseProduct(matrix.col(0))).sum(); const Scalar invdet = Scalar(1) / det; ei_compute_inverse_size3_helper(matrix, invdet, cofactors_col0, result); } @@ -170,7 +170,7 @@ struct ei_compute_inverse_and_det_with_check<MatrixType, ResultType, 3> cofactors_col0.coeffRef(0) = matrix.minor(0,0).determinant(); cofactors_col0.coeffRef(1) = -matrix.minor(1,0).determinant(); cofactors_col0.coeffRef(2) = matrix.minor(2,0).determinant(); - determinant = (cofactors_col0.cwise()*matrix.col(0)).sum(); + determinant = (cofactors_col0.cwiseProduct(matrix.col(0))).sum(); invertible = ei_abs(determinant) > absDeterminantThreshold; if(!invertible) return; const Scalar invdet = Scalar(1) / determinant; @@ -212,6 +212,7 @@ struct ei_compute_inverse<MatrixType, ResultType, 4> : ei_compute_inverse_size4<Architecture::Target, typename MatrixType::Scalar, MatrixType, ResultType> { + // FIXME empty? }; template<typename MatrixType, typename ResultType> diff --git a/Eigen/src/LU/PartialPivLU.h b/Eigen/src/LU/PartialPivLU.h index 577daa345..deb29b5c6 100644 --- a/Eigen/src/LU/PartialPivLU.h +++ b/Eigen/src/LU/PartialPivLU.h @@ -229,7 +229,7 @@ struct ei_partial_lu_impl { int row_of_biggest_in_col; RealScalar biggest_in_corner - = lu.col(k).end(rows-k).cwise().abs().maxCoeff(&row_of_biggest_in_col); + = lu.col(k).end(rows-k).cwiseAbs().maxCoeff(&row_of_biggest_in_col); row_of_biggest_in_col += k; if(biggest_in_corner == 0) // the pivot is exactly zero: the matrix is singular @@ -351,7 +351,7 @@ struct ei_partial_lu_impl // A12 = A11^-1 A12 A11.template triangularView<UnitLowerTriangular>().solveInPlace(A12); - A22 -= A21 * A12; + A22.noalias() -= A21 * A12; } } return true; @@ -407,7 +407,7 @@ struct ei_solve_retval<PartialPivLU<_MatrixType>, Rhs> : ei_solve_retval_base<PartialPivLU<_MatrixType>, Rhs> { EIGEN_MAKE_SOLVE_HELPERS(PartialPivLU<_MatrixType>,Rhs) - + template<typename Dest> void evalTo(Dest& dst) const { /* The decomposition PA = LU can be rewritten as A = P^{-1} L U. @@ -416,7 +416,7 @@ struct ei_solve_retval<PartialPivLU<_MatrixType>, Rhs> * Step 2: replace c by the solution x to Lx = c. * Step 3: replace c by the solution x to Ux = c. */ - + const int size = dec().matrixLU().rows(); ei_assert(rhs().rows() == size); diff --git a/Eigen/src/LeastSquares/LeastSquares.h b/Eigen/src/LeastSquares/LeastSquares.h index ab0c0c49c..e0e9af1bc 100644 --- a/Eigen/src/LeastSquares/LeastSquares.h +++ b/Eigen/src/LeastSquares/LeastSquares.h @@ -174,7 +174,7 @@ void fitHyperplane(int numPoints, // let's compute the constant coefficient such that the // plane pass trough the mean point: - result->offset() = - (result->normal().cwise()* mean).sum(); + result->offset() = - (result->normal().cwiseProduct(mean)).sum(); } diff --git a/Eigen/src/QR/ColPivHouseholderQR.h b/Eigen/src/QR/ColPivHouseholderQR.h index 1b2472a99..b4c1a5fcc 100644 --- a/Eigen/src/QR/ColPivHouseholderQR.h +++ b/Eigen/src/QR/ColPivHouseholderQR.h @@ -328,7 +328,7 @@ typename MatrixType::RealScalar ColPivHouseholderQR<MatrixType>::logAbsDetermina { ei_assert(m_isInitialized && "ColPivHouseholderQR is not initialized."); ei_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!"); - return m_qr.diagonal().cwise().abs().cwise().log().sum(); + return m_qr.diagonal().cwiseAbs().array().log().sum(); } template<typename MatrixType> @@ -409,7 +409,7 @@ ColPivHouseholderQR<MatrixType>& ColPivHouseholderQR<MatrixType>::compute(const .applyHouseholderOnTheLeft(m_qr.col(k).end(rows-k-1), m_hCoeffs.coeffRef(k), &temp.coeffRef(k+1)); // update our table of squared norms of the columns - colSqNorms.end(cols-k-1) -= m_qr.row(k).end(cols-k-1).cwise().abs2(); + colSqNorms.end(cols-k-1) -= m_qr.row(k).end(cols-k-1).cwiseAbs2(); } m_cols_permutation.setIdentity(cols); diff --git a/Eigen/src/QR/FullPivHouseholderQR.h b/Eigen/src/QR/FullPivHouseholderQR.h index ae4e4aa4d..51609ca1a 100644 --- a/Eigen/src/QR/FullPivHouseholderQR.h +++ b/Eigen/src/QR/FullPivHouseholderQR.h @@ -254,7 +254,7 @@ typename MatrixType::RealScalar FullPivHouseholderQR<MatrixType>::logAbsDetermin { ei_assert(m_isInitialized && "FullPivHouseholderQR is not initialized."); ei_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!"); - return m_qr.diagonal().cwise().abs().cwise().log().sum(); + return m_qr.diagonal().cwiseAbs().array().log().sum(); } template<typename MatrixType> @@ -284,7 +284,7 @@ FullPivHouseholderQR<MatrixType>& FullPivHouseholderQR<MatrixType>::compute(cons RealScalar biggest_in_corner; biggest_in_corner = m_qr.corner(Eigen::BottomRight, rows-k, cols-k) - .cwise().abs() + .cwiseAbs() .maxCoeff(&row_of_biggest_in_corner, &col_of_biggest_in_corner); row_of_biggest_in_corner += k; col_of_biggest_in_corner += k; @@ -367,8 +367,8 @@ struct ei_solve_retval<FullPivHouseholderQR<_MatrixType>, Rhs> if(!dec().isSurjective()) { // is c is in the image of R ? - RealScalar biggest_in_upper_part_of_c = c.corner(TopLeft, dec().rank(), c.cols()).cwise().abs().maxCoeff(); - RealScalar biggest_in_lower_part_of_c = c.corner(BottomLeft, rows-dec().rank(), c.cols()).cwise().abs().maxCoeff(); + RealScalar biggest_in_upper_part_of_c = c.corner(TopLeft, dec().rank(), c.cols()).cwiseAbs().maxCoeff(); + RealScalar biggest_in_lower_part_of_c = c.corner(BottomLeft, rows-dec().rank(), c.cols()).cwiseAbs().maxCoeff(); // FIXME brain dead const RealScalar m_precision = epsilon<Scalar>() * std::min(rows,cols); if(!ei_isMuchSmallerThan(biggest_in_lower_part_of_c, biggest_in_upper_part_of_c, m_precision)) diff --git a/Eigen/src/QR/HouseholderQR.h b/Eigen/src/QR/HouseholderQR.h index 95496b943..895ae046a 100644 --- a/Eigen/src/QR/HouseholderQR.h +++ b/Eigen/src/QR/HouseholderQR.h @@ -176,7 +176,7 @@ typename MatrixType::RealScalar HouseholderQR<MatrixType>::logAbsDeterminant() c { ei_assert(m_isInitialized && "HouseholderQR is not initialized."); ei_assert(m_qr.rows() == m_qr.cols() && "You can't take the determinant of a non-square matrix!"); - return m_qr.diagonal().cwise().abs().cwise().log().sum(); + return m_qr.diagonal().cwiseAbs().array().log().sum(); } template<typename MatrixType> diff --git a/Eigen/src/SVD/SVD.h b/Eigen/src/SVD/SVD.h index 0ec41e36d..7a8e4f312 100644 --- a/Eigen/src/SVD/SVD.h +++ b/Eigen/src/SVD/SVD.h @@ -205,7 +205,7 @@ SVD<MatrixType>& SVD<MatrixType>::compute(const MatrixType& matrix) g = s = scale = 0.0; if (i < m) { - scale = A.col(i).end(m-i).cwise().abs().sum(); + scale = A.col(i).end(m-i).cwiseAbs().sum(); if (scale != Scalar(0)) { for (k=i; k<m; k++) @@ -230,7 +230,7 @@ SVD<MatrixType>& SVD<MatrixType>::compute(const MatrixType& matrix) g = s = scale = 0.0; if (i+1 <= m && i+1 != n) { - scale = A.row(i).end(n-l+1).cwise().abs().sum(); + scale = A.row(i).end(n-l+1).cwiseAbs().sum(); if (scale != Scalar(0)) { for (k=l-1; k<n; k++) diff --git a/Eigen/src/Sparse/DynamicSparseMatrix.h b/Eigen/src/Sparse/DynamicSparseMatrix.h index 3ce5e84da..4373e1cda 100644 --- a/Eigen/src/Sparse/DynamicSparseMatrix.h +++ b/Eigen/src/Sparse/DynamicSparseMatrix.h @@ -46,12 +46,13 @@ template<typename _Scalar, int _Flags> struct ei_traits<DynamicSparseMatrix<_Scalar, _Flags> > { typedef _Scalar Scalar; + typedef Sparse StorageType; enum { RowsAtCompileTime = Dynamic, ColsAtCompileTime = Dynamic, MaxRowsAtCompileTime = Dynamic, MaxColsAtCompileTime = Dynamic, - Flags = SparseBit | _Flags, + Flags = _Flags, CoeffReadCost = NumTraits<Scalar>::ReadCost, SupportedAccessPatterns = OuterRandomAccessPattern }; diff --git a/Eigen/src/Sparse/SparseBlock.h b/Eigen/src/Sparse/SparseBlock.h index 6659a88e2..7f2e05c4d 100644 --- a/Eigen/src/Sparse/SparseBlock.h +++ b/Eigen/src/Sparse/SparseBlock.h @@ -30,6 +30,7 @@ template<typename MatrixType, int Size> struct ei_traits<SparseInnerVectorSet<MatrixType, Size> > { typedef typename ei_traits<MatrixType>::Scalar Scalar; + typedef typename ei_traits<MatrixType>::StorageType StorageType; enum { IsRowMajor = (int(MatrixType::Flags)&RowMajorBit)==RowMajorBit, Flags = MatrixType::Flags, diff --git a/Eigen/src/Sparse/SparseCwise.h b/Eigen/src/Sparse/SparseCwise.h deleted file mode 100644 index bf8f2355c..000000000 --- a/Eigen/src/Sparse/SparseCwise.h +++ /dev/null @@ -1,175 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> -// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> -// -// 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_SPARSE_CWISE_H -#define EIGEN_SPARSE_CWISE_H - -/** \internal - * convenient macro to defined the return type of a cwise binary operation */ -#define EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(OP) \ - CwiseBinaryOp<OP<typename ei_traits<ExpressionType>::Scalar>, ExpressionType, OtherDerived> - -#define EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE \ - SparseCwiseBinaryOp< \ - ei_scalar_product_op< \ - typename ei_scalar_product_traits< \ - typename ei_traits<ExpressionType>::Scalar, \ - typename ei_traits<OtherDerived>::Scalar \ - >::ReturnType \ - >, \ - ExpressionType, \ - OtherDerived \ - > - -/** \internal - * convenient macro to defined the return type of a cwise unary operation */ -#define EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(OP) \ - SparseCwiseUnaryOp<OP<typename ei_traits<ExpressionType>::Scalar>, ExpressionType> - -/** \internal - * convenient macro to defined the return type of a cwise comparison to a scalar */ -/*#define EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(OP) \ - CwiseBinaryOp<OP<typename ei_traits<ExpressionType>::Scalar>, ExpressionType, \ - typename ExpressionType::ConstantReturnType >*/ - -template<typename ExpressionType> class SparseCwise -{ - public: - - typedef typename ei_traits<ExpressionType>::Scalar Scalar; - typedef typename ei_meta_if<ei_must_nest_by_value<ExpressionType>::ret, - ExpressionType, const ExpressionType&>::ret ExpressionTypeNested; - typedef CwiseUnaryOp<ei_scalar_add_op<Scalar>, ExpressionType> ScalarAddReturnType; - - inline SparseCwise(const ExpressionType& matrix) : m_matrix(matrix) {} - - /** \internal */ - inline const ExpressionType& _expression() const { return m_matrix; } - - template<typename OtherDerived> - const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE - operator*(const SparseMatrixBase<OtherDerived> &other) const; - - template<typename OtherDerived> - const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE - operator*(const MatrixBase<OtherDerived> &other) const; - -// template<typename OtherDerived> -// const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op) -// operator/(const SparseMatrixBase<OtherDerived> &other) const; -// -// template<typename OtherDerived> -// const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op) -// operator/(const MatrixBase<OtherDerived> &other) const; - - template<typename OtherDerived> - const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op) - min(const SparseMatrixBase<OtherDerived> &other) const; - - template<typename OtherDerived> - const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op) - max(const SparseMatrixBase<OtherDerived> &other) const; - - const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs_op) abs() const; - const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs2_op) abs2() const; -// const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_square_op) square() const; -// const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_cube_op) cube() const; -// const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_inverse_op) inverse() const; -// const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_sqrt_op) sqrt() const; -// const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_exp_op) exp() const; -// const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_log_op) log() const; -// const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_cos_op) cos() const; -// const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_sin_op) sin() const; -// const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_pow_op) pow(const Scalar& exponent) const; - - template<typename OtherDerived> - inline ExpressionType& operator*=(const SparseMatrixBase<OtherDerived> &other); - -// template<typename OtherDerived> -// inline ExpressionType& operator/=(const SparseMatrixBase<OtherDerived> &other); - - /* - template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::less) - operator<(const MatrixBase<OtherDerived>& other) const; - - template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::less_equal) - operator<=(const MatrixBase<OtherDerived>& other) const; - - template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater) - operator>(const MatrixBase<OtherDerived>& other) const; - - template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::greater_equal) - operator>=(const MatrixBase<OtherDerived>& other) const; - - template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::equal_to) - operator==(const MatrixBase<OtherDerived>& other) const; - - template<typename OtherDerived> const EIGEN_CWISE_BINOP_RETURN_TYPE(std::not_equal_to) - operator!=(const MatrixBase<OtherDerived>& other) const; - - // comparisons to a scalar value - const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less) - operator<(Scalar s) const; - - const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less_equal) - operator<=(Scalar s) const; - - const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater) - operator>(Scalar s) const; - - const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater_equal) - operator>=(Scalar s) const; - - const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::equal_to) - operator==(Scalar s) const; - - const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::not_equal_to) - operator!=(Scalar s) const; - */ - - // allow to extend SparseCwise outside Eigen - #ifdef EIGEN_SPARSE_CWISE_PLUGIN - #include EIGEN_SPARSE_CWISE_PLUGIN - #endif - - protected: - ExpressionTypeNested m_matrix; -}; - -template<typename Derived> -inline const SparseCwise<Derived> -SparseMatrixBase<Derived>::cwise() const -{ - return derived(); -} - -template<typename Derived> -inline SparseCwise<Derived> -SparseMatrixBase<Derived>::cwise() -{ - return derived(); -} - -#endif // EIGEN_SPARSE_CWISE_H diff --git a/Eigen/src/Sparse/SparseCwiseBinaryOp.h b/Eigen/src/Sparse/SparseCwiseBinaryOp.h index 2dcd6b944..4f8221787 100644 --- a/Eigen/src/Sparse/SparseCwiseBinaryOp.h +++ b/Eigen/src/Sparse/SparseCwiseBinaryOp.h @@ -42,89 +42,37 @@ // 4 - dense op dense product dense // generic dense -template<typename BinaryOp, typename Lhs, typename Rhs> -struct ei_traits<SparseCwiseBinaryOp<BinaryOp, Lhs, Rhs> > -{ - typedef typename ei_result_of< - BinaryOp( - typename Lhs::Scalar, - typename Rhs::Scalar - ) - >::type Scalar; - typedef typename Lhs::Nested LhsNested; - typedef typename Rhs::Nested RhsNested; - typedef typename ei_unref<LhsNested>::type _LhsNested; - typedef typename ei_unref<RhsNested>::type _RhsNested; - enum { - LhsCoeffReadCost = _LhsNested::CoeffReadCost, - RhsCoeffReadCost = _RhsNested::CoeffReadCost, - LhsFlags = _LhsNested::Flags, - RhsFlags = _RhsNested::Flags, - RowsAtCompileTime = Lhs::RowsAtCompileTime, - ColsAtCompileTime = Lhs::ColsAtCompileTime, - MaxRowsAtCompileTime = Lhs::MaxRowsAtCompileTime, - MaxColsAtCompileTime = Lhs::MaxColsAtCompileTime, - Flags = (int(LhsFlags) | int(RhsFlags)) & HereditaryBits, - CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + ei_functor_traits<BinaryOp>::Cost - }; -}; +template<> struct ei_promote_storage_type<Dense,Sparse> +{ typedef Sparse ret; }; + +template<> struct ei_promote_storage_type<Sparse,Dense> +{ typedef Sparse ret; }; template<typename BinaryOp, typename Lhs, typename Rhs> -class SparseCwiseBinaryOp : ei_no_assignment_operator, - public SparseMatrixBase<SparseCwiseBinaryOp<BinaryOp, Lhs, Rhs> > +class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Sparse> + : public SparseMatrixBase<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > { public: - class InnerIterator; - - EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseCwiseBinaryOp) - typedef typename ei_traits<SparseCwiseBinaryOp>::LhsNested LhsNested; - typedef typename ei_traits<SparseCwiseBinaryOp>::RhsNested RhsNested; - typedef typename ei_unref<LhsNested>::type _LhsNested; - typedef typename ei_unref<RhsNested>::type _RhsNested; - - EIGEN_STRONG_INLINE SparseCwiseBinaryOp(const Lhs& lhs, const Rhs& rhs, const BinaryOp& func = BinaryOp()) - : m_lhs(lhs), m_rhs(rhs), m_functor(func) - { - EIGEN_STATIC_ASSERT((_LhsNested::Flags&RowMajorBit)==(_RhsNested::Flags&RowMajorBit), - BOTH_MATRICES_MUST_HAVE_THE_SAME_STORAGE_ORDER) - EIGEN_STATIC_ASSERT((ei_functor_allows_mixing_real_and_complex<BinaryOp>::ret - ? int(ei_is_same_type<typename Lhs::RealScalar, typename Rhs::RealScalar>::ret) - : int(ei_is_same_type<typename Lhs::Scalar, typename Rhs::Scalar>::ret)), - YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY) - // require the sizes to match - EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Lhs, Rhs) - ei_assert(lhs.rows() == rhs.rows() && lhs.cols() == rhs.cols()); - } - - EIGEN_STRONG_INLINE int rows() const { return m_lhs.rows(); } - EIGEN_STRONG_INLINE int cols() const { return m_lhs.cols(); } - - EIGEN_STRONG_INLINE const _LhsNested& lhs() const { return m_lhs; } - EIGEN_STRONG_INLINE const _RhsNested& rhs() const { return m_rhs; } - EIGEN_STRONG_INLINE const BinaryOp& functor() const { return m_functor; } - - protected: - const LhsNested m_lhs; - const RhsNested m_rhs; - const BinaryOp m_functor; + typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> Derived; + EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) }; template<typename BinaryOp, typename Lhs, typename Rhs, typename Derived, - int _LhsStorageMode = int(Lhs::Flags) & SparseBit, - int _RhsStorageMode = int(Rhs::Flags) & SparseBit> + typename _LhsStorageMode = typename ei_traits<Lhs>::StorageType, + typename _RhsStorageMode = typename ei_traits<Rhs>::StorageType> class ei_sparse_cwise_binary_op_inner_iterator_selector; template<typename BinaryOp, typename Lhs, typename Rhs> -class SparseCwiseBinaryOp<BinaryOp,Lhs,Rhs>::InnerIterator - : public ei_sparse_cwise_binary_op_inner_iterator_selector<BinaryOp,Lhs,Rhs, typename SparseCwiseBinaryOp<BinaryOp,Lhs,Rhs>::InnerIterator> +class CwiseBinaryOpImpl<BinaryOp,Lhs,Rhs,Sparse>::InnerIterator + : public ei_sparse_cwise_binary_op_inner_iterator_selector<BinaryOp,Lhs,Rhs,typename CwiseBinaryOpImpl<BinaryOp,Lhs,Rhs,Sparse>::InnerIterator> { public: typedef ei_sparse_cwise_binary_op_inner_iterator_selector< BinaryOp,Lhs,Rhs, InnerIterator> Base; - EIGEN_STRONG_INLINE InnerIterator(const SparseCwiseBinaryOp& binOp, int outer) - : Base(binOp,outer) + EIGEN_STRONG_INLINE InnerIterator(const CwiseBinaryOpImpl& binOp, int outer) + : Base(binOp.derived(),outer) {} }; @@ -139,9 +87,9 @@ class SparseCwiseBinaryOp<BinaryOp,Lhs,Rhs>::InnerIterator // sparse - sparse (generic) template<typename BinaryOp, typename Lhs, typename Rhs, typename Derived> -class ei_sparse_cwise_binary_op_inner_iterator_selector<BinaryOp, Lhs, Rhs, Derived, IsSparse, IsSparse> +class ei_sparse_cwise_binary_op_inner_iterator_selector<BinaryOp, Lhs, Rhs, Derived, Sparse, Sparse> { - typedef SparseCwiseBinaryOp<BinaryOp, Lhs, Rhs> CwiseBinaryXpr; + typedef CwiseBinaryOp<BinaryOp, Lhs, Rhs> CwiseBinaryXpr; typedef typename ei_traits<CwiseBinaryXpr>::Scalar Scalar; typedef typename ei_traits<CwiseBinaryXpr>::_LhsNested _LhsNested; typedef typename ei_traits<CwiseBinaryXpr>::_RhsNested _RhsNested; @@ -201,10 +149,10 @@ class ei_sparse_cwise_binary_op_inner_iterator_selector<BinaryOp, Lhs, Rhs, Deri // sparse - sparse (product) template<typename T, typename Lhs, typename Rhs, typename Derived> -class ei_sparse_cwise_binary_op_inner_iterator_selector<ei_scalar_product_op<T>, Lhs, Rhs, Derived, IsSparse, IsSparse> +class ei_sparse_cwise_binary_op_inner_iterator_selector<ei_scalar_product_op<T>, Lhs, Rhs, Derived, Sparse, Sparse> { typedef ei_scalar_product_op<T> BinaryFunc; - typedef SparseCwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr; + typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr; typedef typename CwiseBinaryXpr::Scalar Scalar; typedef typename ei_traits<CwiseBinaryXpr>::_LhsNested _LhsNested; typedef typename _LhsNested::InnerIterator LhsIterator; @@ -254,10 +202,10 @@ class ei_sparse_cwise_binary_op_inner_iterator_selector<ei_scalar_product_op<T>, // sparse - dense (product) template<typename T, typename Lhs, typename Rhs, typename Derived> -class ei_sparse_cwise_binary_op_inner_iterator_selector<ei_scalar_product_op<T>, Lhs, Rhs, Derived, IsSparse, IsDense> +class ei_sparse_cwise_binary_op_inner_iterator_selector<ei_scalar_product_op<T>, Lhs, Rhs, Derived, Sparse, Dense> { typedef ei_scalar_product_op<T> BinaryFunc; - typedef SparseCwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr; + typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr; typedef typename CwiseBinaryXpr::Scalar Scalar; typedef typename ei_traits<CwiseBinaryXpr>::_LhsNested _LhsNested; typedef typename ei_traits<CwiseBinaryXpr>::RhsNested RhsNested; @@ -294,10 +242,10 @@ class ei_sparse_cwise_binary_op_inner_iterator_selector<ei_scalar_product_op<T>, // sparse - dense (product) template<typename T, typename Lhs, typename Rhs, typename Derived> -class ei_sparse_cwise_binary_op_inner_iterator_selector<ei_scalar_product_op<T>, Lhs, Rhs, Derived, IsDense, IsSparse> +class ei_sparse_cwise_binary_op_inner_iterator_selector<ei_scalar_product_op<T>, Lhs, Rhs, Derived, Dense, Sparse> { typedef ei_scalar_product_op<T> BinaryFunc; - typedef SparseCwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr; + typedef CwiseBinaryOp<BinaryFunc, Lhs, Rhs> CwiseBinaryXpr; typedef typename CwiseBinaryXpr::Scalar Scalar; typedef typename ei_traits<CwiseBinaryXpr>::_RhsNested _RhsNested; typedef typename _RhsNested::InnerIterator RhsIterator; @@ -335,15 +283,15 @@ class ei_sparse_cwise_binary_op_inner_iterator_selector<ei_scalar_product_op<T>, * Implementation of SparseMatrixBase and SparseCwise functions/operators ***************************************************************************/ -template<typename Derived> -template<typename OtherDerived> -EIGEN_STRONG_INLINE const SparseCwiseBinaryOp<ei_scalar_difference_op<typename ei_traits<Derived>::Scalar>, - Derived, OtherDerived> -SparseMatrixBase<Derived>::operator-(const SparseMatrixBase<OtherDerived> &other) const -{ - return SparseCwiseBinaryOp<ei_scalar_difference_op<Scalar>, - Derived, OtherDerived>(derived(), other.derived()); -} +// template<typename Derived> +// template<typename OtherDerived> +// EIGEN_STRONG_INLINE const CwiseBinaryOp<ei_scalar_difference_op<typename ei_traits<Derived>::Scalar>, +// Derived, OtherDerived> +// SparseMatrixBase<Derived>::operator-(const SparseMatrixBase<OtherDerived> &other) const +// { +// return CwiseBinaryOp<ei_scalar_difference_op<Scalar>, +// Derived, OtherDerived>(derived(), other.derived()); +// } template<typename Derived> template<typename OtherDerived> @@ -353,13 +301,13 @@ SparseMatrixBase<Derived>::operator-=(const SparseMatrixBase<OtherDerived> &othe return *this = derived() - other.derived(); } -template<typename Derived> -template<typename OtherDerived> -EIGEN_STRONG_INLINE const SparseCwiseBinaryOp<ei_scalar_sum_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived> -SparseMatrixBase<Derived>::operator+(const SparseMatrixBase<OtherDerived> &other) const -{ - return SparseCwiseBinaryOp<ei_scalar_sum_op<Scalar>, Derived, OtherDerived>(derived(), other.derived()); -} +// template<typename Derived> +// template<typename OtherDerived> +// EIGEN_STRONG_INLINE const CwiseBinaryOp<ei_scalar_sum_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived> +// SparseMatrixBase<Derived>::operator+(const SparseMatrixBase<OtherDerived> &other) const +// { +// return CwiseBinaryOp<ei_scalar_sum_op<Scalar>, Derived, OtherDerived>(derived(), other.derived()); +// } template<typename Derived> template<typename OtherDerived> @@ -369,20 +317,20 @@ SparseMatrixBase<Derived>::operator+=(const SparseMatrixBase<OtherDerived>& othe return *this = derived() + other.derived(); } -template<typename ExpressionType> -template<typename OtherDerived> -EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE -SparseCwise<ExpressionType>::operator*(const SparseMatrixBase<OtherDerived> &other) const -{ - return EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE(_expression(), other.derived()); -} +// template<typename ExpressionType> +// template<typename OtherDerived> +// EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE +// SparseCwise<ExpressionType>::operator*(const SparseMatrixBase<OtherDerived> &other) const +// { +// return EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE(_expression(), other.derived()); +// } -template<typename ExpressionType> +template<typename Derived> template<typename OtherDerived> EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE -SparseCwise<ExpressionType>::operator*(const MatrixBase<OtherDerived> &other) const +SparseMatrixBase<Derived>::cwiseProduct(const MatrixBase<OtherDerived> &other) const { - return EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE(_expression(), other.derived()); + return EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE(derived(), other.derived()); } // template<typename ExpressionType> @@ -401,42 +349,12 @@ SparseCwise<ExpressionType>::operator*(const MatrixBase<OtherDerived> &other) co // return EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_quotient_op)(_expression(), other.derived()); // } -template<typename ExpressionType> -template<typename OtherDerived> -inline ExpressionType& SparseCwise<ExpressionType>::operator*=(const SparseMatrixBase<OtherDerived> &other) -{ - return m_matrix.const_cast_derived() = _expression() * other.derived(); -} - // template<typename ExpressionType> // template<typename OtherDerived> -// inline ExpressionType& SparseCwise<ExpressionType>::operator/=(const SparseMatrixBase<OtherDerived> &other) +// inline ExpressionType& SparseCwise<ExpressionType>::operator*=(const SparseMatrixBase<OtherDerived> &other) // { -// return m_matrix.const_cast_derived() = *this / other; +// return m_matrix.const_cast_derived() = _expression() * other.derived(); // } -template<typename ExpressionType> -template<typename OtherDerived> -EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op) -SparseCwise<ExpressionType>::min(const SparseMatrixBase<OtherDerived> &other) const -{ - return EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_min_op)(_expression(), other.derived()); -} - -template<typename ExpressionType> -template<typename OtherDerived> -EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op) -SparseCwise<ExpressionType>::max(const SparseMatrixBase<OtherDerived> &other) const -{ - return EIGEN_SPARSE_CWISE_BINOP_RETURN_TYPE(ei_scalar_max_op)(_expression(), other.derived()); -} - -// template<typename Derived> -// template<typename CustomBinaryOp, typename OtherDerived> -// EIGEN_STRONG_INLINE const CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived> -// SparseMatrixBase<Derived>::binaryExpr(const SparseMatrixBase<OtherDerived> &other, const CustomBinaryOp& func) const -// { -// return CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>(derived(), other.derived(), func); -// } #endif // EIGEN_SPARSE_CWISE_BINARY_OP_H diff --git a/Eigen/src/Sparse/SparseCwiseUnaryOp.h b/Eigen/src/Sparse/SparseCwiseUnaryOp.h index 9a73374bd..eb2c99375 100644 --- a/Eigen/src/Sparse/SparseCwiseUnaryOp.h +++ b/Eigen/src/Sparse/SparseCwiseUnaryOp.h @@ -1,7 +1,7 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> +// Copyright (C) 2008-2009 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 @@ -25,55 +25,42 @@ #ifndef EIGEN_SPARSE_CWISE_UNARY_OP_H #define EIGEN_SPARSE_CWISE_UNARY_OP_H -template<typename UnaryOp, typename MatrixType> -struct ei_traits<SparseCwiseUnaryOp<UnaryOp, MatrixType> > : ei_traits<MatrixType> -{ - typedef typename ei_result_of< - UnaryOp(typename MatrixType::Scalar) - >::type Scalar; - typedef typename MatrixType::Nested MatrixTypeNested; - typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested; - enum { - CoeffReadCost = _MatrixTypeNested::CoeffReadCost + ei_functor_traits<UnaryOp>::Cost - }; -}; +// template<typename UnaryOp, typename MatrixType> +// struct ei_traits<SparseCwiseUnaryOp<UnaryOp, MatrixType> > : ei_traits<MatrixType> +// { +// typedef typename ei_result_of< +// UnaryOp(typename MatrixType::Scalar) +// >::type Scalar; +// typedef typename MatrixType::Nested MatrixTypeNested; +// typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested; +// enum { +// CoeffReadCost = _MatrixTypeNested::CoeffReadCost + ei_functor_traits<UnaryOp>::Cost +// }; +// }; template<typename UnaryOp, typename MatrixType> -class SparseCwiseUnaryOp : ei_no_assignment_operator, - public SparseMatrixBase<SparseCwiseUnaryOp<UnaryOp, MatrixType> > +class CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse> + : public SparseMatrixBase<CwiseUnaryOp<UnaryOp, MatrixType> > { public: class InnerIterator; // typedef typename ei_unref<LhsNested>::type _LhsNested; - EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseCwiseUnaryOp) - - inline SparseCwiseUnaryOp(const MatrixType& mat, const UnaryOp& func = UnaryOp()) - : m_matrix(mat), m_functor(func) {} - - EIGEN_STRONG_INLINE int rows() const { return m_matrix.rows(); } - EIGEN_STRONG_INLINE int cols() const { return m_matrix.cols(); } - -// EIGEN_STRONG_INLINE const typename MatrixType::Nested& _matrix() const { return m_matrix; } -// EIGEN_STRONG_INLINE const UnaryOp& _functor() const { return m_functor; } - - protected: - const typename MatrixType::Nested m_matrix; - const UnaryOp m_functor; + typedef CwiseUnaryOp<UnaryOp, MatrixType> Derived; + EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) }; - template<typename UnaryOp, typename MatrixType> -class SparseCwiseUnaryOp<UnaryOp,MatrixType>::InnerIterator +class CwiseUnaryOpImpl<UnaryOp,MatrixType,Sparse>::InnerIterator { - typedef typename SparseCwiseUnaryOp::Scalar Scalar; - typedef typename ei_traits<SparseCwiseUnaryOp>::_MatrixTypeNested _MatrixTypeNested; + typedef typename CwiseUnaryOpImpl::Scalar Scalar; + typedef typename ei_traits<Derived>::_MatrixTypeNested _MatrixTypeNested; typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator; public: - EIGEN_STRONG_INLINE InnerIterator(const SparseCwiseUnaryOp& unaryOp, int outer) - : m_iter(unaryOp.m_matrix,outer), m_functor(unaryOp.m_functor) + EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryOpImpl& unaryOp, int outer) + : m_iter(unaryOp.derived().nestedExpression(),outer), m_functor(unaryOp.derived()._functor()) {} EIGEN_STRONG_INLINE InnerIterator& operator++() @@ -92,73 +79,47 @@ class SparseCwiseUnaryOp<UnaryOp,MatrixType>::InnerIterator const UnaryOp m_functor; }; -template<typename Derived> -template<typename CustomUnaryOp> -EIGEN_STRONG_INLINE const SparseCwiseUnaryOp<CustomUnaryOp, Derived> -SparseMatrixBase<Derived>::unaryExpr(const CustomUnaryOp& func) const +template<typename ViewOp, typename MatrixType> +class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse> + : public SparseMatrixBase<CwiseUnaryView<ViewOp, MatrixType> > { - return SparseCwiseUnaryOp<CustomUnaryOp, Derived>(derived(), func); -} + public: -template<typename Derived> -EIGEN_STRONG_INLINE const SparseCwiseUnaryOp<ei_scalar_opposite_op<typename ei_traits<Derived>::Scalar>,Derived> -SparseMatrixBase<Derived>::operator-() const -{ - return derived(); -} + class InnerIterator; +// typedef typename ei_unref<LhsNested>::type _LhsNested; -template<typename ExpressionType> -EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs_op) -SparseCwise<ExpressionType>::abs() const -{ - return _expression(); -} + typedef CwiseUnaryView<ViewOp, MatrixType> Derived; + EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) +}; -template<typename ExpressionType> -EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_UNOP_RETURN_TYPE(ei_scalar_abs2_op) -SparseCwise<ExpressionType>::abs2() const +template<typename ViewOp, typename MatrixType> +class CwiseUnaryViewImpl<ViewOp,MatrixType,Sparse>::InnerIterator { - return _expression(); -} + typedef typename CwiseUnaryViewImpl::Scalar Scalar; + typedef typename ei_traits<Derived>::_MatrixTypeNested _MatrixTypeNested; + typedef typename _MatrixTypeNested::InnerIterator MatrixTypeIterator; + public: -template<typename Derived> -EIGEN_STRONG_INLINE typename SparseMatrixBase<Derived>::ConjugateReturnType -SparseMatrixBase<Derived>::conjugate() const -{ - return ConjugateReturnType(derived()); -} + EIGEN_STRONG_INLINE InnerIterator(const CwiseUnaryViewImpl& unaryView, int outer) + : m_iter(unaryView.derived().nestedExpression(),outer), m_functor(unaryView.derived()._functor()) + {} -template<typename Derived> -EIGEN_STRONG_INLINE const typename SparseMatrixBase<Derived>::RealReturnType -SparseMatrixBase<Derived>::real() const { return derived(); } + EIGEN_STRONG_INLINE InnerIterator& operator++() + { ++m_iter; return *this; } -template<typename Derived> -EIGEN_STRONG_INLINE const typename SparseMatrixBase<Derived>::ImagReturnType -SparseMatrixBase<Derived>::imag() const { return derived(); } + EIGEN_STRONG_INLINE Scalar value() const { return m_functor(m_iter.value()); } + EIGEN_STRONG_INLINE Scalar& valueRef() { return m_functor(m_iter.valueRef()); } -template<typename Derived> -template<typename NewType> -EIGEN_STRONG_INLINE const SparseCwiseUnaryOp<ei_scalar_cast_op<typename ei_traits<Derived>::Scalar, NewType>, Derived> -SparseMatrixBase<Derived>::cast() const -{ - return derived(); -} + EIGEN_STRONG_INLINE int index() const { return m_iter.index(); } + EIGEN_STRONG_INLINE int row() const { return m_iter.row(); } + EIGEN_STRONG_INLINE int col() const { return m_iter.col(); } -template<typename Derived> -EIGEN_STRONG_INLINE const SparseCwiseUnaryOp<ei_scalar_multiple_op<typename ei_traits<Derived>::Scalar>, Derived> -SparseMatrixBase<Derived>::operator*(const Scalar& scalar) const -{ - return SparseCwiseUnaryOp<ei_scalar_multiple_op<Scalar>, Derived> - (derived(), ei_scalar_multiple_op<Scalar>(scalar)); -} + EIGEN_STRONG_INLINE operator bool() const { return m_iter; } -template<typename Derived> -EIGEN_STRONG_INLINE const SparseCwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived> -SparseMatrixBase<Derived>::operator/(const Scalar& scalar) const -{ - return SparseCwiseUnaryOp<ei_scalar_quotient1_op<Scalar>, Derived> - (derived(), ei_scalar_quotient1_op<Scalar>(scalar)); -} + protected: + MatrixTypeIterator m_iter; + const ViewOp m_functor; +}; template<typename Derived> EIGEN_STRONG_INLINE Derived& diff --git a/Eigen/src/Sparse/SparseDiagonalProduct.h b/Eigen/src/Sparse/SparseDiagonalProduct.h index e9ba47f70..ceb4d6576 100644 --- a/Eigen/src/Sparse/SparseDiagonalProduct.h +++ b/Eigen/src/Sparse/SparseDiagonalProduct.h @@ -43,21 +43,22 @@ struct ei_traits<SparseDiagonalProduct<Lhs, Rhs> > typedef typename ei_cleantype<Lhs>::type _Lhs; typedef typename ei_cleantype<Rhs>::type _Rhs; typedef typename _Lhs::Scalar Scalar; + typedef Sparse StorageType; enum { RowsAtCompileTime = _Lhs::RowsAtCompileTime, ColsAtCompileTime = _Rhs::ColsAtCompileTime, MaxRowsAtCompileTime = _Lhs::MaxRowsAtCompileTime, MaxColsAtCompileTime = _Rhs::MaxColsAtCompileTime, - + SparseFlags = ei_is_diagonal<_Lhs>::ret ? int(_Rhs::Flags) : int(_Lhs::Flags), - Flags = SparseBit | (SparseFlags&RowMajorBit), + Flags = (SparseFlags&RowMajorBit), CoeffReadCost = Dynamic }; }; enum {SDP_IsDiagonal, SDP_IsSparseRowMajor, SDP_IsSparseColMajor}; -template<typename Lhs, typename Rhs, typename SparseDiagonalProductType, int RhsMode, int LhsMode> +template<typename Lhs, typename Rhs, typename SparseDiagonalProductType, int RhsMode, int LhsMode> class ei_sparse_diagonal_product_inner_iterator_selector; template<typename Lhs, typename Rhs> @@ -70,7 +71,7 @@ class SparseDiagonalProduct typedef typename ei_cleantype<LhsNested>::type _LhsNested; typedef typename ei_cleantype<RhsNested>::type _RhsNested; - + enum { LhsMode = ei_is_diagonal<_LhsNested>::ret ? SDP_IsDiagonal : (_LhsNested::Flags&RowMajorBit) ? SDP_IsSparseRowMajor : SDP_IsSparseColMajor, @@ -81,7 +82,7 @@ class SparseDiagonalProduct public: EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseDiagonalProduct) - + typedef ei_sparse_diagonal_product_inner_iterator_selector <_LhsNested,_RhsNested,SparseDiagonalProduct,LhsMode,RhsMode> InnerIterator; @@ -106,9 +107,9 @@ class SparseDiagonalProduct template<typename Lhs, typename Rhs, typename SparseDiagonalProductType> class ei_sparse_diagonal_product_inner_iterator_selector <Lhs,Rhs,SparseDiagonalProductType,SDP_IsDiagonal,SDP_IsSparseRowMajor> - : public SparseCwiseUnaryOp<ei_scalar_multiple_op<typename Lhs::Scalar>,Rhs>::InnerIterator + : public CwiseUnaryOp<ei_scalar_multiple_op<typename Lhs::Scalar>,Rhs>::InnerIterator { - typedef typename SparseCwiseUnaryOp<ei_scalar_multiple_op<typename Lhs::Scalar>,Rhs>::InnerIterator Base; + typedef typename CwiseUnaryOp<ei_scalar_multiple_op<typename Lhs::Scalar>,Rhs>::InnerIterator Base; public: inline ei_sparse_diagonal_product_inner_iterator_selector( const SparseDiagonalProductType& expr, int outer) @@ -119,28 +120,28 @@ class ei_sparse_diagonal_product_inner_iterator_selector template<typename Lhs, typename Rhs, typename SparseDiagonalProductType> class ei_sparse_diagonal_product_inner_iterator_selector <Lhs,Rhs,SparseDiagonalProductType,SDP_IsDiagonal,SDP_IsSparseColMajor> - : public SparseCwiseBinaryOp< + : public CwiseBinaryOp< ei_scalar_product_op<typename Lhs::Scalar>, SparseInnerVectorSet<Rhs,1>, typename Lhs::DiagonalVectorType>::InnerIterator { - typedef typename SparseCwiseBinaryOp< + typedef typename CwiseBinaryOp< ei_scalar_product_op<typename Lhs::Scalar>, SparseInnerVectorSet<Rhs,1>, typename Lhs::DiagonalVectorType>::InnerIterator Base; public: inline ei_sparse_diagonal_product_inner_iterator_selector( const SparseDiagonalProductType& expr, int outer) - : Base(expr.rhs().innerVector(outer) .cwise()* expr.lhs().diagonal(), 0) + : Base(expr.rhs().innerVector(outer) .cwiseProduct(expr.lhs().diagonal()), 0) {} }; template<typename Lhs, typename Rhs, typename SparseDiagonalProductType> class ei_sparse_diagonal_product_inner_iterator_selector <Lhs,Rhs,SparseDiagonalProductType,SDP_IsSparseColMajor,SDP_IsDiagonal> - : public SparseCwiseUnaryOp<ei_scalar_multiple_op<typename Rhs::Scalar>,Lhs>::InnerIterator + : public CwiseUnaryOp<ei_scalar_multiple_op<typename Rhs::Scalar>,Lhs>::InnerIterator { - typedef typename SparseCwiseUnaryOp<ei_scalar_multiple_op<typename Rhs::Scalar>,Lhs>::InnerIterator Base; + typedef typename CwiseUnaryOp<ei_scalar_multiple_op<typename Rhs::Scalar>,Lhs>::InnerIterator Base; public: inline ei_sparse_diagonal_product_inner_iterator_selector( const SparseDiagonalProductType& expr, int outer) @@ -151,19 +152,19 @@ class ei_sparse_diagonal_product_inner_iterator_selector template<typename Lhs, typename Rhs, typename SparseDiagonalProductType> class ei_sparse_diagonal_product_inner_iterator_selector <Lhs,Rhs,SparseDiagonalProductType,SDP_IsSparseRowMajor,SDP_IsDiagonal> - : public SparseCwiseBinaryOp< + : public CwiseBinaryOp< ei_scalar_product_op<typename Rhs::Scalar>, SparseInnerVectorSet<Lhs,1>, Transpose<typename Rhs::DiagonalVectorType> >::InnerIterator { - typedef typename SparseCwiseBinaryOp< + typedef typename CwiseBinaryOp< ei_scalar_product_op<typename Rhs::Scalar>, SparseInnerVectorSet<Lhs,1>, Transpose<typename Rhs::DiagonalVectorType> >::InnerIterator Base; public: inline ei_sparse_diagonal_product_inner_iterator_selector( const SparseDiagonalProductType& expr, int outer) - : Base(expr.lhs().innerVector(outer) .cwise()* expr.rhs().diagonal().transpose(), 0) + : Base(expr.lhs().innerVector(outer) .cwiseProduct(expr.rhs().diagonal().transpose()), 0) {} }; diff --git a/Eigen/src/Sparse/SparseFlagged.h b/Eigen/src/Sparse/SparseFlagged.h deleted file mode 100644 index 386a80abc..000000000 --- a/Eigen/src/Sparse/SparseFlagged.h +++ /dev/null @@ -1,97 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2008 Benoit Jacob <jacob.benoit.1@gmail.com> -// 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_SPARSE_FLAGGED_H -#define EIGEN_SPARSE_FLAGGED_H - -template<typename ExpressionType, unsigned int Added, unsigned int Removed> -struct ei_traits<SparseFlagged<ExpressionType, Added, Removed> > : ei_traits<ExpressionType> -{ - enum { Flags = (ExpressionType::Flags | Added) & ~Removed }; -}; - -template<typename ExpressionType, unsigned int Added, unsigned int Removed> class SparseFlagged - : public SparseMatrixBase<SparseFlagged<ExpressionType, Added, Removed> > -{ - public: - - EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(SparseFlagged) - class InnerIterator; - class ReverseInnerIterator; - - typedef typename ei_meta_if<ei_must_nest_by_value<ExpressionType>::ret, - ExpressionType, const ExpressionType&>::ret ExpressionTypeNested; - - inline SparseFlagged(const ExpressionType& matrix) : m_matrix(matrix) {} - - inline int rows() const { return m_matrix.rows(); } - inline int cols() const { return m_matrix.cols(); } - - // FIXME should be keep them ? - inline Scalar& coeffRef(int row, int col) - { return m_matrix.const_cast_derived().coeffRef(col, row); } - - inline const Scalar coeff(int row, int col) const - { return m_matrix.coeff(col, row); } - - inline const Scalar coeff(int index) const - { return m_matrix.coeff(index); } - - inline Scalar& coeffRef(int index) - { return m_matrix.const_cast_derived().coeffRef(index); } - - protected: - ExpressionTypeNested m_matrix; -}; - -template<typename ExpressionType, unsigned int Added, unsigned int Removed> - class SparseFlagged<ExpressionType,Added,Removed>::InnerIterator : public ExpressionType::InnerIterator -{ - public: - - EIGEN_STRONG_INLINE InnerIterator(const SparseFlagged& xpr, int outer) - : ExpressionType::InnerIterator(xpr.m_matrix, outer) - {} -}; - -template<typename ExpressionType, unsigned int Added, unsigned int Removed> - class SparseFlagged<ExpressionType,Added,Removed>::ReverseInnerIterator : public ExpressionType::ReverseInnerIterator -{ - public: - - EIGEN_STRONG_INLINE ReverseInnerIterator(const SparseFlagged& xpr, int outer) - : ExpressionType::ReverseInnerIterator(xpr.m_matrix, outer) - {} -}; - -template<typename Derived> -template<unsigned int Added> -inline const SparseFlagged<Derived, Added, 0> -SparseMatrixBase<Derived>::marked() const -{ - return derived(); -} - -#endif // EIGEN_SPARSE_FLAGGED_H diff --git a/Eigen/src/Sparse/SparseLDLT.h b/Eigen/src/Sparse/SparseLDLT.h index 3a7e82567..625357e2b 100644 --- a/Eigen/src/Sparse/SparseLDLT.h +++ b/Eigen/src/Sparse/SparseLDLT.h @@ -333,12 +333,12 @@ bool SparseLDLT<MatrixType, Backend>::solveInPlace(MatrixBase<Derived> &b) const return false; if (m_matrix.nonZeros()>0) // otherwise L==I - m_matrix.template triangular<UnitLowerTriangular>().solveInPlace(b); - b = b.cwise() / m_diag; + m_matrix.template triangularView<UnitLowerTriangular>().solveInPlace(b); + b = b.cwiseQuotient(m_diag); // FIXME should be .adjoint() but it fails to compile... if (m_matrix.nonZeros()>0) // otherwise L==I - m_matrix.transpose().template triangular<UnitUpperTriangular>().solveInPlace(b); + m_matrix.transpose().template triangularView<UnitUpperTriangular>().solveInPlace(b); return true; } diff --git a/Eigen/src/Sparse/SparseLLT.h b/Eigen/src/Sparse/SparseLLT.h index 4b73dd205..68ae43022 100644 --- a/Eigen/src/Sparse/SparseLLT.h +++ b/Eigen/src/Sparse/SparseLLT.h @@ -193,15 +193,15 @@ bool SparseLLT<MatrixType, Backend>::solveInPlace(MatrixBase<Derived> &b) const const int size = m_matrix.rows(); ei_assert(size==b.rows()); - m_matrix.template triangular<LowerTriangular>().solveInPlace(b); + m_matrix.template triangularView<LowerTriangular>().solveInPlace(b); // FIXME should be simply .adjoint() but it fails to compile... if (NumTraits<Scalar>::IsComplex) { CholMatrixType aux = m_matrix.conjugate(); - aux.transpose().template triangular<UpperTriangular>().solveInPlace(b); + aux.transpose().template triangularView<UpperTriangular>().solveInPlace(b); } else - m_matrix.transpose().template triangular<UpperTriangular>().solveInPlace(b); + m_matrix.transpose().template triangularView<UpperTriangular>().solveInPlace(b); return true; } diff --git a/Eigen/src/Sparse/SparseMatrix.h b/Eigen/src/Sparse/SparseMatrix.h index 8369bba54..7feb2aff8 100644 --- a/Eigen/src/Sparse/SparseMatrix.h +++ b/Eigen/src/Sparse/SparseMatrix.h @@ -45,12 +45,13 @@ template<typename _Scalar, int _Options> struct ei_traits<SparseMatrix<_Scalar, _Options> > { typedef _Scalar Scalar; + typedef Sparse StorageType; enum { RowsAtCompileTime = Dynamic, ColsAtCompileTime = Dynamic, MaxRowsAtCompileTime = Dynamic, MaxColsAtCompileTime = Dynamic, - Flags = SparseBit | _Options, + Flags = _Options, CoeffReadCost = NumTraits<Scalar>::ReadCost, SupportedAccessPatterns = InnerRandomAccessPattern }; @@ -546,6 +547,7 @@ class SparseMatrix<Scalar,_Options>::InnerIterator inline Scalar& valueRef() { return const_cast<Scalar&>(m_matrix.m_data.value(m_id)); } inline int index() const { return m_matrix.m_data.index(m_id); } + inline int outer() const { return m_outer; } inline int row() const { return IsRowMajor ? m_outer : index(); } inline int col() const { return IsRowMajor ? index() : m_outer; } diff --git a/Eigen/src/Sparse/SparseMatrixBase.h b/Eigen/src/Sparse/SparseMatrixBase.h index cbbaf6b8b..80cb7620c 100644 --- a/Eigen/src/Sparse/SparseMatrixBase.h +++ b/Eigen/src/Sparse/SparseMatrixBase.h @@ -41,7 +41,8 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived public: typedef typename ei_traits<Derived>::Scalar Scalar; -// typedef typename Derived::InnerIterator InnerIterator; + typedef typename ei_packet_traits<Scalar>::type PacketScalar; + typedef SparseMatrixBase StorageBaseType; enum { @@ -86,24 +87,37 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived * this expression. */ - IsRowMajor = Flags&RowMajorBit ? 1 : 0 + IsRowMajor = Flags&RowMajorBit ? 1 : 0, + + #ifndef EIGEN_PARSED_BY_DOXYGEN + _HasDirectAccess = (int(Flags)&DirectAccessBit) ? 1 : 0 // workaround sunCC + #endif }; - /** \internal the return type of MatrixBase::conjugate() */ - typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex, - const SparseCwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Derived>, - const Derived& - >::ret ConjugateReturnType; - /** \internal the return type of MatrixBase::real() */ - typedef SparseCwiseUnaryOp<ei_scalar_real_op<Scalar>, Derived> RealReturnType; - /** \internal the return type of MatrixBase::imag() */ - typedef SparseCwiseUnaryOp<ei_scalar_imag_op<Scalar>, Derived> ImagReturnType; + /* \internal the return type of MatrixBase::conjugate() */ +// typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex, +// const SparseCwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Derived>, +// const Derived& +// >::ret ConjugateReturnType; + /* \internal the return type of MatrixBase::real() */ +// typedef SparseCwiseUnaryOp<ei_scalar_real_op<Scalar>, Derived> RealReturnType; + /* \internal the return type of MatrixBase::imag() */ +// typedef SparseCwiseUnaryOp<ei_scalar_imag_op<Scalar>, Derived> ImagReturnType; /** \internal the return type of MatrixBase::adjoint() */ typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex, - SparseCwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::SparseTranspose<Derived> >, - SparseTranspose<Derived> + CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<Derived> >, + Transpose<Derived> >::ret AdjointReturnType; + typedef SparseMatrix<Scalar, Flags&RowMajorBit ? RowMajor : ColMajor> PlainMatrixType; + + #define EIGEN_CURRENT_STORAGE_BASE_CLASS Eigen::SparseMatrixBase + #include "../plugins/CommonCwiseUnaryOps.h" + #include "../plugins/CommonCwiseBinaryOps.h" + #include "../plugins/MatrixCwiseUnaryOps.h" + #include "../plugins/MatrixCwiseBinaryOps.h" + #undef EIGEN_CURRENT_STORAGE_BASE_CLASS + #ifndef EIGEN_PARSED_BY_DOXYGEN /** This is the "real scalar" type; if the \a Scalar type is already real numbers * (e.g. int, float or double) then \a RealScalar is just the same as \a Scalar. If @@ -113,6 +127,13 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived */ typedef typename NumTraits<Scalar>::Real RealScalar; + /** \internal the return type of coeff() + */ + typedef typename ei_meta_if<_HasDirectAccess, const Scalar&, Scalar>::ret CoeffReturnType; + + /** \internal Represents a matrix with all coefficients equal to one another*/ + typedef CwiseNullaryOp<ei_scalar_constant_op<Scalar>,Matrix<Scalar,Dynamic,Dynamic> > ConstantReturnType; + /** type of the equivalent square matrix */ typedef Matrix<Scalar,EIGEN_ENUM_MAX(RowsAtCompileTime,ColsAtCompileTime), EIGEN_ENUM_MAX(RowsAtCompileTime,ColsAtCompileTime)> SquareMatrixType; @@ -228,7 +249,7 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived } template<typename Lhs, typename Rhs> - inline Derived& operator=(const SparseProduct<Lhs,Rhs,SparseTimeSparseProduct>& product); + inline Derived& operator=(const SparseProduct<Lhs,Rhs>& product); friend std::ostream & operator << (std::ostream & s, const SparseMatrixBase& m) { @@ -272,15 +293,15 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived return s; } - const SparseCwiseUnaryOp<ei_scalar_opposite_op<typename ei_traits<Derived>::Scalar>,Derived> operator-() const; +// const SparseCwiseUnaryOp<ei_scalar_opposite_op<typename ei_traits<Derived>::Scalar>,Derived> operator-() const; - template<typename OtherDerived> - const SparseCwiseBinaryOp<ei_scalar_sum_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived> - operator+(const SparseMatrixBase<OtherDerived> &other) const; +// template<typename OtherDerived> +// const CwiseBinaryOp<ei_scalar_sum_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived> +// operator+(const SparseMatrixBase<OtherDerived> &other) const; - template<typename OtherDerived> - const SparseCwiseBinaryOp<ei_scalar_difference_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived> - operator-(const SparseMatrixBase<OtherDerived> &other) const; +// template<typename OtherDerived> +// const CwiseBinaryOp<ei_scalar_difference_op<typename ei_traits<Derived>::Scalar>, Derived, OtherDerived> +// operator-(const SparseMatrixBase<OtherDerived> &other) const; template<typename OtherDerived> Derived& operator+=(const SparseMatrixBase<OtherDerived>& other); @@ -293,14 +314,30 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived Derived& operator*=(const Scalar& other); Derived& operator/=(const Scalar& other); - const SparseCwiseUnaryOp<ei_scalar_multiple_op<typename ei_traits<Derived>::Scalar>, Derived> - operator*(const Scalar& scalar) const; - const SparseCwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived> - operator/(const Scalar& scalar) const; + #define EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE \ + CwiseBinaryOp< \ + ei_scalar_product_op< \ + typename ei_scalar_product_traits< \ + typename ei_traits<Derived>::Scalar, \ + typename ei_traits<OtherDerived>::Scalar \ + >::ReturnType \ + >, \ + Derived, \ + OtherDerived \ + > + + template<typename OtherDerived> + EIGEN_STRONG_INLINE const EIGEN_SPARSE_CWISE_PRODUCT_RETURN_TYPE + cwiseProduct(const MatrixBase<OtherDerived> &other) const; + +// const SparseCwiseUnaryOp<ei_scalar_multiple_op<typename ei_traits<Derived>::Scalar>, Derived> +// operator*(const Scalar& scalar) const; +// const SparseCwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived> +// operator/(const Scalar& scalar) const; - inline friend const SparseCwiseUnaryOp<ei_scalar_multiple_op<typename ei_traits<Derived>::Scalar>, Derived> - operator*(const Scalar& scalar, const SparseMatrixBase& matrix) - { return matrix*scalar; } +// inline friend const SparseCwiseUnaryOp<ei_scalar_multiple_op<typename ei_traits<Derived>::Scalar>, Derived> +// operator*(const Scalar& scalar, const SparseMatrixBase& matrix) +// { return matrix*scalar; } // sparse * sparse @@ -321,17 +358,19 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived // dense * sparse (return a dense object) template<typename OtherDerived> friend - const typename SparseProductReturnType<OtherDerived,Derived>::Type + const DenseTimeSparseProduct<OtherDerived,Derived> operator*(const MatrixBase<OtherDerived>& lhs, const Derived& rhs) - { return typename SparseProductReturnType<OtherDerived,Derived>::Type(lhs.derived(),rhs); } + { return DenseTimeSparseProduct<OtherDerived,Derived>(lhs.derived(),rhs); } + // sparse * dense (returns a dense object) template<typename OtherDerived> - const typename SparseProductReturnType<Derived,OtherDerived>::Type + const SparseTimeDenseProduct<Derived,OtherDerived> operator*(const MatrixBase<OtherDerived> &other) const; template<typename OtherDerived> Derived& operator*=(const SparseMatrixBase<OtherDerived>& other); + #ifdef EIGEN2_SUPPORT // deprecated template<typename OtherDerived> typename ei_plain_matrix_type_column_major<OtherDerived>::type @@ -342,9 +381,13 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived void solveTriangularInPlace(MatrixBase<OtherDerived>& other) const; // template<typename OtherDerived> // void solveTriangularInPlace(SparseMatrixBase<OtherDerived>& other) const; + #endif // EIGEN2_SUPPORT template<int Mode> - inline const SparseTriangular<Derived, Mode> triangular() const; + inline const SparseTriangularView<Derived, Mode> triangularView() const; + + template<unsigned int UpLo> inline const SparseSelfAdjointView<Derived, UpLo> selfadjointView() const; + template<unsigned int UpLo> inline SparseSelfAdjointView<Derived, UpLo> selfadjointView(); template<typename OtherDerived> Scalar dot(const MatrixBase<OtherDerived>& other) const; template<typename OtherDerived> Scalar dot(const SparseMatrixBase<OtherDerived>& other) const; @@ -353,8 +396,8 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived // const PlainMatrixType normalized() const; // void normalize(); - SparseTranspose<Derived> transpose() { return derived(); } - const SparseTranspose<Derived> transpose() const { return derived(); } + Transpose<Derived> transpose() { return derived(); } + const Transpose<Derived> transpose() const { return derived(); } // void transposeInPlace(); const AdjointReturnType adjoint() const { return transpose(); } @@ -503,8 +546,8 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived // { return (cwise() != other).any(); } - template<typename NewType> - const SparseCwiseUnaryOp<ei_scalar_cast_op<typename ei_traits<Derived>::Scalar, NewType>, Derived> cast() const; +// template<typename NewType> +// const SparseCwiseUnaryOp<ei_scalar_cast_op<typename ei_traits<Derived>::Scalar, NewType>, Derived> cast() const; /** \returns the matrix or vector obtained by evaluating this expression. * @@ -517,8 +560,8 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived // template<typename OtherDerived> // void swap(MatrixBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other); - template<unsigned int Added> - const SparseFlagged<Derived, Added, 0> marked() const; +// template<unsigned int Added> +// const SparseFlagged<Derived, Added, 0> marked() const; // const Flagged<Derived, 0, EvalBeforeNestingBit | EvalBeforeAssigningBit> lazy() const; /** \returns number of elements to skip to pass from one row (resp. column) to another @@ -528,12 +571,13 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived */ // inline int stride(void) const { return derived().stride(); } - ConjugateReturnType conjugate() const; - const RealReturnType real() const; - const ImagReturnType imag() const; +// FIXME +// ConjugateReturnType conjugate() const; +// const RealReturnType real() const; +// const ImagReturnType imag() const; - template<typename CustomUnaryOp> - const SparseCwiseUnaryOp<CustomUnaryOp, Derived> unaryExpr(const CustomUnaryOp& func = CustomUnaryOp()) const; +// template<typename CustomUnaryOp> +// const SparseCwiseUnaryOp<CustomUnaryOp, Derived> unaryExpr(const CustomUnaryOp& func = CustomUnaryOp()) const; // template<typename CustomBinaryOp, typename OtherDerived> // const CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived> @@ -557,8 +601,8 @@ template<typename Derived> class SparseMatrixBase : public AnyMatrixBase<Derived // void visit(Visitor& func) const; - const SparseCwise<Derived> cwise() const; - SparseCwise<Derived> cwise(); +// const SparseCwise<Derived> cwise() const; +// SparseCwise<Derived> cwise(); // inline const WithFormat<Derived> format(const IOFormat& fmt) const; diff --git a/Eigen/src/Sparse/SparseProduct.h b/Eigen/src/Sparse/SparseProduct.h index cb1196bc9..08f6e3cac 100644 --- a/Eigen/src/Sparse/SparseProduct.h +++ b/Eigen/src/Sparse/SparseProduct.h @@ -25,29 +25,8 @@ #ifndef EIGEN_SPARSEPRODUCT_H #define EIGEN_SPARSEPRODUCT_H -template<typename Lhs, typename Rhs> struct ei_sparse_product_mode -{ - enum { - - value = (Rhs::Flags&Lhs::Flags&SparseBit)==SparseBit - ? SparseTimeSparseProduct - : (Lhs::Flags&SparseBit)==SparseBit - ? SparseTimeDenseProduct - : DenseTimeSparseProduct }; -}; - -template<typename Lhs, typename Rhs, int ProductMode> -struct SparseProductReturnType -{ - typedef const typename ei_nested<Lhs,Rhs::RowsAtCompileTime>::type LhsNested; - typedef const typename ei_nested<Rhs,Lhs::RowsAtCompileTime>::type RhsNested; - - typedef SparseProduct<LhsNested, RhsNested, ProductMode> Type; -}; - -// sparse product return type specialization template<typename Lhs, typename Rhs> -struct SparseProductReturnType<Lhs,Rhs,SparseTimeSparseProduct> +struct SparseProductReturnType { typedef typename ei_traits<Lhs>::Scalar Scalar; enum { @@ -67,12 +46,13 @@ struct SparseProductReturnType<Lhs,Rhs,SparseTimeSparseProduct> SparseMatrix<Scalar,0>, const typename ei_nested<Rhs,Lhs::RowsAtCompileTime>::type>::ret RhsNested; - typedef SparseProduct<LhsNested, RhsNested, SparseTimeSparseProduct> Type; + typedef SparseProduct<LhsNested, RhsNested> Type; }; -template<typename LhsNested, typename RhsNested, int ProductMode> -struct ei_traits<SparseProduct<LhsNested, RhsNested, ProductMode> > +template<typename LhsNested, typename RhsNested> +struct ei_traits<SparseProduct<LhsNested, RhsNested> > { + typedef DenseStorageMatrix DenseStorageType; // clean the nested types: typedef typename ei_cleantype<LhsNested>::type _LhsNested; typedef typename ei_cleantype<RhsNested>::type _RhsNested; @@ -91,13 +71,9 @@ struct ei_traits<SparseProduct<LhsNested, RhsNested, ProductMode> > MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime, MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime, -// LhsIsRowMajor = (LhsFlags & RowMajorBit)==RowMajorBit, -// RhsIsRowMajor = (RhsFlags & RowMajorBit)==RowMajorBit, - EvalToRowMajor = (RhsFlags & LhsFlags & RowMajorBit), - ResultIsSparse = ProductMode==SparseTimeSparseProduct, - RemovedBits = ~( (EvalToRowMajor ? 0 : RowMajorBit) | (ResultIsSparse ? 0 : SparseBit) ), + RemovedBits = ~(EvalToRowMajor ? 0 : RowMajorBit), Flags = (int(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits) | EvalBeforeAssigningBit @@ -106,14 +82,14 @@ struct ei_traits<SparseProduct<LhsNested, RhsNested, ProductMode> > CoeffReadCost = Dynamic }; - typedef typename ei_meta_if<ResultIsSparse, - SparseMatrixBase<SparseProduct<LhsNested, RhsNested, ProductMode> >, - MatrixBase<SparseProduct<LhsNested, RhsNested, ProductMode> > >::ret Base; + typedef Sparse StorageType; + + typedef SparseMatrixBase<SparseProduct<LhsNested, RhsNested> > Base; }; -template<typename LhsNested, typename RhsNested, int ProductMode> +template<typename LhsNested, typename RhsNested> class SparseProduct : ei_no_assignment_operator, - public ei_traits<SparseProduct<LhsNested, RhsNested, ProductMode> >::Base + public ei_traits<SparseProduct<LhsNested, RhsNested> >::Base { public: @@ -264,38 +240,14 @@ struct ei_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,RowMajor,ColMajor> } }; -// NOTE eventually let's transpose one argument even in this case since it might be expensive if -// the result is not dense. -// template<typename Lhs, typename Rhs, typename ResultType, int ResStorageOrder> -// struct ei_sparse_product_selector<Lhs,Rhs,ResultType,RowMajor,ColMajor,ResStorageOrder> -// { -// static void run(const Lhs& lhs, const Rhs& rhs, ResultType& res) -// { -// // trivial product as lhs.row/rhs.col dot products -// // loop over the preferred order of the result -// } -// }; - // NOTE the 2 others cases (col row *) must never occurs since they are caught // by ProductReturnType which transform it to (col col *) by evaluating rhs. -// template<typename Derived> -// template<typename Lhs, typename Rhs> -// inline Derived& SparseMatrixBase<Derived>::lazyAssign(const SparseProduct<Lhs,Rhs>& product) -// { -// // std::cout << "sparse product to dense\n"; -// ei_sparse_product_selector< -// typename ei_cleantype<Lhs>::type, -// typename ei_cleantype<Rhs>::type, -// typename ei_cleantype<Derived>::type>::run(product.lhs(),product.rhs(),derived()); -// return derived(); -// } - // sparse = sparse * sparse template<typename Derived> template<typename Lhs, typename Rhs> -inline Derived& SparseMatrixBase<Derived>::operator=(const SparseProduct<Lhs,Rhs,SparseTimeSparseProduct>& product) +inline Derived& SparseMatrixBase<Derived>::operator=(const SparseProduct<Lhs,Rhs>& product) { ei_sparse_product_selector< typename ei_cleantype<Lhs>::type, @@ -304,78 +256,80 @@ inline Derived& SparseMatrixBase<Derived>::operator=(const SparseProduct<Lhs,Rhs return derived(); } -// dense = sparse * dense -// Note that here we force no inlining and separate the setZero() because GCC messes up otherwise -template<typename Lhs, typename Rhs, typename Dest> -EIGEN_DONT_INLINE void ei_sparse_time_dense_product(const Lhs& lhs, const Rhs& rhs, Dest& dst) + +template<typename Lhs, typename Rhs> +struct ei_traits<SparseTimeDenseProduct<Lhs,Rhs> > + : ei_traits<ProductBase<SparseTimeDenseProduct<Lhs,Rhs>, Lhs, Rhs> > { - typedef typename ei_cleantype<Lhs>::type _Lhs; - typedef typename ei_cleantype<Rhs>::type _Rhs; - typedef typename _Lhs::InnerIterator LhsInnerIterator; - enum { - LhsIsRowMajor = (_Lhs::Flags&RowMajorBit)==RowMajorBit, - LhsIsSelfAdjoint = (_Lhs::Flags&SelfAdjointBit)==SelfAdjointBit, - ProcessFirstHalf = LhsIsSelfAdjoint - && ( ((_Lhs::Flags&(UpperTriangularBit|LowerTriangularBit))==0) - || ( (_Lhs::Flags&UpperTriangularBit) && !LhsIsRowMajor) - || ( (_Lhs::Flags&LowerTriangularBit) && LhsIsRowMajor) ), - ProcessSecondHalf = LhsIsSelfAdjoint && (!ProcessFirstHalf) - }; - for (int j=0; j<lhs.outerSize(); ++j) - { - LhsInnerIterator i(lhs,j); - if (ProcessSecondHalf && i && (i.index()==j)) - { - dst.row(j) += i.value() * rhs.row(j); - ++i; - } - typename Rhs::Scalar rhs_j = rhs.coeff(j,0); - Block<Dest,1,Dest::ColsAtCompileTime> dst_j(dst.row(LhsIsRowMajor ? j : 0)); - for(; (ProcessFirstHalf ? i && i.index() < j : i) ; ++i) + typedef Dense StorageType; + typedef DenseStorageMatrix DenseStorageType; +}; + +template<typename Lhs, typename Rhs> +class SparseTimeDenseProduct + : public ProductBase<SparseTimeDenseProduct<Lhs,Rhs>, Lhs, Rhs> +{ + public: + EIGEN_PRODUCT_PUBLIC_INTERFACE(SparseTimeDenseProduct) + + SparseTimeDenseProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) + {} + + template<typename Dest> void scaleAndAddTo(Dest& dest, Scalar alpha) const { - if(LhsIsSelfAdjoint) + typedef typename ei_cleantype<Lhs>::type _Lhs; + typedef typename ei_cleantype<Rhs>::type _Rhs; + typedef typename _Lhs::InnerIterator LhsInnerIterator; + enum { LhsIsRowMajor = (_Lhs::Flags&RowMajorBit)==RowMajorBit }; + for(int j=0; j<m_lhs.outerSize(); ++j) { - int a = LhsIsRowMajor ? j : i.index(); - int b = LhsIsRowMajor ? i.index() : j; - typename Lhs::Scalar v = i.value(); - dst.row(a) += (v) * rhs.row(b); - dst.row(b) += ei_conj(v) * rhs.row(a); + typename Rhs::Scalar rhs_j = alpha * m_rhs.coeff(j,0); + Block<Dest,1,Dest::ColsAtCompileTime> dest_j(dest.row(LhsIsRowMajor ? j : 0)); + for(LhsInnerIterator it(m_lhs,j); it ;++it) + { + if(LhsIsRowMajor) dest_j += (alpha*it.value()) * m_rhs.row(it.index()); + else if(Rhs::ColsAtCompileTime==1) dest.coeffRef(it.index()) += it.value() * rhs_j; + else dest.row(it.index()) += (alpha*it.value()) * m_rhs.row(j); + } } - else if(LhsIsRowMajor) - dst_j += i.value() * rhs.row(i.index()); - else if(Rhs::ColsAtCompileTime==1) - dst.coeffRef(i.index()) += i.value() * rhs_j; - else - dst.row(i.index()) += i.value() * rhs.row(j); } - if (ProcessFirstHalf && i && (i.index()==j)) - dst.row(j) += i.value() * rhs.row(j); - } -} -template<typename Derived> + private: + SparseTimeDenseProduct& operator=(const SparseTimeDenseProduct&); +}; + + +// dense = dense * sparse template<typename Lhs, typename Rhs> -Derived& MatrixBase<Derived>::lazyAssign(const SparseProduct<Lhs,Rhs,SparseTimeDenseProduct>& product) +struct ei_traits<DenseTimeSparseProduct<Lhs,Rhs> > + : ei_traits<ProductBase<DenseTimeSparseProduct<Lhs,Rhs>, Lhs, Rhs> > { - derived().setZero(); - ei_sparse_time_dense_product(product.lhs(), product.rhs(), derived()); - return derived(); -} + typedef Dense StorageType; +}; -// dense = dense * sparse -template<typename Derived> template<typename Lhs, typename Rhs> -Derived& MatrixBase<Derived>::lazyAssign(const SparseProduct<Lhs,Rhs,DenseTimeSparseProduct>& product) +class DenseTimeSparseProduct + : public ProductBase<DenseTimeSparseProduct<Lhs,Rhs>, Lhs, Rhs> { - typedef typename ei_cleantype<Rhs>::type _Rhs; - typedef typename _Rhs::InnerIterator RhsInnerIterator; - enum { RhsIsRowMajor = (_Rhs::Flags&RowMajorBit)==RowMajorBit }; - derived().setZero(); - for (int j=0; j<product.rhs().outerSize(); ++j) - for (RhsInnerIterator i(product.rhs(),j); i; ++i) - derived().col(RhsIsRowMajor ? i.index() : j) += i.value() * product.lhs().col(RhsIsRowMajor ? j : i.index()); - return derived(); -} + public: + EIGEN_PRODUCT_PUBLIC_INTERFACE(DenseTimeSparseProduct) + + DenseTimeSparseProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) + {} + + template<typename Dest> void scaleAndAddTo(Dest& dest, Scalar alpha) const + { + typedef typename ei_cleantype<Rhs>::type _Rhs; + typedef typename _Rhs::InnerIterator RhsInnerIterator; + enum { RhsIsRowMajor = (_Rhs::Flags&RowMajorBit)==RowMajorBit }; + for(int j=0; j<m_rhs.outerSize(); ++j) + for(RhsInnerIterator i(m_rhs,j); i; ++i) + dest.col(RhsIsRowMajor ? i.index() : j) += (alpha*i.value()) * m_lhs.col(RhsIsRowMajor ? j : i.index()); + } + + private: + DenseTimeSparseProduct& operator=(const DenseTimeSparseProduct&); +}; // sparse * sparse template<typename Derived> @@ -389,10 +343,10 @@ SparseMatrixBase<Derived>::operator*(const SparseMatrixBase<OtherDerived> &other // sparse * dense template<typename Derived> template<typename OtherDerived> -EIGEN_STRONG_INLINE const typename SparseProductReturnType<Derived,OtherDerived>::Type +EIGEN_STRONG_INLINE const SparseTimeDenseProduct<Derived,OtherDerived> SparseMatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const { - return typename SparseProductReturnType<Derived,OtherDerived>::Type(derived(), other.derived()); + return SparseTimeDenseProduct<Derived,OtherDerived>(derived(), other.derived()); } #endif // EIGEN_SPARSEPRODUCT_H diff --git a/Eigen/src/Sparse/SparseSelfAdjointView.h b/Eigen/src/Sparse/SparseSelfAdjointView.h new file mode 100644 index 000000000..f5296accf --- /dev/null +++ b/Eigen/src/Sparse/SparseSelfAdjointView.h @@ -0,0 +1,223 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 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_SPARSE_SELFADJOINTVIEW_H +#define EIGEN_SPARSE_SELFADJOINTVIEW_H + +/** \class SparseSelfAdjointView + * \nonstableyet + * + * \brief Pseudo expression to manipulate a triangular sparse matrix as a selfadjoint matrix. + * + * \param MatrixType the type of the dense matrix storing the coefficients + * \param UpLo can be either \c LowerTriangular or \c UpperTriangular + * + * This class is an expression of a sefladjoint matrix from a triangular part of a matrix + * with given dense storage of the coefficients. It is the return type of MatrixBase::selfadjointView() + * and most of the time this is the only way that it is used. + * + * \sa SparseMatrixBase::selfAdjointView() + */ +template<typename Lhs, typename Rhs, int UpLo> +class SparseSelfAdjointTimeDenseProduct; + +template<typename Lhs, typename Rhs, int UpLo> +class DenseTimeSparseSelfAdjointProduct; + +template<typename MatrixType, unsigned int UpLo> class SparseSelfAdjointView +{ + public: + + typedef typename ei_traits<MatrixType>::Scalar Scalar; + + inline SparseSelfAdjointView(const MatrixType& matrix) : m_matrix(matrix) + { + ei_assert(ei_are_flags_consistent<UpLo>::ret); + ei_assert(rows()==cols() && "SelfAdjointView is only for squared matrices"); + } + + inline int rows() const { return m_matrix.rows(); } + inline int cols() const { return m_matrix.cols(); } + + /** \internal \returns a reference to the nested matrix */ + const MatrixType& matrix() const { return m_matrix; } + + /** Efficient sparse self-adjoint matrix times dense vector/matrix product */ + template<typename OtherDerived> + SparseSelfAdjointTimeDenseProduct<MatrixType,OtherDerived,UpLo> + operator*(const MatrixBase<OtherDerived>& rhs) const + { + return SparseSelfAdjointTimeDenseProduct<MatrixType,OtherDerived,UpLo>(m_matrix, rhs.derived()); + } + + /** Efficient dense vector/matrix times sparse self-adjoint matrix product */ + template<typename OtherDerived> friend + DenseTimeSparseSelfAdjointProduct<OtherDerived,MatrixType,UpLo> + operator*(const MatrixBase<OtherDerived>& lhs, const SparseSelfAdjointView& rhs) + { + return DenseTimeSparseSelfAdjointProduct<OtherDerived,MatrixType,UpLo>(lhs.derived(), rhs.m_matrix); + } + + /** Perform a symmetric rank K update of the selfadjoint matrix \c *this: + * \f$ this = this + \alpha ( u u^* ) \f$ where \a u is a vector or matrix. + * + * \returns a reference to \c *this + * + * Note that it is faster to set alpha=0 than initializing the matrix to zero + * and then keep the default value alpha=1. + * + * To perform \f$ this = this + \alpha ( u^* u ) \f$ you can simply + * call this function with u.adjoint(). + */ + template<typename DerivedU> + SparseSelfAdjointView& rankUpdate(const MatrixBase<DerivedU>& u, Scalar alpha = Scalar(1)); + + // const SparseLLT<PlainMatrixType, UpLo> llt() const; + // const SparseLDLT<PlainMatrixType, UpLo> ldlt() const; + + protected: + + const typename MatrixType::Nested m_matrix; +}; + +/*************************************************************************** +* Implementation of SparseMatrixBase methods +***************************************************************************/ + +template<typename Derived> +template<unsigned int UpLo> +const SparseSelfAdjointView<Derived, UpLo> SparseMatrixBase<Derived>::selfadjointView() const +{ + return derived(); +} + +template<typename Derived> +template<unsigned int UpLo> +SparseSelfAdjointView<Derived, UpLo> SparseMatrixBase<Derived>::selfadjointView() +{ + return derived(); +} + +/*************************************************************************** +* Implementation of SparseSelfAdjointView methods +***************************************************************************/ + +template<typename MatrixType, unsigned int UpLo> +template<typename DerivedU> +SparseSelfAdjointView<MatrixType,UpLo>& +SparseSelfAdjointView<MatrixType,UpLo>::rankUpdate(const MatrixBase<DerivedU>& u, Scalar alpha) +{ + SparseMatrix<Scalar,MatrixType::Flags&RowMajorBit?RowMajor:ColMajor> tmp = u * u.adjoint(); + if(alpha==Scalar(0)) + m_matrix = tmp.template triangularView<UpLo>(); + else + m_matrix += alpha * tmp.template triangularView<UpLo>(); + + return this; +} + +/*************************************************************************** +* Implementation of sparse self-adjoint time dense matrix +***************************************************************************/ + +template<typename Lhs, typename Rhs, int UpLo> +struct ei_traits<SparseSelfAdjointTimeDenseProduct<Lhs,Rhs,UpLo> > + : ei_traits<ProductBase<SparseSelfAdjointTimeDenseProduct<Lhs,Rhs,UpLo>, Lhs, Rhs> > +{}; + +template<typename Lhs, typename Rhs, int UpLo> +class SparseSelfAdjointTimeDenseProduct + : public ProductBase<SparseSelfAdjointTimeDenseProduct<Lhs,Rhs,UpLo>, Lhs, Rhs> +{ + public: + EIGEN_PRODUCT_PUBLIC_INTERFACE(SparseSelfAdjointTimeDenseProduct) + + SparseSelfAdjointTimeDenseProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) + {} + + template<typename Dest> void scaleAndAddTo(Dest& dest, Scalar alpha) const + { + // TODO use alpha + ei_assert(alpha==Scalar(1) && "alpha != 1 is not implemented yet, sorry"); + typedef typename ei_cleantype<Lhs>::type _Lhs; + typedef typename ei_cleantype<Rhs>::type _Rhs; + typedef typename _Lhs::InnerIterator LhsInnerIterator; + enum { + LhsIsRowMajor = (_Lhs::Flags&RowMajorBit)==RowMajorBit, + ProcessFirstHalf = + ((UpLo&(UpperTriangularBit|LowerTriangularBit))==(UpperTriangularBit|LowerTriangularBit)) + || ( (UpLo&UpperTriangularBit) && !LhsIsRowMajor) + || ( (UpLo&LowerTriangularBit) && LhsIsRowMajor), + ProcessSecondHalf = !ProcessFirstHalf + }; + for (int j=0; j<m_lhs.outerSize(); ++j) + { + LhsInnerIterator i(m_lhs,j); + if (ProcessSecondHalf && i && (i.index()==j)) + { + dest.row(j) += i.value() * m_rhs.row(j); + ++i; + } + Block<Dest,1,Dest::ColsAtCompileTime> dest_j(dest.row(LhsIsRowMajor ? j : 0)); + for(; (ProcessFirstHalf ? i && i.index() < j : i) ; ++i) + { + int a = LhsIsRowMajor ? j : i.index(); + int b = LhsIsRowMajor ? i.index() : j; + typename Lhs::Scalar v = i.value(); + dest.row(a) += (v) * m_rhs.row(b); + dest.row(b) += ei_conj(v) * m_rhs.row(a); + } + if (ProcessFirstHalf && i && (i.index()==j)) + dest.row(j) += i.value() * m_rhs.row(j); + } + } + + private: + SparseSelfAdjointTimeDenseProduct& operator=(const SparseSelfAdjointTimeDenseProduct&); +}; + +template<typename Lhs, typename Rhs, int UpLo> +struct ei_traits<DenseTimeSparseSelfAdjointProduct<Lhs,Rhs,UpLo> > + : ei_traits<ProductBase<DenseTimeSparseSelfAdjointProduct<Lhs,Rhs,UpLo>, Lhs, Rhs> > +{}; + +template<typename Lhs, typename Rhs, int UpLo> +class DenseTimeSparseSelfAdjointProduct + : public ProductBase<DenseTimeSparseSelfAdjointProduct<Lhs,Rhs,UpLo>, Lhs, Rhs> +{ + public: + EIGEN_PRODUCT_PUBLIC_INTERFACE(DenseTimeSparseSelfAdjointProduct) + + DenseTimeSparseSelfAdjointProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) + {} + + template<typename Dest> void scaleAndAddTo(Dest& dest, Scalar alpha) const + { + // TODO + } + + private: + DenseTimeSparseSelfAdjointProduct& operator=(const DenseTimeSparseSelfAdjointProduct&); +}; +#endif // EIGEN_SPARSE_SELFADJOINTVIEW_H diff --git a/Eigen/src/Sparse/SparseTranspose.h b/Eigen/src/Sparse/SparseTranspose.h index 9a702739d..b8c38617a 100644 --- a/Eigen/src/Sparse/SparseTranspose.h +++ b/Eigen/src/Sparse/SparseTranspose.h @@ -1,7 +1,7 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> +// Copyright (C) 2008-2009 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 @@ -25,64 +25,51 @@ #ifndef EIGEN_SPARSETRANSPOSE_H #define EIGEN_SPARSETRANSPOSE_H -template<typename MatrixType> -struct ei_traits<SparseTranspose<MatrixType> > : ei_traits<Transpose<MatrixType> > -{}; - -template<typename MatrixType> class SparseTranspose - : public SparseMatrixBase<SparseTranspose<MatrixType> > +template<typename MatrixType> class TransposeImpl<MatrixType,Sparse> + : public SparseMatrixBase<Transpose<MatrixType> > { public: - EIGEN_GENERIC_PUBLIC_INTERFACE(SparseTranspose) + EIGEN_SPARSE_PUBLIC_INTERFACE(Transpose<MatrixType>) class InnerIterator; class ReverseInnerIterator; - inline SparseTranspose(const MatrixType& matrix) : m_matrix(matrix) {} - - //EIGEN_INHERIT_ASSIGNMENT_OPERATORS(SparseTranspose) - - inline int rows() const { return m_matrix.cols(); } - inline int cols() const { return m_matrix.rows(); } - inline int nonZeros() const { return m_matrix.nonZeros(); } + inline int nonZeros() const { return derived().nestedExpression().nonZeros(); } // FIXME should be keep them ? inline Scalar& coeffRef(int row, int col) - { return m_matrix.const_cast_derived().coeffRef(col, row); } + { return const_cast_derived().nestedExpression().coeffRef(col, row); } inline const Scalar coeff(int row, int col) const - { return m_matrix.coeff(col, row); } + { return derived().nestedExpression().coeff(col, row); } inline const Scalar coeff(int index) const - { return m_matrix.coeff(index); } + { return derived().nestedExpression().coeff(index); } inline Scalar& coeffRef(int index) - { return m_matrix.const_cast_derived().coeffRef(index); } - - protected: - const typename MatrixType::Nested m_matrix; + { return const_cast_derived().nestedExpression().coeffRef(index); } }; -template<typename MatrixType> class SparseTranspose<MatrixType>::InnerIterator : public MatrixType::InnerIterator +template<typename MatrixType> class TransposeImpl<MatrixType,Sparse>::InnerIterator : public MatrixType::InnerIterator { typedef typename MatrixType::InnerIterator Base; public: - EIGEN_STRONG_INLINE InnerIterator(const SparseTranspose& trans, int outer) - : Base(trans.m_matrix, outer) + EIGEN_STRONG_INLINE InnerIterator(const TransposeImpl& trans, int outer) + : Base(trans.derived().nestedExpression(), outer) {} inline int row() const { return Base::col(); } inline int col() const { return Base::row(); } }; -template<typename MatrixType> class SparseTranspose<MatrixType>::ReverseInnerIterator : public MatrixType::ReverseInnerIterator +template<typename MatrixType> class TransposeImpl<MatrixType,Sparse>::ReverseInnerIterator : public MatrixType::ReverseInnerIterator { typedef typename MatrixType::ReverseInnerIterator Base; public: - EIGEN_STRONG_INLINE ReverseInnerIterator(const SparseTranspose& xpr, int outer) - : Base(xpr.m_matrix, outer) + EIGEN_STRONG_INLINE ReverseInnerIterator(const TransposeImpl& xpr, int outer) + : Base(xpr.derived().nestedExpression(), outer) {} inline int row() const { return Base::col(); } inline int col() const { return Base::row(); } diff --git a/Eigen/src/Sparse/SparseTriangular.h b/Eigen/src/Sparse/SparseTriangular.h deleted file mode 100644 index 42e7ff02a..000000000 --- a/Eigen/src/Sparse/SparseTriangular.h +++ /dev/null @@ -1,60 +0,0 @@ -// This file is part of Eigen, a lightweight C++ template library -// for linear algebra. -// -// Copyright (C) 2009 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_SPARSE_TRIANGULAR_H -#define EIGEN_SPARSE_TRIANGULAR_H - -template<typename ExpressionType, int Mode> class SparseTriangular -{ - public: - - typedef typename ei_traits<ExpressionType>::Scalar Scalar; - typedef typename ei_meta_if<ei_must_nest_by_value<ExpressionType>::ret, - ExpressionType, const ExpressionType&>::ret ExpressionTypeNested; - typedef CwiseUnaryOp<ei_scalar_add_op<Scalar>, ExpressionType> ScalarAddReturnType; - - inline SparseTriangular(const ExpressionType& matrix) : m_matrix(matrix) {} - - /** \internal */ - inline const ExpressionType& _expression() const { return m_matrix; } - - template<typename OtherDerived> - typename ei_plain_matrix_type_column_major<OtherDerived>::type - solve(const MatrixBase<OtherDerived>& other) const; - template<typename OtherDerived> void solveInPlace(MatrixBase<OtherDerived>& other) const; - template<typename OtherDerived> void solveInPlace(SparseMatrixBase<OtherDerived>& other) const; - - protected: - ExpressionTypeNested m_matrix; -}; - -template<typename Derived> -template<int Mode> -inline const SparseTriangular<Derived, Mode> -SparseMatrixBase<Derived>::triangular() const -{ - return derived(); -} - -#endif // EIGEN_SPARSE_TRIANGULAR_H diff --git a/Eigen/src/Sparse/SparseTriangularView.h b/Eigen/src/Sparse/SparseTriangularView.h new file mode 100644 index 000000000..6a9461528 --- /dev/null +++ b/Eigen/src/Sparse/SparseTriangularView.h @@ -0,0 +1,95 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2009 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_SPARSE_TRIANGULARVIEW_H +#define EIGEN_SPARSE_TRIANGULARVIEW_H + +template<typename MatrixType, int Mode> +struct ei_traits<SparseTriangularView<MatrixType,Mode> > +: public ei_traits<MatrixType> +{}; + +template<typename MatrixType, int Mode> class SparseTriangularView + : public SparseMatrixBase<SparseTriangularView<MatrixType,Mode> > +{ + enum { SkipFirst = (Mode==LowerTriangular && (!MatrixType::Flags&RowMajorBit)) + || (Mode==UpperTriangular && ( MatrixType::Flags&RowMajorBit)) }; + public: + + class InnerIterator; + + inline int rows() { return m_matrix.rows(); } + inline int cols() { return m_matrix.cols(); } + + typedef typename ei_traits<MatrixType>::Scalar Scalar; + typedef typename ei_meta_if<ei_must_nest_by_value<MatrixType>::ret, + MatrixType, const MatrixType&>::ret MatrixTypeNested; + + inline SparseTriangularView(const MatrixType& matrix) : m_matrix(matrix) {} + + /** \internal */ + inline const MatrixType& nestedExpression() const { return m_matrix; } + + template<typename OtherDerived> + typename ei_plain_matrix_type_column_major<OtherDerived>::type + solve(const MatrixBase<OtherDerived>& other) const; + + template<typename OtherDerived> void solveInPlace(MatrixBase<OtherDerived>& other) const; + template<typename OtherDerived> void solveInPlace(SparseMatrixBase<OtherDerived>& other) const; + + protected: + MatrixTypeNested m_matrix; +}; + +template<typename MatrixType, int Mode> +class SparseTriangularView<MatrixType,Mode>::InnerIterator : public MatrixType::InnerIterator +{ + typedef typename MatrixType::InnerIterator Base; + public: + + EIGEN_STRONG_INLINE InnerIterator(const SparseTriangularView& view, int outer) + : Base(view.nestedExpression(), outer) + { + if(SkipFirst) + while((*this) && this->index()<outer) + ++(*this); + } + inline int row() const { return Base::row(); } + inline int col() const { return Base::col(); } + + EIGEN_STRONG_INLINE operator bool() const + { + return SkipFirst ? Base::operator bool() : (Base::operator bool() && this->index() < this->outer()); + } +}; + +template<typename Derived> +template<int Mode> +inline const SparseTriangularView<Derived, Mode> +SparseMatrixBase<Derived>::triangularView() const +{ + return derived(); +} + +#endif // EIGEN_SPARSE_TRIANGULARVIEW_H diff --git a/Eigen/src/Sparse/SparseUtil.h b/Eigen/src/Sparse/SparseUtil.h index 52781aa46..965565b73 100644 --- a/Eigen/src/Sparse/SparseUtil.h +++ b/Eigen/src/Sparse/SparseUtil.h @@ -69,7 +69,24 @@ enum { RowsAtCompileTime = Eigen::ei_traits<Derived>::RowsAtCompileTime, \ IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; #define EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(Derived) \ -_EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(Derived, Eigen::SparseMatrixBase<Derived>) + _EIGEN_SPARSE_GENERIC_PUBLIC_INTERFACE(Derived, Eigen::SparseMatrixBase<Derived>) + +#define _EIGEN_SPARSE_PUBLIC_INTERFACE(Derived, BaseClass) \ + typedef BaseClass Base; \ + typedef typename Eigen::ei_traits<Derived>::Scalar Scalar; \ + typedef typename Eigen::NumTraits<Scalar>::Real RealScalar; \ + typedef typename Eigen::ei_nested<Derived>::type Nested; \ + enum { RowsAtCompileTime = Eigen::ei_traits<Derived>::RowsAtCompileTime, \ + ColsAtCompileTime = Eigen::ei_traits<Derived>::ColsAtCompileTime, \ + Flags = Eigen::ei_traits<Derived>::Flags, \ + CoeffReadCost = Eigen::ei_traits<Derived>::CoeffReadCost, \ + SizeAtCompileTime = Base::SizeAtCompileTime, \ + IsVectorAtCompileTime = Base::IsVectorAtCompileTime }; \ + using Base::derived; \ + using Base::const_cast_derived; + +#define EIGEN_SPARSE_PUBLIC_INTERFACE(Derived) \ + _EIGEN_SPARSE_PUBLIC_INTERFACE(Derived, Eigen::SparseMatrixBase<Derived>) enum SparseBackend { DefaultBackend, @@ -101,41 +118,33 @@ enum { }; template<typename Derived> class SparseMatrixBase; -template<typename _Scalar, int _Flags = 0> class SparseMatrix; -template<typename _Scalar, int _Flags = 0> class DynamicSparseMatrix; -template<typename _Scalar, int _Flags = 0> class SparseVector; -template<typename _Scalar, int _Flags = 0> class MappedSparseMatrix; - -template<typename MatrixType> class SparseTranspose; -template<typename MatrixType, int Size> class SparseInnerVectorSet; -template<typename Derived> class SparseCwise; -template<typename UnaryOp, typename MatrixType> class SparseCwiseUnaryOp; -template<typename BinaryOp, typename Lhs, typename Rhs> class SparseCwiseBinaryOp; -template<typename ExpressionType, - unsigned int Added, unsigned int Removed> class SparseFlagged; -template<typename ExpressionType, int Mode> class SparseTriangular; -template<typename Lhs, typename Rhs> class SparseDiagonalProduct; - -template<typename Lhs, typename Rhs> struct ei_sparse_product_mode; -template<typename Lhs, typename Rhs, int ProductMode = ei_sparse_product_mode<Lhs,Rhs>::value> struct SparseProductReturnType; - -const int CoherentAccessPattern = 0x1; +template<typename _Scalar, int _Flags = 0> class SparseMatrix; +template<typename _Scalar, int _Flags = 0> class DynamicSparseMatrix; +template<typename _Scalar, int _Flags = 0> class SparseVector; +template<typename _Scalar, int _Flags = 0> class MappedSparseMatrix; + +template<typename MatrixType, int Size> class SparseInnerVectorSet; +template<typename MatrixType, int Mode> class SparseTriangularView; +template<typename MatrixType, unsigned int UpLo> class SparseSelfAdjointView; +template<typename Lhs, typename Rhs> class SparseDiagonalProduct; + + +template<typename Lhs, typename Rhs> class SparseProduct; +template<typename Lhs, typename Rhs> class SparseTimeDenseProduct; +template<typename Lhs, typename Rhs> class DenseTimeSparseProduct; + +template<typename Lhs, typename Rhs, + typename LhsStorage = typename ei_traits<Lhs>::StorageType, + typename RhsStorage = typename ei_traits<Rhs>::StorageType> struct ei_sparse_product_mode; + +template<typename Lhs, typename Rhs> struct SparseProductReturnType; + +const int CoherentAccessPattern = 0x1; const int InnerRandomAccessPattern = 0x2 | CoherentAccessPattern; const int OuterRandomAccessPattern = 0x4 | CoherentAccessPattern; const int RandomAccessPattern = 0x8 | OuterRandomAccessPattern | InnerRandomAccessPattern; -// const int AccessPatternNotSupported = 0x0; -// const int AccessPatternSupported = 0x1; -// -// template<typename MatrixType, int AccessPattern> struct ei_support_access_pattern -// { -// enum { ret = (int(ei_traits<MatrixType>::SupportedAccessPatterns) & AccessPattern) == AccessPattern -// ? AccessPatternSupported -// : AccessPatternNotSupported -// }; -// }; - -template<typename T> class ei_eval<T,IsSparse> +template<typename T> class ei_eval<T,Sparse> { typedef typename ei_traits<T>::Scalar _Scalar; enum { diff --git a/Eigen/src/Sparse/SparseVector.h b/Eigen/src/Sparse/SparseVector.h index b87cae856..5ac3f6be7 100644 --- a/Eigen/src/Sparse/SparseVector.h +++ b/Eigen/src/Sparse/SparseVector.h @@ -38,6 +38,7 @@ template<typename _Scalar, int _Options> struct ei_traits<SparseVector<_Scalar, _Options> > { typedef _Scalar Scalar; + typedef Sparse StorageType; enum { IsColVector = _Options & RowMajorBit ? 0 : 1, @@ -45,7 +46,7 @@ struct ei_traits<SparseVector<_Scalar, _Options> > ColsAtCompileTime = IsColVector ? 1 : Dynamic, MaxRowsAtCompileTime = RowsAtCompileTime, MaxColsAtCompileTime = ColsAtCompileTime, - Flags = SparseBit | _Options, + Flags = _Options, CoeffReadCost = NumTraits<Scalar>::ReadCost, SupportedAccessPatterns = InnerRandomAccessPattern }; diff --git a/Eigen/src/Sparse/TriangularSolver.h b/Eigen/src/Sparse/TriangularSolver.h index cb2bc4d58..5b761e6ad 100644 --- a/Eigen/src/Sparse/TriangularSolver.h +++ b/Eigen/src/Sparse/TriangularSolver.h @@ -52,6 +52,8 @@ struct ei_sparse_solve_triangular_selector<Lhs,Rhs,Mode,LowerTriangular,RowMajor { lastVal = it.value(); lastIndex = it.index(); + if(lastIndex==i) + break; tmp -= lastVal * other.coeff(lastIndex,col); } if (Mode & UnitDiagBit) @@ -160,7 +162,7 @@ struct ei_sparse_solve_triangular_selector<Lhs,Rhs,Mode,UpperTriangular,ColMajor template<typename ExpressionType,int Mode> template<typename OtherDerived> -void SparseTriangular<ExpressionType,Mode>::solveInPlace(MatrixBase<OtherDerived>& other) const +void SparseTriangularView<ExpressionType,Mode>::solveInPlace(MatrixBase<OtherDerived>& other) const { ei_assert(m_matrix.cols() == m_matrix.rows()); ei_assert(m_matrix.cols() == other.rows()); @@ -182,7 +184,7 @@ void SparseTriangular<ExpressionType,Mode>::solveInPlace(MatrixBase<OtherDerived template<typename ExpressionType,int Mode> template<typename OtherDerived> typename ei_plain_matrix_type_column_major<OtherDerived>::type -SparseTriangular<ExpressionType,Mode>::solve(const MatrixBase<OtherDerived>& other) const +SparseTriangularView<ExpressionType,Mode>::solve(const MatrixBase<OtherDerived>& other) const { typename ei_plain_matrix_type_column_major<OtherDerived>::type res(other); solveInPlace(res); @@ -210,10 +212,10 @@ struct ei_sparse_solve_triangular_sparse_selector<Lhs,Rhs,Mode,UpLo,ColMajor> const bool IsLowerTriangular = (UpLo==LowerTriangular); AmbiVector<Scalar> tempVector(other.rows()*2); tempVector.setBounds(0,other.rows()); - + Rhs res(other.rows(), other.cols()); res.reserve(other.nonZeros()); - + for(int col=0 ; col<other.cols() ; ++col) { // FIXME estimate number of non zeros @@ -224,7 +226,7 @@ struct ei_sparse_solve_triangular_sparse_selector<Lhs,Rhs,Mode,UpLo,ColMajor> { tempVector.coeffRef(rhsIt.index()) = rhsIt.value(); } - + for(int i=IsLowerTriangular?0:lhs.cols()-1; IsLowerTriangular?i<lhs.cols():i>=0; i+=IsLowerTriangular?1:-1) @@ -233,7 +235,7 @@ struct ei_sparse_solve_triangular_sparse_selector<Lhs,Rhs,Mode,UpLo,ColMajor> Scalar& ci = tempVector.coeffRef(i); if (ci!=Scalar(0)) { - // find + // find typename Lhs::InnerIterator it(lhs, i); if(!(Mode & UnitDiagBit)) { @@ -260,8 +262,8 @@ struct ei_sparse_solve_triangular_sparse_selector<Lhs,Rhs,Mode,UpLo,ColMajor> } } } - - + + int count = 0; // FIXME compute a reference value to filter zeros for (typename AmbiVector<Scalar>::Iterator it(tempVector/*,1e-12*/); it; ++it) @@ -281,7 +283,7 @@ struct ei_sparse_solve_triangular_sparse_selector<Lhs,Rhs,Mode,UpLo,ColMajor> template<typename ExpressionType,int Mode> template<typename OtherDerived> -void SparseTriangular<ExpressionType,Mode>::solveInPlace(SparseMatrixBase<OtherDerived>& other) const +void SparseTriangularView<ExpressionType,Mode>::solveInPlace(SparseMatrixBase<OtherDerived>& other) const { ei_assert(m_matrix.cols() == m_matrix.rows()); ei_assert(m_matrix.cols() == other.rows()); @@ -300,6 +302,7 @@ void SparseTriangular<ExpressionType,Mode>::solveInPlace(SparseMatrixBase<OtherD // other = otherCopy; } +#ifdef EIGEN2_SUPPORT // deprecated stuff: @@ -321,5 +324,6 @@ SparseMatrixBase<Derived>::solveTriangular(const MatrixBase<OtherDerived>& other derived().solveTriangularInPlace(res); return res; } +#endif // EIGEN2_SUPPORT #endif // EIGEN_SPARSETRIANGULARSOLVER_H diff --git a/Eigen/src/plugins/ArrayCwiseBinaryOps.h b/Eigen/src/plugins/ArrayCwiseBinaryOps.h new file mode 100644 index 000000000..5197d3c4f --- /dev/null +++ b/Eigen/src/plugins/ArrayCwiseBinaryOps.h @@ -0,0 +1,235 @@ + +/** \returns an expression of the coefficient wise product of \c *this and \a other + * + * \sa MatrixBase::cwiseProduct + */ +template<typename OtherDerived> +EIGEN_STRONG_INLINE const EIGEN_CWISE_PRODUCT_RETURN_TYPE(Derived,OtherDerived) +operator*(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const +{ + return EIGEN_CWISE_PRODUCT_RETURN_TYPE(Derived,OtherDerived)(derived(), other.derived()); +} + +/** \returns an expression of the coefficient-wise \< operator of *this and \a other + * + * Example: \include Cwise_less.cpp + * Output: \verbinclude Cwise_less.out + * + * \sa all(), any(), operator>(), operator<=() + */ +EIGEN_MAKE_CWISE_BINARY_OP(operator<,std::less) + +/** \returns an expression of the coefficient-wise \<= operator of *this and \a other + * + * Example: \include Cwise_less_equal.cpp + * Output: \verbinclude Cwise_less_equal.out + * + * \sa all(), any(), operator>=(), operator<() + */ +EIGEN_MAKE_CWISE_BINARY_OP(operator<=,std::less_equal) + +/** \returns an expression of the coefficient-wise \> operator of *this and \a other + * + * Example: \include Cwise_greater.cpp + * Output: \verbinclude Cwise_greater.out + * + * \sa all(), any(), operator>=(), operator<() + */ +EIGEN_MAKE_CWISE_BINARY_OP(operator>,std::greater) + +/** \returns an expression of the coefficient-wise \>= operator of *this and \a other + * + * Example: \include Cwise_greater_equal.cpp + * Output: \verbinclude Cwise_greater_equal.out + * + * \sa all(), any(), operator>(), operator<=() + */ +EIGEN_MAKE_CWISE_BINARY_OP(operator>=,std::greater_equal) + +/** \returns an expression of the coefficient-wise == operator of *this and \a other + * + * \warning this performs an exact comparison, which is generally a bad idea with floating-point types. + * In order to check for equality between two vectors or matrices with floating-point coefficients, it is + * generally a far better idea to use a fuzzy comparison as provided by isApprox() and + * isMuchSmallerThan(). + * + * Example: \include Cwise_equal_equal.cpp + * Output: \verbinclude Cwise_equal_equal.out + * + * \sa all(), any(), isApprox(), isMuchSmallerThan() + */ +EIGEN_MAKE_CWISE_BINARY_OP(operator==,std::equal_to) +// template<typename ExpressionType> +// template<typename OtherDerived> +// inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::equal_to) +// operator==(const MatrixBase<OtherDerived> &other) const +// { +// return EIGEN_CWISE_BINOP_RETURN_TYPE(std::equal_to)(_expression(), other.derived()); +// } + +/** \returns an expression of the coefficient-wise != operator of *this and \a other + * + * \warning this performs an exact comparison, which is generally a bad idea with floating-point types. + * In order to check for equality between two vectors or matrices with floating-point coefficients, it is + * generally a far better idea to use a fuzzy comparison as provided by isApprox() and + * isMuchSmallerThan(). + * + * Example: \include Cwise_not_equal.cpp + * Output: \verbinclude Cwise_not_equal.out + * + * \sa all(), any(), isApprox(), isMuchSmallerThan() + */ +EIGEN_MAKE_CWISE_BINARY_OP(operator!=,std::not_equal_to) +// template<typename ExpressionType> +// template<typename OtherDerived> +// inline const EIGEN_CWISE_BINOP_RETURN_TYPE(std::not_equal_to) +// operator!=(const MatrixBase<OtherDerived> &other) const +// { +// return EIGEN_CWISE_BINOP_RETURN_TYPE(std::not_equal_to)(_expression(), other.derived()); +// } + +// comparisons to scalar value + +#if 0 + +/** \returns an expression of the coefficient-wise \< operator of *this and a scalar \a s + * + * \sa operator<(const MatrixBase<OtherDerived> &) const + */ +inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less) +operator<(Scalar s) const +{ + return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less)(_expression(), + typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s)); +} + +/** \returns an expression of the coefficient-wise \<= operator of *this and a scalar \a s + * + * \sa operator<=(const MatrixBase<OtherDerived> &) const + */ +inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less_equal) +operator<=(Scalar s) const +{ + return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::less_equal)(_expression(), + typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s)); +} + +/** \returns an expression of the coefficient-wise \> operator of *this and a scalar \a s + * + * \sa operator>(const MatrixBase<OtherDerived> &) const + */ +inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater) +operator>(Scalar s) const +{ + return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater)(_expression(), + typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s)); +} + +/** \returns an expression of the coefficient-wise \>= operator of *this and a scalar \a s + * + * \sa operator>=(const MatrixBase<OtherDerived> &) const + */ +inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater_equal) +operator>=(Scalar s) const +{ + return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::greater_equal)(_expression(), + typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s)); +} + +/** \returns an expression of the coefficient-wise == operator of *this and a scalar \a s + * + * \warning this performs an exact comparison, which is generally a bad idea with floating-point types. + * In order to check for equality between two vectors or matrices with floating-point coefficients, it is + * generally a far better idea to use a fuzzy comparison as provided by isApprox() and + * isMuchSmallerThan(). + * + * \sa operator==(const MatrixBase<OtherDerived> &) const + */ +inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::equal_to) +operator==(Scalar s) const +{ + return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::equal_to)(_expression(), + typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s)); +} + +/** \returns an expression of the coefficient-wise != operator of *this and a scalar \a s + * + * \warning this performs an exact comparison, which is generally a bad idea with floating-point types. + * In order to check for equality between two vectors or matrices with floating-point coefficients, it is + * generally a far better idea to use a fuzzy comparison as provided by isApprox() and + * isMuchSmallerThan(). + * + * \sa operator!=(const MatrixBase<OtherDerived> &) const + */ +inline const EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::not_equal_to) +operator!=(Scalar s) const +{ + return EIGEN_CWISE_COMP_TO_SCALAR_RETURN_TYPE(std::not_equal_to)(_expression(), + typename ExpressionType::ConstantReturnType(_expression().rows(), _expression().cols(), s)); +} + +#endif + +// scalar addition + +/** \returns an expression of \c *this with each coeff incremented by the constant \a scalar + * + * Example: \include Cwise_plus.cpp + * Output: \verbinclude Cwise_plus.out + * + * \sa operator+=(), operator-() + */ +inline const CwiseUnaryOp<ei_scalar_add_op<Scalar>, Derived> +operator+(const Scalar& scalar) const +{ + return CwiseUnaryOp<ei_scalar_add_op<Scalar>, Derived>(derived(), ei_scalar_add_op<Scalar>(scalar)); +} + +friend inline const CwiseUnaryOp<ei_scalar_add_op<Scalar>, Derived> +operator+(const Scalar& scalar,const EIGEN_CURRENT_STORAGE_BASE_CLASS<Derived>& other) +{ + return other + scalar; +} + +/** Adds the given \a scalar to each coeff of this expression. + * + * Example: \include Cwise_plus_equal.cpp + * Output: \verbinclude Cwise_plus_equal.out + * + * \sa operator+(), operator-=() + */ +// inline Derived& operator+=(const Scalar& scalar) +// { +// return derived() = *this + scalar; +// } + +/** \returns an expression of \c *this with each coeff decremented by the constant \a scalar + * + * Example: \include Cwise_minus.cpp + * Output: \verbinclude Cwise_minus.out + * + * \sa operator+(), operator-=() + */ +inline const CwiseUnaryOp<ei_scalar_add_op<Scalar>, Derived> +operator-(const Scalar& scalar) const +{ + return *this + (-scalar); +} + +friend inline const CwiseUnaryOp<ei_scalar_add_op<Scalar>, Derived> +operator-(const Scalar& scalar,const EIGEN_CURRENT_STORAGE_BASE_CLASS<Derived>& other) +{ + return other + (-scalar); +} + +/** Substracts the given \a scalar from each coeff of this expression. + * + * Example: \include Cwise_minus_equal.cpp + * Output: \verbinclude Cwise_minus_equal.out + * + * \sa operator+=(), operator-() + */ +// inline Derived& operator-=(const Scalar& scalar) +// { +// return derived() = *this - scalar; +// } diff --git a/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/Eigen/src/plugins/ArrayCwiseUnaryOps.h new file mode 100644 index 000000000..c5c568fea --- /dev/null +++ b/Eigen/src/plugins/ArrayCwiseUnaryOps.h @@ -0,0 +1,162 @@ + + +/** \returns an expression of the coefficient-wise absolute value of \c *this + * + * Example: \include Cwise_abs.cpp + * Output: \verbinclude Cwise_abs.out + * + * \sa abs2() + */ +EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_abs_op<Scalar>, Derived> +abs() const +{ + return derived(); +} + +/** \returns an expression of the coefficient-wise squared absolute value of \c *this + * + * Example: \include Cwise_abs2.cpp + * Output: \verbinclude Cwise_abs2.out + * + * \sa abs(), square() + */ +EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_abs2_op<Scalar>, Derived> +abs2() const +{ + return derived(); +} + +/** \returns an expression of the coefficient-wise exponential of *this. + * + * Example: \include Cwise_exp.cpp + * Output: \verbinclude Cwise_exp.out + * + * \sa pow(), log(), sin(), cos() + */ +inline const CwiseUnaryOp<ei_scalar_exp_op<Scalar>, Derived> +exp() const +{ + return derived(); +} + +/** \returns an expression of the coefficient-wise logarithm of *this. + * + * Example: \include Cwise_log.cpp + * Output: \verbinclude Cwise_log.out + * + * \sa exp() + */ +inline const CwiseUnaryOp<ei_scalar_log_op<Scalar>, Derived> +log() const +{ + return derived(); +} + +/** \returns an expression of the coefficient-wise square root of *this. + * + * Example: \include Cwise_sqrt.cpp + * Output: \verbinclude Cwise_sqrt.out + * + * \sa pow(), square() + */ +inline const CwiseUnaryOp<ei_scalar_sqrt_op<Scalar>, Derived> +sqrt() const +{ + return derived(); +} + +/** \returns an expression of the coefficient-wise cosine of *this. + * + * Example: \include Cwise_cos.cpp + * Output: \verbinclude Cwise_cos.out + * + * \sa sin(), exp() + */ +inline const CwiseUnaryOp<ei_scalar_cos_op<Scalar>, Derived> +cos() const +{ + return derived(); +} + + +/** \returns an expression of the coefficient-wise sine of *this. + * + * Example: \include Cwise_sin.cpp + * Output: \verbinclude Cwise_sin.out + * + * \sa cos(), exp() + */ +inline const CwiseUnaryOp<ei_scalar_sin_op<Scalar>, Derived> +sin() const +{ + return derived(); +} + + +/** \returns an expression of the coefficient-wise power of *this to the given exponent. + * + * Example: \include Cwise_pow.cpp + * Output: \verbinclude Cwise_pow.out + * + * \sa exp(), log() + */ +inline const CwiseUnaryOp<ei_scalar_pow_op<Scalar>, Derived> +pow(const Scalar& exponent) const +{ + return CwiseUnaryOp<ei_scalar_pow_op<Scalar>,Derived> + (derived(), ei_scalar_pow_op<Scalar>(exponent)); +} + + +/** \returns an expression of the coefficient-wise inverse of *this. + * + * Example: \include Cwise_inverse.cpp + * Output: \verbinclude Cwise_inverse.out + * + * \sa operator/(), operator*() + */ +inline const CwiseUnaryOp<ei_scalar_inverse_op<Scalar>, Derived> +inverse() const +{ + return derived(); +} + +/** \returns an expression of the coefficient-wise square of *this. + * + * Example: \include Cwise_square.cpp + * Output: \verbinclude Cwise_square.out + * + * \sa operator/(), operator*(), abs2() + */ +inline const CwiseUnaryOp<ei_scalar_square_op<Scalar>, Derived> +square() const +{ + return derived(); +} + +/** \returns an expression of the coefficient-wise cube of *this. + * + * Example: \include Cwise_cube.cpp + * Output: \verbinclude Cwise_cube.out + * + * \sa square(), pow() + */ +inline const CwiseUnaryOp<ei_scalar_cube_op<Scalar>, Derived> +cube() const +{ + return derived(); +} + +#define EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(METHOD_NAME,FUNCTOR) \ + inline const CwiseUnaryOp<std::binder2nd<FUNCTOR<Scalar> >,Derived> \ + METHOD_NAME(Scalar s) const { \ + return CwiseUnaryOp<std::binder2nd<FUNCTOR<Scalar> >,Derived> \ + (derived(), std::bind2nd(FUNCTOR<Scalar>(), s)); \ + } + +EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator==, std::equal_to); +EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator!=, std::not_equal_to); +EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator<, std::less); +EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator<=, std::less_equal); +EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator>, std::greater); +EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator>=, std::greater_equal); diff --git a/Eigen/src/plugins/CommonCwiseBinaryOps.h b/Eigen/src/plugins/CommonCwiseBinaryOps.h new file mode 100644 index 000000000..762cb3b8c --- /dev/null +++ b/Eigen/src/plugins/CommonCwiseBinaryOps.h @@ -0,0 +1,61 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr> +// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> +// +// 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/>. + +// This file is a base class plugin containing common coefficient wise functions. + +/** \returns an expression of the difference of \c *this and \a other + * + * \note If you want to substract a given scalar from all coefficients, see Cwise::operator-(). + * + * \sa class CwiseBinaryOp, MatrixBase::operator-=() + */ +EIGEN_MAKE_CWISE_BINARY_OP(operator-,ei_scalar_difference_op) + +/** \returns an expression of the sum of \c *this and \a other + * + * \note If you want to add a given scalar to all coefficients, see Cwise::operator+(). + * + * \sa class CwiseBinaryOp, MatrixBase::operator+=() + */ +EIGEN_MAKE_CWISE_BINARY_OP(operator+,ei_scalar_sum_op) + +/** \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 + * of the custom operator (see class CwiseBinaryOp for an example) + * + * Here is an example illustrating the use of custom functors: + * \include class_CwiseBinaryOp.cpp + * Output: \verbinclude class_CwiseBinaryOp.out + * + * \sa class CwiseBinaryOp, MatrixBase::operator+, MatrixBase::operator-, MatrixBase::cwiseProduct + */ +template<typename CustomBinaryOp, typename OtherDerived> +EIGEN_STRONG_INLINE const CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived> +binaryExpr(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other, const CustomBinaryOp& func = CustomBinaryOp()) const +{ + return CwiseBinaryOp<CustomBinaryOp, Derived, OtherDerived>(derived(), other.derived(), func); +} + diff --git a/Eigen/src/plugins/CommonCwiseUnaryOps.h b/Eigen/src/plugins/CommonCwiseUnaryOps.h new file mode 100644 index 000000000..6360ddf7c --- /dev/null +++ b/Eigen/src/plugins/CommonCwiseUnaryOps.h @@ -0,0 +1,179 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr> +// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> +// +// 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/>. + +// This file is a base class plugin containing common coefficient wise functions. + +#ifndef EIGEN_PARSED_BY_DOXYGEN + +/** \internal Represents a scalar multiple of a matrix */ +typedef CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, Derived> ScalarMultipleReturnType; +/** \internal Represents a quotient of a matrix by a scalar*/ +typedef CwiseUnaryOp<ei_scalar_quotient1_op<Scalar>, Derived> ScalarQuotient1ReturnType; +/** \internal the return type of MatrixBase::conjugate() */ +typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex, + const CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Derived>, + const Derived& + >::ret ConjugateReturnType; +/** \internal the return type of MatrixBase::real() const */ +typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex, + const CwiseUnaryOp<ei_scalar_real_op<Scalar>, Derived>, + const Derived& + >::ret RealReturnType; +/** \internal the return type of MatrixBase::real() */ +typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex, + CwiseUnaryView<ei_scalar_real_op<Scalar>, Derived>, + Derived& + >::ret NonConstRealReturnType; +/** \internal the return type of MatrixBase::imag() const */ +typedef CwiseUnaryOp<ei_scalar_imag_op<Scalar>, Derived> ImagReturnType; +/** \internal the return type of MatrixBase::imag() */ +typedef CwiseUnaryView<ei_scalar_imag_op<Scalar>, Derived> NonConstImagReturnType; + +#endif // not EIGEN_PARSED_BY_DOXYGEN + +/** \returns an expression of the opposite of \c *this + */ +EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_opposite_op<typename ei_traits<Derived>::Scalar>,Derived> +operator-() const { return derived(); } + + +/** \returns an expression of \c *this scaled by the scalar factor \a scalar */ +EIGEN_STRONG_INLINE const ScalarMultipleReturnType +operator*(const Scalar& scalar) const +{ + return CwiseUnaryOp<ei_scalar_multiple_op<Scalar>, Derived> + (derived(), ei_scalar_multiple_op<Scalar>(scalar)); +} + +#ifdef EIGEN_PARSED_BY_DOXYGEN +const ScalarMultipleReturnType operator*(const RealScalar& scalar) const; +#endif + +/** \returns an expression of \c *this divided by the scalar value \a scalar */ +EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, Derived> +operator/(const Scalar& scalar) const +{ + return CwiseUnaryOp<ei_scalar_quotient1_op<Scalar>, Derived> + (derived(), ei_scalar_quotient1_op<Scalar>(scalar)); +} + +/** Overloaded for efficient real matrix times complex scalar value */ +EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_multiple2_op<Scalar,std::complex<Scalar> >, Derived> +operator*(const std::complex<Scalar>& scalar) const +{ + return CwiseUnaryOp<ei_scalar_multiple2_op<Scalar,std::complex<Scalar> >, Derived> + (*static_cast<const Derived*>(this), ei_scalar_multiple2_op<Scalar,std::complex<Scalar> >(scalar)); +} + +inline friend const ScalarMultipleReturnType +operator*(const Scalar& scalar, const StorageBaseType& matrix) +{ return matrix*scalar; } + +inline friend const CwiseUnaryOp<ei_scalar_multiple2_op<Scalar,std::complex<Scalar> >, Derived> +operator*(const std::complex<Scalar>& scalar, const StorageBaseType& matrix) +{ return matrix*scalar; } + +/** \returns an expression of *this with the \a Scalar type casted to + * \a NewScalar. + * + * The template parameter \a NewScalar is the type we are casting the scalars to. + * + * \sa class CwiseUnaryOp + */ +template<typename NewType> +typename ei_cast_return_type<Derived,const CwiseUnaryOp<ei_scalar_cast_op<typename ei_traits<Derived>::Scalar, NewType>, Derived> >::type +cast() const +{ + return derived(); +} + +/** \returns an expression of the complex conjugate of \c *this. + * + * \sa adjoint() */ +EIGEN_STRONG_INLINE ConjugateReturnType +conjugate() const +{ + return ConjugateReturnType(derived()); +} + +/** \returns a read-only expression of the real part of \c *this. + * + * \sa imag() */ +EIGEN_STRONG_INLINE RealReturnType +real() const { return derived(); } + +/** \returns an read-only expression of the imaginary part of \c *this. + * + * \sa real() */ +EIGEN_STRONG_INLINE const ImagReturnType +imag() const { return derived(); } + +/** \returns an expression of a custom coefficient-wise unary operator \a func of *this + * + * The template parameter \a CustomUnaryOp is the type of the functor + * of the custom unary operator. + * + * Example: + * \include class_CwiseUnaryOp.cpp + * Output: \verbinclude class_CwiseUnaryOp.out + * + * \sa class CwiseUnaryOp, class CwiseBinarOp, MatrixBase::operator-, Cwise::abs + */ +template<typename CustomUnaryOp> +EIGEN_STRONG_INLINE const CwiseUnaryOp<CustomUnaryOp, Derived> +unaryExpr(const CustomUnaryOp& func = CustomUnaryOp()) const +{ + return CwiseUnaryOp<CustomUnaryOp, Derived>(derived(), func); +} + +/** \returns an expression of a custom coefficient-wise unary operator \a func of *this + * + * The template parameter \a CustomUnaryOp is the type of the functor + * of the custom unary operator. + * + * Example: + * \include class_CwiseUnaryOp.cpp + * Output: \verbinclude class_CwiseUnaryOp.out + * + * \sa class CwiseUnaryOp, class CwiseBinarOp, MatrixBase::operator-, Cwise::abs + */ +template<typename CustomViewOp> +EIGEN_STRONG_INLINE const CwiseUnaryView<CustomViewOp, Derived> +unaryViewExpr(const CustomViewOp& func = CustomViewOp()) const +{ + return CwiseUnaryView<CustomViewOp, Derived>(derived(), func); +} + +/** \returns a non const expression of the real part of \c *this. + * + * \sa imag() */ +EIGEN_STRONG_INLINE NonConstRealReturnType +real() { return derived(); } + +/** \returns a non const expression of the imaginary part of \c *this. + * + * \sa real() */ +EIGEN_STRONG_INLINE NonConstImagReturnType +imag() { return derived(); } diff --git a/Eigen/src/plugins/MatrixCwiseBinaryOps.h b/Eigen/src/plugins/MatrixCwiseBinaryOps.h new file mode 100644 index 000000000..1efe7b314 --- /dev/null +++ b/Eigen/src/plugins/MatrixCwiseBinaryOps.h @@ -0,0 +1,120 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr> +// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> +// +// 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/>. + +// This file is a base class plugin containing matrix specifics coefficient wise functions. + +/** \returns an expression of the Schur product (coefficient wise product) of *this and \a other + * + * Example: \include MatrixBase_cwiseProduct.cpp + * Output: \verbinclude MatrixBase_cwiseProduct.out + * + * \sa class CwiseBinaryOp, cwiseAbs2 + */ +template<typename OtherDerived> +EIGEN_STRONG_INLINE const EIGEN_CWISE_PRODUCT_RETURN_TYPE(Derived,OtherDerived) +cwiseProduct(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const +{ + return EIGEN_CWISE_PRODUCT_RETURN_TYPE(Derived,OtherDerived)(derived(), other.derived()); +} + +/** \returns an expression of the coefficient-wise == operator of *this and \a other + * + * \warning this performs an exact comparison, which is generally a bad idea with floating-point types. + * In order to check for equality between two vectors or matrices with floating-point coefficients, it is + * generally a far better idea to use a fuzzy comparison as provided by MatrixBase::isApprox() and + * MatrixBase::isMuchSmallerThan(). + * + * Example: \include MatrixBase_cwiseEqual.cpp + * Output: \verbinclude MatrixBase_cwiseEqual.out + * + * \sa MatrixBase::cwiseNotEqual(), MatrixBase::isApprox(), MatrixBase::isMuchSmallerThan() + */ +template<typename OtherDerived> +inline const CwiseBinaryOp<std::equal_to<Scalar>, Derived, OtherDerived> +cwiseEqual(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const +{ + return CwiseBinaryOp<std::equal_to<Scalar>, Derived, OtherDerived>(derived(), other.derived()); +} + +/** \returns an expression of the coefficient-wise != operator of *this and \a other + * + * \warning this performs an exact comparison, which is generally a bad idea with floating-point types. + * In order to check for equality between two vectors or matrices with floating-point coefficients, it is + * generally a far better idea to use a fuzzy comparison as provided by MatrixBase::isApprox() and + * MatrixBase::isMuchSmallerThan(). + * + * Example: \include MatrixBase_cwiseNotEqual.cpp + * Output: \verbinclude MatrixBase_cwiseNotEqual.out + * + * \sa MatrixBase::cwiseEqual(), MatrixBase::isApprox(), MatrixBase::isMuchSmallerThan() + */ +template<typename OtherDerived> +inline const CwiseBinaryOp<std::not_equal_to<Scalar>, Derived, OtherDerived> +cwiseNotEqual(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const +{ + return CwiseBinaryOp<std::not_equal_to<Scalar>, Derived, OtherDerived>(derived(), other.derived()); +} + +/** \returns an expression of the coefficient-wise min of *this and \a other + * + * Example: \include MatrixBase_cwiseMin.cpp + * Output: \verbinclude MatrixBase_cwiseMin.out + * + * \sa class CwiseBinaryOp, max() + */ +template<typename OtherDerived> +EIGEN_STRONG_INLINE const CwiseBinaryOp<ei_scalar_min_op<Scalar>, Derived, OtherDerived> +cwiseMin(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const +{ + return CwiseBinaryOp<ei_scalar_min_op<Scalar>, Derived, OtherDerived>(derived(), other.derived()); +} + +/** \returns an expression of the coefficient-wise max of *this and \a other + * + * Example: \include MatrixBase_cwiseMax.cpp + * Output: \verbinclude MatrixBase_cwiseMax.out + * + * \sa class CwiseBinaryOp, min() + */ +template<typename OtherDerived> +EIGEN_STRONG_INLINE const CwiseBinaryOp<ei_scalar_max_op<Scalar>, Derived, OtherDerived> +cwiseMax(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const +{ + return CwiseBinaryOp<ei_scalar_max_op<Scalar>, Derived, OtherDerived>(derived(), other.derived()); +} + +/** \returns an expression of the coefficient-wise quotient of *this and \a other + * + * Example: \include MatrixBase_cwiseQuotient.cpp + * Output: \verbinclude MatrixBase_cwiseQuotient.out + * + * \sa class CwiseBinaryOp, cwiseProduct(), cwiseInverse() + */ +template<typename OtherDerived> +EIGEN_STRONG_INLINE const CwiseBinaryOp<ei_scalar_quotient_op<Scalar>, Derived, OtherDerived> +cwiseQuotient(const EIGEN_CURRENT_STORAGE_BASE_CLASS<OtherDerived> &other) const +{ + return CwiseBinaryOp<ei_scalar_quotient_op<Scalar>, Derived, OtherDerived>(derived(), other.derived()); +} diff --git a/Eigen/src/plugins/MatrixCwiseUnaryOps.h b/Eigen/src/plugins/MatrixCwiseUnaryOps.h new file mode 100644 index 000000000..d75e229fb --- /dev/null +++ b/Eigen/src/plugins/MatrixCwiseUnaryOps.h @@ -0,0 +1,82 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 2008-2009 Gael Guennebaud <g.gael@free.fr> +// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> +// +// 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/>. + +// This file is a base class plugin containing matrix specifics coefficient wise functions. + +/** \returns an expression of the coefficient-wise absolute value of \c *this + * + * Example: \include MatrixBase_cwiseAbs.cpp + * Output: \verbinclude MatrixBase_cwiseAbs.out + * + * \sa cwiseAbs2() + */ +EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_abs_op<Scalar>,Derived> +cwiseAbs() const { return derived(); } + +/** \returns an expression of the coefficient-wise squared absolute value of \c *this + * + * Example: \include MatrixBase_cwiseAbs2.cpp + * Output: \verbinclude MatrixBase_cwiseAbs2.out + * + * \sa cwiseAbs() + */ +EIGEN_STRONG_INLINE const CwiseUnaryOp<ei_scalar_abs2_op<Scalar>,Derived> +cwiseAbs2() const { return derived(); } + +/** \returns an expression of the coefficient-wise square root of *this. + * + * Example: \include MatrixBase_cwiseSqrt.cpp + * Output: \verbinclude MatrixBase_cwiseSqrt.out + * + * \sa cwisePow(), cwiseSquare() + */ +inline const CwiseUnaryOp<ei_scalar_sqrt_op<Scalar>,Derived> +cwiseSqrt() const { return derived(); } + +/** \returns an expression of the coefficient-wise inverse of *this. + * + * Example: \include MatrixBase_cwiseInverse.cpp + * Output: \verbinclude MatrixBase_cwiseInverse.out + * + * \sa cwiseProduct() + */ +inline const CwiseUnaryOp<ei_scalar_inverse_op<Scalar>,Derived> +cwiseInverse() const { return derived(); } + +/** \returns an expression of the coefficient-wise == operator of \c *this and a scalar \a s + * + * \warning this performs an exact comparison, which is generally a bad idea with floating-point types. + * In order to check for equality between two vectors or matrices with floating-point coefficients, it is + * generally a far better idea to use a fuzzy comparison as provided by MatrixBase::isApprox() and + * MatrixBase::isMuchSmallerThan(). + * + * \sa cwiseEqual(const MatrixBase<OtherDerived> &) const + */ +inline const CwiseUnaryOp<std::binder1st<std::equal_to<Scalar> >,Derived> +cwiseEqual(Scalar s) const +{ + return CwiseUnaryOp<std::binder1st<std::equal_to<Scalar> >,Derived> + (derived(), std::bind1st(std::equal_to<Scalar>(), s)); +} |