From dd9ff1b9a67c7757dcf566c05b2ee5cbfac6c715 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Tue, 9 Mar 2010 09:04:21 +0100 Subject: [PATCH 01/12] Fix MSVC warnings. --- Eigen/src/Core/DenseBase.h | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h index 52a883811..29a95b8db 100644 --- a/Eigen/src/Core/DenseBase.h +++ b/Eigen/src/Core/DenseBase.h @@ -501,8 +501,12 @@ template class DenseBase * 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::type eval() const - { return typename ei_eval::type(derived()); } + inline const typename ei_eval::type eval() const + { + // MSVC cannot honor strong inlining when the return type + // is a dynamic matrix + return typename ei_eval::type(derived()); + } template void swap(DenseBase EIGEN_REF_TO_TEMPORARY other); From b20b393a4e1aa4a5103ac27ec4ba573bb14e9332 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Wed, 10 Mar 2010 17:12:45 +0100 Subject: [PATCH 02/12] Enable resizing of Arrays. --- Eigen/src/Array/Array.h | 3 +++ 1 file changed, 3 insertions(+) diff --git a/Eigen/src/Array/Array.h b/Eigen/src/Array/Array.h index 91a091152..8a53b8c3e 100644 --- a/Eigen/src/Array/Array.h +++ b/Eigen/src/Array/Array.h @@ -44,6 +44,9 @@ class Array typedef typename Base::PlainObject PlainObject; protected: + template + friend struct ei_conservative_resize_like_impl; + using Base::m_storage; public: enum { NeedsToAlign = (!(Options&DontAlign)) From 2a82b162d7a3f415c7589c326a38f3b73b8ffced Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Wed, 10 Mar 2010 17:13:07 +0100 Subject: [PATCH 03/12] Nest expression within MatrixWrapper by value. --- Eigen/src/Array/ArrayWrapper.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Eigen/src/Array/ArrayWrapper.h b/Eigen/src/Array/ArrayWrapper.h index 0075dd537..4ac240899 100644 --- a/Eigen/src/Array/ArrayWrapper.h +++ b/Eigen/src/Array/ArrayWrapper.h @@ -188,7 +188,7 @@ class MatrixWrapper : public MatrixBase > } protected: - const NestedExpressionType& m_expression; + const NestedExpressionType m_expression; }; #endif // EIGEN_ARRAYWRAPPER_H From 3e08c22028933be56078bdbeb1684dfafbf536d7 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Thu, 11 Mar 2010 12:41:46 -0500 Subject: [PATCH 04/12] attempt to fix #101 --- Eigen/src/Core/util/ForwardDeclarations.h | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index aa01fdab2..129b78e6a 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -41,10 +41,19 @@ template class NestByValue; template class ForceAlignedAccess; template class SwapWrapper; template class Minor; -// MSVC will not compile when the expression ei_traits::Flags&DirectAccessBit -// is put into brackets like (ei_traits::Flags&DirectAccessBit)! + +// MSVC has a big bug: when the expression ei_traits::Flags&DirectAccessBit ? HasDirectAccess : NoDirectAccess +// is used as default template parameter value here, it gets mis-evaluated as just ei_traits::Flags +// Moreover, adding brackets tends to give compilation errors with MSVC. +// Solution: defer that to a helper struct. +template +struct ei_block_direct_access_status +{ + enum { ret = ei_traits::Flags&DirectAccessBit ? HasDirectAccess : NoDirectAccess }; +}; template::Flags&DirectAccessBit ? HasDirectAccess : NoDirectAccess> class Block; + int _DirectAccessStatus = ei_block_direct_access_status::ret> class Block; + template class VectorBlock; template class Transpose; template class Conjugate; From b9644f332330a7242fa13e8194e87ba4b5678f58 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Sat, 13 Mar 2010 13:15:27 +0100 Subject: [PATCH 05/12] Propagate fixed size dimensions if available (on MSVC it leads >2.5x speedup for some reductions). --- Eigen/src/Core/CwiseBinaryOp.h | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/Eigen/src/Core/CwiseBinaryOp.h b/Eigen/src/Core/CwiseBinaryOp.h index 9ed005dce..fc455350c 100644 --- a/Eigen/src/Core/CwiseBinaryOp.h +++ b/Eigen/src/Core/CwiseBinaryOp.h @@ -121,8 +121,20 @@ class CwiseBinaryOp : ei_no_assignment_operator, 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 int rows() const { + // return the fixed size type if available to enable compile time optimizations + if (ei_traits::type>::RowsAtCompileTime==Dynamic) + return m_rhs.rows(); + else + return m_lhs.rows(); + } + EIGEN_STRONG_INLINE int cols() const { + // return the fixed size type if available to enable compile time optimizations + if (ei_traits::type>::ColsAtCompileTime==Dynamic) + return m_rhs.cols(); + else + return m_lhs.cols(); + } /** \returns the left hand side nested expression */ const _LhsNested& lhs() const { return m_lhs; } From fc20e6fd5579bd88d519083037376bd1f96781cd Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Sat, 13 Mar 2010 14:33:39 +0100 Subject: [PATCH 06/12] Try to avoid modulo operations in Replicate if possible. --- Eigen/src/Array/Replicate.h | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/Eigen/src/Array/Replicate.h b/Eigen/src/Array/Replicate.h index cd23e0d6f..31fc28c35 100644 --- a/Eigen/src/Array/Replicate.h +++ b/Eigen/src/Array/Replicate.h @@ -76,7 +76,7 @@ template class Replicate THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE) ei_assert(RowFactor!=Dynamic && ColFactor!=Dynamic); } - + template inline Replicate(const OriginalMatrixType& matrix, int rowFactor, int colFactor) : m_matrix(matrix), m_rowFactor(rowFactor), m_colFactor(colFactor) @@ -90,7 +90,14 @@ template class Replicate inline Scalar coeff(int row, int col) const { - return m_matrix.coeff(row%m_matrix.rows(), col%m_matrix.cols()); + // try to avoid using modulo; this is a pure optimization strategy + // - it is assumed unlikely that RowFactor==1 && ColFactor==1 + if (RowFactor==1) + return m_matrix.coeff(m_matrix.rows(), col%m_matrix.cols()); + else if (ColFactor==1) + return m_matrix.coeff(row%m_matrix.rows(), m_matrix.cols()); + else + return m_matrix.coeff(row%m_matrix.rows(), col%m_matrix.cols()); } protected: From 0e5a232dae3e503279c31ad5ab8f2ab85f171b08 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Sun, 14 Mar 2010 11:58:44 +0100 Subject: [PATCH 07/12] Ups - again a missing typename. --- Eigen/src/Core/CwiseBinaryOp.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Eigen/src/Core/CwiseBinaryOp.h b/Eigen/src/Core/CwiseBinaryOp.h index fc455350c..df13d3aad 100644 --- a/Eigen/src/Core/CwiseBinaryOp.h +++ b/Eigen/src/Core/CwiseBinaryOp.h @@ -123,14 +123,14 @@ class CwiseBinaryOp : ei_no_assignment_operator, EIGEN_STRONG_INLINE int rows() const { // return the fixed size type if available to enable compile time optimizations - if (ei_traits::type>::RowsAtCompileTime==Dynamic) + if (ei_traits::type>::RowsAtCompileTime==Dynamic) return m_rhs.rows(); else return m_lhs.rows(); } EIGEN_STRONG_INLINE int cols() const { // return the fixed size type if available to enable compile time optimizations - if (ei_traits::type>::ColsAtCompileTime==Dynamic) + if (ei_traits::type>::ColsAtCompileTime==Dynamic) return m_rhs.cols(); else return m_lhs.cols(); From 6d08f71a2dcedf2eee26b1b04f2359502100e078 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Sun, 14 Mar 2010 12:09:29 +0100 Subject: [PATCH 08/12] Removed strong inlines which cannot always be inlined. --- Eigen/src/Sparse/SparseMatrixBase.h | 2 +- Eigen/src/Sparse/SparseProduct.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/Eigen/src/Sparse/SparseMatrixBase.h b/Eigen/src/Sparse/SparseMatrixBase.h index cf1a5d7bf..d269ce604 100644 --- a/Eigen/src/Sparse/SparseMatrixBase.h +++ b/Eigen/src/Sparse/SparseMatrixBase.h @@ -557,7 +557,7 @@ template class SparseMatrixBase : public EigenBase * 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::type eval() const + inline const typename ei_eval::type eval() const { return typename ei_eval::type(derived()); } // template diff --git a/Eigen/src/Sparse/SparseProduct.h b/Eigen/src/Sparse/SparseProduct.h index a56bc7601..efc676a69 100644 --- a/Eigen/src/Sparse/SparseProduct.h +++ b/Eigen/src/Sparse/SparseProduct.h @@ -562,7 +562,7 @@ class DenseTimeSparseProduct // sparse * sparse template template -EIGEN_STRONG_INLINE const typename SparseProductReturnType::Type +inline const typename SparseProductReturnType::Type SparseMatrixBase::operator*(const SparseMatrixBase &other) const { return typename SparseProductReturnType::Type(derived(), other.derived()); @@ -571,7 +571,7 @@ SparseMatrixBase::operator*(const SparseMatrixBase &other // sparse * dense template template -EIGEN_STRONG_INLINE const SparseTimeDenseProduct +inline const SparseTimeDenseProduct SparseMatrixBase::operator*(const MatrixBase &other) const { return SparseTimeDenseProduct(derived(), other.derived()); From d68b85744f82e879b555e72d90cc8feefd96c2c0 Mon Sep 17 00:00:00 2001 From: Hauke Heibel Date: Sun, 14 Mar 2010 13:01:10 +0100 Subject: [PATCH 09/12] Replaced strong with weak inlines in CwiseUnaryOp. --- Eigen/src/plugins/CommonCwiseUnaryOps.h | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/Eigen/src/plugins/CommonCwiseUnaryOps.h b/Eigen/src/plugins/CommonCwiseUnaryOps.h index 6360ddf7c..ec76ca38f 100644 --- a/Eigen/src/plugins/CommonCwiseUnaryOps.h +++ b/Eigen/src/plugins/CommonCwiseUnaryOps.h @@ -55,12 +55,12 @@ typedef CwiseUnaryView, Derived> NonConstImagReturnTyp /** \returns an expression of the opposite of \c *this */ -EIGEN_STRONG_INLINE const CwiseUnaryOp::Scalar>,Derived> +inline const CwiseUnaryOp::Scalar>,Derived> operator-() const { return derived(); } /** \returns an expression of \c *this scaled by the scalar factor \a scalar */ -EIGEN_STRONG_INLINE const ScalarMultipleReturnType +inline const ScalarMultipleReturnType operator*(const Scalar& scalar) const { return CwiseUnaryOp, Derived> @@ -72,7 +72,7 @@ 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::Scalar>, Derived> +inline const CwiseUnaryOp::Scalar>, Derived> operator/(const Scalar& scalar) const { return CwiseUnaryOp, Derived> @@ -80,7 +80,7 @@ operator/(const Scalar& scalar) const } /** Overloaded for efficient real matrix times complex scalar value */ -EIGEN_STRONG_INLINE const CwiseUnaryOp >, Derived> +inline const CwiseUnaryOp >, Derived> operator*(const std::complex& scalar) const { return CwiseUnaryOp >, Derived> @@ -112,7 +112,7 @@ cast() const /** \returns an expression of the complex conjugate of \c *this. * * \sa adjoint() */ -EIGEN_STRONG_INLINE ConjugateReturnType +inline ConjugateReturnType conjugate() const { return ConjugateReturnType(derived()); @@ -121,13 +121,13 @@ conjugate() const /** \returns a read-only expression of the real part of \c *this. * * \sa imag() */ -EIGEN_STRONG_INLINE RealReturnType +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 +inline const ImagReturnType imag() const { return derived(); } /** \returns an expression of a custom coefficient-wise unary operator \a func of *this @@ -142,7 +142,7 @@ imag() const { return derived(); } * \sa class CwiseUnaryOp, class CwiseBinarOp, MatrixBase::operator-, Cwise::abs */ template -EIGEN_STRONG_INLINE const CwiseUnaryOp +inline const CwiseUnaryOp unaryExpr(const CustomUnaryOp& func = CustomUnaryOp()) const { return CwiseUnaryOp(derived(), func); @@ -160,7 +160,7 @@ unaryExpr(const CustomUnaryOp& func = CustomUnaryOp()) const * \sa class CwiseUnaryOp, class CwiseBinarOp, MatrixBase::operator-, Cwise::abs */ template -EIGEN_STRONG_INLINE const CwiseUnaryView +inline const CwiseUnaryView unaryViewExpr(const CustomViewOp& func = CustomViewOp()) const { return CwiseUnaryView(derived(), func); @@ -169,11 +169,11 @@ unaryViewExpr(const CustomViewOp& func = CustomViewOp()) const /** \returns a non const expression of the real part of \c *this. * * \sa imag() */ -EIGEN_STRONG_INLINE NonConstRealReturnType +inline NonConstRealReturnType real() { return derived(); } /** \returns a non const expression of the imaginary part of \c *this. * * \sa real() */ -EIGEN_STRONG_INLINE NonConstImagReturnType +inline NonConstImagReturnType imag() { return derived(); } From d536fef1bb44280bb96bbdc5418c033f17f982a8 Mon Sep 17 00:00:00 2001 From: Gael Guennebaud Date: Mon, 15 Mar 2010 10:39:00 +0100 Subject: [PATCH 10/12] fix and extend replicate optimization, and add the packet method though it is currently disabled --- Eigen/src/Array/Replicate.h | 30 ++++++++++++++++++++++-------- 1 file changed, 22 insertions(+), 8 deletions(-) diff --git a/Eigen/src/Array/Replicate.h b/Eigen/src/Array/Replicate.h index 31fc28c35..661a7b561 100644 --- a/Eigen/src/Array/Replicate.h +++ b/Eigen/src/Array/Replicate.h @@ -76,7 +76,7 @@ template class Replicate THE_MATRIX_OR_EXPRESSION_THAT_YOU_PASSED_DOES_NOT_HAVE_THE_EXPECTED_TYPE) ei_assert(RowFactor!=Dynamic && ColFactor!=Dynamic); } - + template inline Replicate(const OriginalMatrixType& matrix, int rowFactor, int colFactor) : m_matrix(matrix), m_rowFactor(rowFactor), m_colFactor(colFactor) @@ -91,14 +91,28 @@ template class Replicate inline Scalar coeff(int row, int col) const { // try to avoid using modulo; this is a pure optimization strategy - // - it is assumed unlikely that RowFactor==1 && ColFactor==1 - if (RowFactor==1) - return m_matrix.coeff(m_matrix.rows(), col%m_matrix.cols()); - else if (ColFactor==1) - return m_matrix.coeff(row%m_matrix.rows(), m_matrix.cols()); - else - return m_matrix.coeff(row%m_matrix.rows(), col%m_matrix.cols()); + const int actual_row = ei_traits::RowsAtCompileTime==1 ? 0 + : RowFactor==1 ? row + : row%m_matrix.rows(); + const int actual_col = ei_traits::ColsAtCompileTime==1 ? 0 + : ColFactor==1 ? col + : col%m_matrix.cols(); + + return m_matrix.coeff(actual_row, actual_col); } + template + inline PacketScalar packet(int row, int col) const + { + const int actual_row = ei_traits::RowsAtCompileTime==1 ? 0 + : RowFactor==1 ? row + : row%m_matrix.rows(); + const int actual_col = ei_traits::ColsAtCompileTime==1 ? 0 + : ColFactor==1 ? col + : col%m_matrix.cols(); + + return m_matrix.template packet(actual_row, actual_col); + } + protected: const typename MatrixType::Nested m_matrix; From 04a4e22c58a21e084e088e1f64d3b2f8e134debb Mon Sep 17 00:00:00 2001 From: Jitse Niesen Date: Tue, 16 Mar 2010 17:26:55 +0000 Subject: [PATCH 11/12] API change: ei_matrix_exponential(A) --> A.exp(), etc As discussed on mailing list; see http://listengine.tuxfamily.org/lists.tuxfamily.org/eigen/2010/02/msg00190.html --- Eigen/src/Core/MatrixBase.h | 10 +++ Eigen/src/Core/util/ForwardDeclarations.h | 11 ++++ .../src/MatrixFunctions/MatrixExponential.h | 11 ++-- .../src/MatrixFunctions/MatrixFunction.h | 61 ++++++++----------- .../Eigen/src/MatrixFunctions/StemFunction.h | 7 --- .../doc/examples/MatrixExponential.cpp | 4 +- unsupported/doc/examples/MatrixFunction.cpp | 2 +- unsupported/doc/examples/MatrixSine.cpp | 4 +- unsupported/doc/examples/MatrixSinh.cpp | 4 +- unsupported/test/matrix_exponential.cpp | 16 ++--- unsupported/test/matrix_function.cpp | 19 +++--- 11 files changed, 74 insertions(+), 75 deletions(-) diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index ac79de66d..fd9577ca4 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -372,6 +372,16 @@ template class MatrixBase template void applyOnTheRight(int p, int q, const PlanarRotation& j); +///////// MatrixFunctions module ///////// + + typedef typename ei_stem_function::type StemFunction; + const MatrixExponentialReturnValue exp() const; + const MatrixFunctionReturnValue matrixFunction(StemFunction f) const; + const MatrixFunctionReturnValue cosh() const; + const MatrixFunctionReturnValue sinh() const; + const MatrixFunctionReturnValue cos() const; + const MatrixFunctionReturnValue sin() const; + #ifdef EIGEN2_SUPPORT template Derived& operator+=(const Flagged, 0, diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index 129b78e6a..073366d73 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -167,6 +167,17 @@ template class Translation; template class UniformScaling; template class Homogeneous; +// MatrixFunctions module +template struct MatrixExponentialReturnValue; +template struct MatrixFunctionReturnValue; +template +struct ei_stem_function +{ + typedef std::complex::Real> ComplexScalar; + typedef ComplexScalar type(ComplexScalar, int); +}; + + #ifdef EIGEN2_SUPPORT template class Cwise; #endif diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h index 2c761e648..3ef91a7b2 100644 --- a/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h +++ b/unsupported/Eigen/src/MatrixFunctions/MatrixExponential.h @@ -290,8 +290,8 @@ void MatrixExponential::computeUV(double) * This class holds the argument to the matrix exponential until it * is assigned or evaluated for some other reason (so the argument * should not be changed in the meantime). It is the return type of - * ei_matrix_exponential() and most of the time this is the only way - * it is used. + * MatrixBase::exp() and most of the time this is the only way it is + * used. */ template struct MatrixExponentialReturnValue : public ReturnByValue > @@ -381,11 +381,10 @@ struct ei_traits > * \c complex or \c complex . */ template -MatrixExponentialReturnValue -ei_matrix_exponential(const MatrixBase &M) +const MatrixExponentialReturnValue MatrixBase::exp() const { - ei_assert(M.rows() == M.cols()); - return MatrixExponentialReturnValue(M.derived()); + ei_assert(rows() == cols()); + return MatrixExponentialReturnValue(derived()); } #endif // EIGEN_MATRIX_EXPONENTIAL diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h b/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h index e8069154c..72e42aa7c 100644 --- a/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h +++ b/unsupported/Eigen/src/MatrixFunctions/MatrixFunction.h @@ -59,7 +59,7 @@ class MatrixFunction * \param[out] result the function \p f applied to \p A, as * specified in the constructor. * - * See ei_matrix_function() for details on how this computation + * See MatrixBase::matrixFunction() for details on how this computation * is implemented. */ template @@ -486,8 +486,8 @@ typename MatrixFunction::DynMatrixType MatrixFunction class MatrixFunctionReturnValue : public ReturnByValue > @@ -533,6 +533,9 @@ struct ei_traits > }; +/********** MatrixBase methods **********/ + + /** \ingroup MatrixFunctions_Module * * \brief Compute a matrix function. @@ -571,7 +574,7 @@ struct ei_traits > * \end{array} \right]. \f] * This corresponds to a rotation of \f$ \frac14\pi \f$ radians around * the z-axis. This is the same example as used in the documentation - * of ei_matrix_exponential(). + * of MatrixBase::exp(). * * \include MatrixFunction.cpp * Output: \verbinclude MatrixFunction.out @@ -580,16 +583,14 @@ struct ei_traits > * \c x, even though the matrix \c A is over the reals. Instead of * \c expfn, we could also have used StdStemFunctions::exp: * \code - * ei_matrix_function(A, StdStemFunctions >::exp, &B); + * A.matrixFunction(StdStemFunctions >::exp, &B); * \endcode */ template -MatrixFunctionReturnValue -ei_matrix_function(const MatrixBase &M, - typename ei_stem_function::Scalar>::type f) +const MatrixFunctionReturnValue MatrixBase::matrixFunction(typename ei_stem_function::Scalar>::type f) const { - ei_assert(M.rows() == M.cols()); - return MatrixFunctionReturnValue(M.derived(), f); + ei_assert(rows() == cols()); + return MatrixFunctionReturnValue(derived(), f); } /** \ingroup MatrixFunctions_Module @@ -599,19 +600,17 @@ ei_matrix_function(const MatrixBase &M, * \param[in] M a square matrix. * \returns expression representing \f$ \sin(M) \f$. * - * This function calls ei_matrix_function() with StdStemFunctions::sin(). + * This function calls matrixFunction() with StdStemFunctions::sin(). * * \include MatrixSine.cpp * Output: \verbinclude MatrixSine.out */ template -MatrixFunctionReturnValue -ei_matrix_sin(const MatrixBase& M) +const MatrixFunctionReturnValue MatrixBase::sin() const { - ei_assert(M.rows() == M.cols()); - typedef typename ei_traits::Scalar Scalar; + ei_assert(rows() == cols()); typedef typename ei_stem_function::ComplexScalar ComplexScalar; - return MatrixFunctionReturnValue(M.derived(), StdStemFunctions::sin); + return MatrixFunctionReturnValue(derived(), StdStemFunctions::sin); } /** \ingroup MatrixFunctions_Module @@ -621,18 +620,16 @@ ei_matrix_sin(const MatrixBase& M) * \param[in] M a square matrix. * \returns expression representing \f$ \cos(M) \f$. * - * This function calls ei_matrix_function() with StdStemFunctions::cos(). + * This function calls matrixFunction() with StdStemFunctions::cos(). * * \sa ei_matrix_sin() for an example. */ template -MatrixFunctionReturnValue -ei_matrix_cos(const MatrixBase& M) +const MatrixFunctionReturnValue MatrixBase::cos() const { - ei_assert(M.rows() == M.cols()); - typedef typename ei_traits::Scalar Scalar; + ei_assert(rows() == cols()); typedef typename ei_stem_function::ComplexScalar ComplexScalar; - return MatrixFunctionReturnValue(M.derived(), StdStemFunctions::cos); + return MatrixFunctionReturnValue(derived(), StdStemFunctions::cos); } /** \ingroup MatrixFunctions_Module @@ -642,19 +639,17 @@ ei_matrix_cos(const MatrixBase& M) * \param[in] M a square matrix. * \returns expression representing \f$ \sinh(M) \f$ * - * This function calls ei_matrix_function() with StdStemFunctions::sinh(). + * This function calls matrixFunction() with StdStemFunctions::sinh(). * * \include MatrixSinh.cpp * Output: \verbinclude MatrixSinh.out */ template -MatrixFunctionReturnValue -ei_matrix_sinh(const MatrixBase& M) +const MatrixFunctionReturnValue MatrixBase::sinh() const { - ei_assert(M.rows() == M.cols()); - typedef typename ei_traits::Scalar Scalar; + ei_assert(rows() == cols()); typedef typename ei_stem_function::ComplexScalar ComplexScalar; - return MatrixFunctionReturnValue(M.derived(), StdStemFunctions::sinh); + return MatrixFunctionReturnValue(derived(), StdStemFunctions::sinh); } /** \ingroup MatrixFunctions_Module @@ -664,18 +659,16 @@ ei_matrix_sinh(const MatrixBase& M) * \param[in] M a square matrix. * \returns expression representing \f$ \cosh(M) \f$ * - * This function calls ei_matrix_function() with StdStemFunctions::cosh(). + * This function calls matrixFunction() with StdStemFunctions::cosh(). * * \sa ei_matrix_sinh() for an example. */ template -MatrixFunctionReturnValue -ei_matrix_cosh(const MatrixBase& M) +const MatrixFunctionReturnValue MatrixBase::cosh() const { - ei_assert(M.rows() == M.cols()); - typedef typename ei_traits::Scalar Scalar; + ei_assert(rows() == cols()); typedef typename ei_stem_function::ComplexScalar ComplexScalar; - return MatrixFunctionReturnValue(M.derived(), StdStemFunctions::cosh); + return MatrixFunctionReturnValue(derived(), StdStemFunctions::cosh); } #endif // EIGEN_MATRIX_FUNCTION diff --git a/unsupported/Eigen/src/MatrixFunctions/StemFunction.h b/unsupported/Eigen/src/MatrixFunctions/StemFunction.h index 90965c7dd..260690b63 100644 --- a/unsupported/Eigen/src/MatrixFunctions/StemFunction.h +++ b/unsupported/Eigen/src/MatrixFunctions/StemFunction.h @@ -25,13 +25,6 @@ #ifndef EIGEN_STEM_FUNCTION #define EIGEN_STEM_FUNCTION -template -struct ei_stem_function -{ - typedef std::complex::Real> ComplexScalar; - typedef ComplexScalar type(ComplexScalar, int); -}; - /** \ingroup MatrixFunctions_Module * \brief Stem functions corresponding to standard mathematical functions. */ diff --git a/unsupported/doc/examples/MatrixExponential.cpp b/unsupported/doc/examples/MatrixExponential.cpp index 60ef315d7..ebd3b9675 100644 --- a/unsupported/doc/examples/MatrixExponential.cpp +++ b/unsupported/doc/examples/MatrixExponential.cpp @@ -12,7 +12,5 @@ int main() pi/4, 0, 0, 0, 0, 0; std::cout << "The matrix A is:\n" << A << "\n\n"; - - MatrixXd B = ei_matrix_exponential(A); - std::cout << "The matrix exponential of A is:\n" << B << "\n\n"; + std::cout << "The matrix exponential of A is:\n" << A.exp() << "\n\n"; } diff --git a/unsupported/doc/examples/MatrixFunction.cpp b/unsupported/doc/examples/MatrixFunction.cpp index ccef85cef..a4172e4ae 100644 --- a/unsupported/doc/examples/MatrixFunction.cpp +++ b/unsupported/doc/examples/MatrixFunction.cpp @@ -19,5 +19,5 @@ int main() std::cout << "The matrix A is:\n" << A << "\n\n"; std::cout << "The matrix exponential of A is:\n" - << ei_matrix_function(A, expfn) << "\n\n"; + << A.matrixFunction(expfn) << "\n\n"; } diff --git a/unsupported/doc/examples/MatrixSine.cpp b/unsupported/doc/examples/MatrixSine.cpp index e85e6a754..9eea9a081 100644 --- a/unsupported/doc/examples/MatrixSine.cpp +++ b/unsupported/doc/examples/MatrixSine.cpp @@ -8,10 +8,10 @@ int main() MatrixXd A = MatrixXd::Random(3,3); std::cout << "A = \n" << A << "\n\n"; - MatrixXd sinA = ei_matrix_sin(A); + MatrixXd sinA = A.sin(); std::cout << "sin(A) = \n" << sinA << "\n\n"; - MatrixXd cosA = ei_matrix_cos(A); + MatrixXd cosA = A.cos(); std::cout << "cos(A) = \n" << cosA << "\n\n"; // The matrix functions satisfy sin^2(A) + cos^2(A) = I, diff --git a/unsupported/doc/examples/MatrixSinh.cpp b/unsupported/doc/examples/MatrixSinh.cpp index 89566d87a..f77186724 100644 --- a/unsupported/doc/examples/MatrixSinh.cpp +++ b/unsupported/doc/examples/MatrixSinh.cpp @@ -8,10 +8,10 @@ int main() MatrixXf A = MatrixXf::Random(3,3); std::cout << "A = \n" << A << "\n\n"; - MatrixXf sinhA = ei_matrix_sinh(A); + MatrixXf sinhA = A.sinh(); std::cout << "sinh(A) = \n" << sinhA << "\n\n"; - MatrixXf coshA = ei_matrix_cosh(A); + MatrixXf coshA = A.cosh(); std::cout << "cosh(A) = \n" << coshA << "\n\n"; // The matrix functions satisfy cosh^2(A) - sinh^2(A) = I, diff --git a/unsupported/test/matrix_exponential.cpp b/unsupported/test/matrix_exponential.cpp index 61f30334d..66e52e100 100644 --- a/unsupported/test/matrix_exponential.cpp +++ b/unsupported/test/matrix_exponential.cpp @@ -57,11 +57,11 @@ void test2dRotation(double tol) angle = static_cast(pow(10, i / 5. - 2)); B << cos(angle), sin(angle), -sin(angle), cos(angle); - C = ei_matrix_function(angle*A, expfn); + C = (angle*A).matrixFunction(expfn); std::cout << "test2dRotation: i = " << i << " error funm = " << relerr(C, B); VERIFY(C.isApprox(B, static_cast(tol))); - C = ei_matrix_exponential(angle*A); + C = (angle*A).exp(); std::cout << " error expm = " << relerr(C, B) << "\n"; VERIFY(C.isApprox(B, static_cast(tol))); } @@ -82,11 +82,11 @@ void test2dHyperbolicRotation(double tol) A << 0, angle*imagUnit, -angle*imagUnit, 0; B << ch, sh*imagUnit, -sh*imagUnit, ch; - C = ei_matrix_function(A, expfn); + C = A.matrixFunction(expfn); std::cout << "test2dHyperbolicRotation: i = " << i << " error funm = " << relerr(C, B); VERIFY(C.isApprox(B, static_cast(tol))); - C = ei_matrix_exponential(A); + C = A.exp(); std::cout << " error expm = " << relerr(C, B) << "\n"; VERIFY(C.isApprox(B, static_cast(tol))); } @@ -106,11 +106,11 @@ void testPascal(double tol) for (int j=0; j<=i; j++) B(i,j) = static_cast(binom(i,j)); - C = ei_matrix_function(A, expfn); + C = A.matrixFunction(expfn); std::cout << "testPascal: size = " << size << " error funm = " << relerr(C, B); VERIFY(C.isApprox(B, static_cast(tol))); - C = ei_matrix_exponential(A); + C = A.exp(); std::cout << " error expm = " << relerr(C, B) << "\n"; VERIFY(C.isApprox(B, static_cast(tol))); } @@ -132,11 +132,11 @@ void randomTest(const MatrixType& m, double tol) for(int i = 0; i < g_repeat; i++) { m1 = MatrixType::Random(rows, cols); - m2 = ei_matrix_function(m1, expfn) * ei_matrix_function(-m1, expfn); + m2 = m1.matrixFunction(expfn) * (-m1).matrixFunction(expfn); std::cout << "randomTest: error funm = " << relerr(identity, m2); VERIFY(identity.isApprox(m2, static_cast(tol))); - m2 = ei_matrix_exponential(m1) * ei_matrix_exponential(-m1); + m2 = m1.exp() * (-m1).exp(); std::cout << " error expm = " << relerr(identity, m2) << "\n"; VERIFY(identity.isApprox(m2, static_cast(tol))); } diff --git a/unsupported/test/matrix_function.cpp b/unsupported/test/matrix_function.cpp index e40af7b4e..16995d836 100644 --- a/unsupported/test/matrix_function.cpp +++ b/unsupported/test/matrix_function.cpp @@ -114,8 +114,7 @@ void testMatrixExponential(const MatrixType& A) typedef typename NumTraits::Real RealScalar; typedef std::complex ComplexScalar; - VERIFY_IS_APPROX(ei_matrix_exponential(A), - ei_matrix_function(A, StdStemFunctions::exp)); + VERIFY_IS_APPROX(A.exp(), A.matrixFunction(StdStemFunctions::exp)); } template @@ -123,10 +122,8 @@ void testHyperbolicFunctions(const MatrixType& A) { // Need to use absolute error because of possible cancellation when // adding/subtracting expA and expmA. - MatrixType expA = ei_matrix_exponential(A); - MatrixType expmA = ei_matrix_exponential(-A); - VERIFY_IS_APPROX_ABS(ei_matrix_sinh(A), (expA - expmA) / 2); - VERIFY_IS_APPROX_ABS(ei_matrix_cosh(A), (expA + expmA) / 2); + VERIFY_IS_APPROX_ABS(A.sinh(), (A.exp() - (-A).exp()) / 2); + VERIFY_IS_APPROX_ABS(A.cosh(), (A.exp() + (-A).exp()) / 2); } template @@ -143,15 +140,13 @@ void testGonioFunctions(const MatrixType& A) ComplexMatrix Ac = A.template cast(); - ComplexMatrix exp_iA = ei_matrix_exponential(imagUnit * Ac); - ComplexMatrix exp_miA = ei_matrix_exponential(-imagUnit * Ac); + ComplexMatrix exp_iA = (imagUnit * Ac).exp(); + ComplexMatrix exp_miA = (-imagUnit * Ac).exp(); - MatrixType sinA = ei_matrix_sin(A); - ComplexMatrix sinAc = sinA.template cast(); + ComplexMatrix sinAc = A.sin().template cast(); VERIFY_IS_APPROX_ABS(sinAc, (exp_iA - exp_miA) / (two*imagUnit)); - MatrixType cosA = ei_matrix_cos(A); - ComplexMatrix cosAc = cosA.template cast(); + ComplexMatrix cosAc = A.cos().template cast(); VERIFY_IS_APPROX_ABS(cosAc, (exp_iA + exp_miA) / 2); } From 089bd8951211f8771cfc0a8143812c4fb0aaeb4e Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Thu, 18 Mar 2010 20:10:24 -0400 Subject: [PATCH 12/12] compile with gcc 4.5 --- Eigen/src/Array/Replicate.h | 4 ++-- Eigen/src/Array/VectorwiseOp.h | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Eigen/src/Array/Replicate.h b/Eigen/src/Array/Replicate.h index 661a7b561..46a06a61c 100644 --- a/Eigen/src/Array/Replicate.h +++ b/Eigen/src/Array/Replicate.h @@ -160,10 +160,10 @@ DenseBase::replicate(int rowFactor,int colFactor) const * \sa VectorwiseOp::replicate(), DenseBase::replicate(), class Replicate */ template -const Replicate +const typename VectorwiseOp::ReplicateReturnType VectorwiseOp::replicate(int factor) const { - return Replicate + return typename VectorwiseOp::ReplicateReturnType (_expression(),Direction==Vertical?factor:1,Direction==Horizontal?factor:1); } diff --git a/Eigen/src/Array/VectorwiseOp.h b/Eigen/src/Array/VectorwiseOp.h index 06d999b14..50cfa7a5e 100644 --- a/Eigen/src/Array/VectorwiseOp.h +++ b/Eigen/src/Array/VectorwiseOp.h @@ -384,8 +384,8 @@ template class VectorwiseOp const Reverse reverse() const { return Reverse( _expression() ); } - const Replicate - replicate(int factor) const; + typedef Replicate ReplicateReturnType; + const ReplicateReturnType replicate(int factor) const; /** \nonstableyet * \return an expression of the replication of each column (or row) of \c *this