diff options
-rw-r--r-- | Eigen/Core | 1 | ||||
-rw-r--r-- | Eigen/src/Array/Array.h | 324 | ||||
-rw-r--r-- | Eigen/src/Array/ArrayBase.h | 14 | ||||
-rw-r--r-- | Eigen/src/Array/Random.h | 28 | ||||
-rw-r--r-- | Eigen/src/Core/CwiseNullaryOp.h | 86 | ||||
-rw-r--r-- | Eigen/src/Core/DenseStorageBase.h | 629 | ||||
-rw-r--r-- | Eigen/src/Core/Matrix.h | 610 | ||||
-rw-r--r-- | Eigen/src/Core/util/ForwardDeclarations.h | 3 | ||||
-rw-r--r-- | Eigen/src/Core/util/Macros.h | 13 | ||||
-rw-r--r-- | Eigen/src/Eigen2Support/Cwise.h | 14 | ||||
-rw-r--r-- | Eigen/src/Eigen2Support/CwiseOperators.h | 4 | ||||
-rw-r--r-- | Eigen/src/plugins/ArrayCwiseBinaryOps.h | 18 | ||||
-rw-r--r-- | Eigen/src/plugins/ArrayCwiseUnaryOps.h | 6 | ||||
-rw-r--r-- | Eigen/src/plugins/MatrixCwiseBinaryOps.h | 19 | ||||
-rw-r--r-- | test/product_notemporary.cpp | 4 |
15 files changed, 1226 insertions, 547 deletions
diff --git a/Eigen/Core b/Eigen/Core index a3abe0598..fe1f1a5bf 100644 --- a/Eigen/Core +++ b/Eigen/Core @@ -168,6 +168,7 @@ struct Dense {}; #include "src/Core/ForceAlignedAccess.h" #include "src/Core/ReturnByValue.h" #include "src/Core/NoAlias.h" +#include "src/Core/DenseStorageBase.h" #include "src/Core/Matrix.h" #include "src/Core/SelfCwiseBinaryOp.h" #include "src/Core/CwiseBinaryOp.h" diff --git a/Eigen/src/Array/Array.h b/Eigen/src/Array/Array.h index 2619d8597..ac2ae140d 100644 --- a/Eigen/src/Array/Array.h +++ b/Eigen/src/Array/Array.h @@ -26,4 +26,328 @@ #define EIGEN_ARRAY_H + +// 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)); +// } + + +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, _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> +{ + public: + + typedef DenseStorageBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, ArrayBase, _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> Base; + _EIGEN_DENSE_PUBLIC_INTERFACE(Array) + + 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; + + 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 Matrix& operator=(const MatrixBase<OtherDerived>& other) +// { +// return _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()); } + + /** \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); } + //@} + + #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 index 97b4fd732..980ee6489 100644 --- a/Eigen/src/Array/ArrayBase.h +++ b/Eigen/src/Array/ArrayBase.h @@ -96,13 +96,13 @@ template<typename Derived> class ArrayBase * 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; - /** \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 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*/ diff --git a/Eigen/src/Array/Random.h b/Eigen/src/Array/Random.h index 831e93816..2ef51d1d4 100644 --- a/Eigen/src/Array/Random.h +++ b/Eigen/src/Array/Random.h @@ -136,13 +136,13 @@ inline Derived& DenseBase<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) -{ - resize(size); - return setRandom(); -} +// 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) +// { +// resize(size); +// return setRandom(); +// } /** Resizes to the given size, and sets all coefficients in this expression to random values. * @@ -154,12 +154,12 @@ 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) -{ - resize(rows, cols); - return setRandom(); -} +// 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) +// { +// resize(rows, cols); +// return setRandom(); +// } #endif // EIGEN_RANDOM_H diff --git a/Eigen/src/Core/CwiseNullaryOp.h b/Eigen/src/Core/CwiseNullaryOp.h index 0fc1ce41e..9b4c705cd 100644 --- a/Eigen/src/Core/CwiseNullaryOp.h +++ b/Eigen/src/Core/CwiseNullaryOp.h @@ -278,13 +278,13 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setConstant(const Scalar& value * * \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) -{ - resize(size); - return setConstant(value); -} +// 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) +// { +// resize(size); +// return setConstant(value); +// } /** Resizes to the given size, and sets all coefficients in this expression to the given \a value. * @@ -296,13 +296,13 @@ 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) -{ - resize(rows, cols); - return setConstant(value); -} +// 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) +// { +// resize(rows, cols); +// return setConstant(value); +// } // zero: @@ -408,13 +408,13 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>::setZero() * * \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) -{ - resize(size); - return setConstant(Scalar(0)); -} +// 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) +// { +// resize(size); +// return setConstant(Scalar(0)); +// } /** Resizes to the given size, and sets all coefficients in this expression to zero. * @@ -426,13 +426,13 @@ Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::setZero(int size) * * \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) -{ - resize(rows, cols); - return setConstant(Scalar(0)); -} +// 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) +// { +// resize(rows, cols); +// return setConstant(Scalar(0)); +// } // ones: @@ -534,13 +534,13 @@ EIGEN_STRONG_INLINE Derived& DenseBase<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) -{ - resize(size); - return setConstant(Scalar(1)); -} +// 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) +// { +// resize(size); +// return setConstant(Scalar(1)); +// } /** Resizes to the given size, and sets all coefficients in this expression to one. * @@ -552,13 +552,13 @@ 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) -{ - resize(rows, cols); - return setConstant(Scalar(1)); -} +// 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) +// { +// resize(rows, cols); +// return setConstant(Scalar(1)); +// } // Identity: @@ -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/DenseStorageBase.h b/Eigen/src/Core/DenseStorageBase.h new file mode 100644 index 000000000..67506d80b --- /dev/null +++ b/Eigen/src/Core/DenseStorageBase.h @@ -0,0 +1,629 @@ +// 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, typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> +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<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; + + 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)); + m_storage.resize(rows * cols, rows, cols); + EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + } + + /** 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); + if(RowsAtCompileTime == 1) + m_storage.resize(size, 1, size); + else + m_storage.resize(size, size, 1); + EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + } + + /** 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 MatrixBase<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; + /** Resizes to the given \a size, and sets all coefficients in this expression to the given \a value. + * + * \only_for_vectors + * + * Example: \include Matrix_setConstant_int.cpp + * Output: \verbinclude Matrix_setConstant_int.out + * + * \sa MatrixBase::setConstant(const Scalar&), setConstant(int,int,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&) + */ + Derived& setConstant(int size, const Scalar& value) + { + resize(size); + return setConstant(value); + } + + /** Resizes to the given size, and sets all coefficients in this expression to the given \a value. + * + * \param rows the new number of rows + * \param cols the new number of columns + * + * Example: \include Matrix_setConstant_int_int.cpp + * Output: \verbinclude Matrix_setConstant_int_int.out + * + * \sa MatrixBase::setConstant(const Scalar&), setConstant(int,const Scalar&), class CwiseNullaryOp, MatrixBase::Constant(const Scalar&) + */ + Derived& setConstant(int rows, int cols, const Scalar& value) + { + resize(rows, cols); + return setConstant(value); + } + + using Base::setZero; + Derived& setZero(int size) + { return setConstant(size, Scalar(0)); } + Derived& setZero(int rows, int cols) + { return setConstant(rows, cols, Scalar(0)); } + + using Base::setOnes; + Derived& setOnes(int size) + { return setConstant(size, Scalar(1)); } + Derived& setOnes(int rows, int cols) + { return setConstant(rows, cols, Scalar(1)); } + + using Base::setRandom; + Derived& setRandom(int size) + { + resize(size); + return setRandom(); + } + Derived& setRandom(int rows, int cols) + { + resize(rows, cols); + return setRandom(); + } + + #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(((_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(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 DenseBase<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 DenseBase<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/Matrix.h b/Eigen/src/Core/Matrix.h index 04fbcc59d..6cd989e22 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 @@ -131,10 +124,13 @@ 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, _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> +// : public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > { public: - EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix) + + typedef DenseStorageBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, MatrixBase, _Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> Base; + _EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix) enum { Options = _Options }; typedef typename Base::PlainMatrixType PlainMatrixType; @@ -144,241 +140,18 @@ class Matrix 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)); - m_storage.resize(rows * cols, rows, cols); - EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED - } - - /** 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); - if(RowsAtCompileTime == 1) - m_storage.resize(size, 1, size); - else - m_storage.resize(size, size, 1); - EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED - } - - /** 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)); - } + using Base::base; + using Base::coeff; + using Base::coeffRef; - template<typename OtherDerived> - EIGEN_STRONG_INLINE void conservativeResizeLike(const MatrixBase<OtherDerived>& other) - { - ei_conservative_resize_like_impl<Matrix, OtherDerived>::run(*this, other); - } /** Copies the value of the expression \a other into \c *this with automatic resizing. * @@ -392,7 +165,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 @@ -400,24 +173,25 @@ class Matrix */ EIGEN_STRONG_INLINE Matrix& operator=(const Matrix& other) { - return _set(other); + return Base::_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); - } - +// 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); +// } + + using Base::operator =; using Base::operator +=; using Base::operator -=; using Base::operator *=; @@ -433,17 +207,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 @@ -453,9 +228,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); @@ -466,8 +241,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. @@ -483,7 +258,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; @@ -492,7 +267,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; @@ -505,24 +280,24 @@ 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); } @@ -530,21 +305,21 @@ class Matrix inline ~Matrix() {} /** \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; - } +// 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; } @@ -552,7 +327,8 @@ class Matrix * data pointers. */ template<typename OtherDerived> - void swap(MatrixBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other); + void swap(MatrixBase<OtherDerived> EIGEN_REF_TO_TEMPORARY other) + { this->_swap(other.derived()); } /** \name Map * These are convenience functions returning Map objects. The Map() static functions return unaligned Map objects, @@ -589,21 +365,21 @@ class Matrix { 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); +// 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); using Base::setIdentity; Matrix& setIdentity(int rows, int cols); @@ -628,16 +404,16 @@ class Matrix * 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); - } +// 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. * @@ -650,136 +426,110 @@ class Matrix * * \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); } +// 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 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 _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)); -} +// 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); +// } +// }; /** \defgroup matrixtypedefs Global matrix typedefs * diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index bcd79468c..09c6c9528 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -115,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; diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h index d68538f1a..b3a1955fb 100644 --- a/Eigen/src/Core/util/Macros.h +++ b/Eigen/src/Core/util/Macros.h @@ -353,4 +353,17 @@ using Eigen::ei_cos; 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/Eigen2Support/Cwise.h b/Eigen/src/Eigen2Support/Cwise.h index 03472f051..c8d470228 100644 --- a/Eigen/src/Eigen2Support/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> diff --git a/Eigen/src/Eigen2Support/CwiseOperators.h b/Eigen/src/Eigen2Support/CwiseOperators.h index fc5fe86c6..ac1dc0a7e 100644 --- a/Eigen/src/Eigen2Support/CwiseOperators.h +++ b/Eigen/src/Eigen2Support/CwiseOperators.h @@ -95,10 +95,10 @@ Cwise<ExpressionType>::log() const */ template<typename ExpressionType> template<typename OtherDerived> -EIGEN_STRONG_INLINE const EIGEN_CWISE_PRODUCT_RETURN_TYPE +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(_expression(), other.derived()); + return EIGEN_CWISE_PRODUCT_RETURN_TYPE(ExpressionType,OtherDerived)(_expression(), other.derived()); } /** \returns an expression of the coefficient-wise quotient of *this and \a other diff --git a/Eigen/src/plugins/ArrayCwiseBinaryOps.h b/Eigen/src/plugins/ArrayCwiseBinaryOps.h index 19cb909d7..5197d3c4f 100644 --- a/Eigen/src/plugins/ArrayCwiseBinaryOps.h +++ b/Eigen/src/plugins/ArrayCwiseBinaryOps.h @@ -3,27 +3,13 @@ * * \sa MatrixBase::cwiseProduct */ - -#define EIGEN_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_CWISE_PRODUCT_RETURN_TYPE +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(), other.derived()); + return EIGEN_CWISE_PRODUCT_RETURN_TYPE(Derived,OtherDerived)(derived(), other.derived()); } -#undef EIGEN_CWISE_PRODUCT_RETURN_TYPE - /** \returns an expression of the coefficient-wise \< operator of *this and \a other * * Example: \include Cwise_less.cpp diff --git a/Eigen/src/plugins/ArrayCwiseUnaryOps.h b/Eigen/src/plugins/ArrayCwiseUnaryOps.h index ce69a04b5..c5c568fea 100644 --- a/Eigen/src/plugins/ArrayCwiseUnaryOps.h +++ b/Eigen/src/plugins/ArrayCwiseUnaryOps.h @@ -148,10 +148,10 @@ cube() const } #define EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(METHOD_NAME,FUNCTOR) \ - inline const CwiseUnaryOp<std::binder1st<FUNCTOR<Scalar> >,Derived> \ + inline const CwiseUnaryOp<std::binder2nd<FUNCTOR<Scalar> >,Derived> \ METHOD_NAME(Scalar s) const { \ - return CwiseUnaryOp<std::binder1st<FUNCTOR<Scalar> >,Derived> \ - (derived(), std::bind1st(FUNCTOR<Scalar>(), s)); \ + return CwiseUnaryOp<std::binder2nd<FUNCTOR<Scalar> >,Derived> \ + (derived(), std::bind2nd(FUNCTOR<Scalar>(), s)); \ } EIGEN_MAKE_SCALAR_CWISE_UNARY_OP(operator==, std::equal_to); diff --git a/Eigen/src/plugins/MatrixCwiseBinaryOps.h b/Eigen/src/plugins/MatrixCwiseBinaryOps.h index 2b9621977..1efe7b314 100644 --- a/Eigen/src/plugins/MatrixCwiseBinaryOps.h +++ b/Eigen/src/plugins/MatrixCwiseBinaryOps.h @@ -32,28 +32,13 @@ * * \sa class CwiseBinaryOp, cwiseAbs2 */ - -#define EIGEN_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_CWISE_PRODUCT_RETURN_TYPE +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(), other.derived()); + return EIGEN_CWISE_PRODUCT_RETURN_TYPE(Derived,OtherDerived)(derived(), other.derived()); } -#undef EIGEN_CWISE_PRODUCT_RETURN_TYPE - /** \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. diff --git a/test/product_notemporary.cpp b/test/product_notemporary.cpp index e592afff7..534d23d84 100644 --- a/test/product_notemporary.cpp +++ b/test/product_notemporary.cpp @@ -24,8 +24,8 @@ static int nb_temporaries; -#define EIGEN_DEBUG_MATRIX_CTOR(MTYPE) { \ - if(MTYPE::SizeAtCompileTime==Dynamic) \ +#define EIGEN_DEBUG_MATRIX_CTOR { \ + if(SizeAtCompileTime==Dynamic) \ nb_temporaries++; \ } |