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)) 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 diff --git a/Eigen/src/Array/Replicate.h b/Eigen/src/Array/Replicate.h index cd23e0d6f..46a06a61c 100644 --- a/Eigen/src/Array/Replicate.h +++ b/Eigen/src/Array/Replicate.h @@ -90,8 +90,29 @@ 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 + 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; @@ -139,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 diff --git a/Eigen/src/Core/CwiseBinaryOp.h b/Eigen/src/Core/CwiseBinaryOp.h index 9ed005dce..df13d3aad 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; } diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h index ecce3ad05..74945fc79 100644 --- a/Eigen/src/Core/DenseBase.h +++ b/Eigen/src/Core/DenseBase.h @@ -491,8 +491,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); 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 d0ba7328f..eb7e93b91 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -46,10 +46,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; @@ -163,6 +172,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/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()); 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(); } 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); }