From 50c07e50e8faed8015ab0fae92f2161f3f5f4164 Mon Sep 17 00:00:00 2001 From: Chen-Pang He Date: Sat, 29 Sep 2012 17:41:51 +0800 Subject: Avoid memory manipulation for simplicity, efficiency, and safety. --- .../Eigen/src/MatrixFunctions/MatrixPower.h | 90 ++++++++++++++-------- 1 file changed, 58 insertions(+), 32 deletions(-) (limited to 'unsupported/Eigen/src') diff --git a/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h b/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h index 7beb209eb..bf8bc4424 100644 --- a/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h +++ b/unsupported/Eigen/src/MatrixFunctions/MatrixPower.h @@ -12,6 +12,8 @@ namespace Eigen { +template class MatrixPowerEvaluator; + /** * \ingroup MatrixFunctions_Module * @@ -41,17 +43,19 @@ class MatrixPower : public MatrixPowerBase,MatrixType> * \brief Constructor. * * \param[in] A the base of the matrix power. + * + * \warning Construct with a matrix, not a matrix expression! */ - template - explicit MatrixPower(const MatrixExpression& A); + explicit MatrixPower(const MatrixType& A) : Base(A,0) + { } /** * \brief Return the expression \f$ A^p \f$. * * \param[in] p exponent, a real scalar. */ - const MatrixPowerReturnValue operator()(RealScalar p) - { return MatrixPowerReturnValue(*this, p); } + const MatrixPowerEvaluator operator()(RealScalar p) + { return MatrixPowerEvaluator(*this, p); } /** * \brief Compute the matrix power. @@ -95,12 +99,6 @@ class MatrixPower : public MatrixPowerBase,MatrixType> void computeFracPower(ResultType&, RealScalar); }; -template -template -MatrixPower::MatrixPower(const MatrixExpression& A) : - Base(A, 0) -{ } - template void MatrixPower::compute(MatrixType& res, RealScalar p) { @@ -237,9 +235,10 @@ template void MatrixPower::computeFracPower(ResultType& res, RealScalar p) { if (p) { + eigen_assert(m_conditionNumber); MatrixPowerTriangularAtomic(m_T).compute(m_fT, p); - internal::recompose_complex_schur::IsComplex>::run(m_tmp2, m_fT, m_U); - res = m_tmp2 * res; + internal::recompose_complex_schur::IsComplex>::run(m_tmp1, m_fT, m_U); + res = m_tmp1 * res; } } @@ -249,14 +248,17 @@ class MatrixPowerMatrixProduct : public MatrixPowerProductBase& pow, const Rhs& b, RealScalar p) - : m_pow(pow), m_b(b), m_p(p) { } + MatrixPowerMatrixProduct(MatrixPower& pow, const Rhs& b, RealScalar p) : + m_pow(pow), + m_b(b), + m_p(p) + { } template inline void evalTo(ResultType& res) const { m_pow.compute(m_b, res, m_p); } - Index rows() const { return m_b.rows(); } + Index rows() const { return m_pow.rows(); } Index cols() const { return m_b.cols(); } private: @@ -293,14 +295,8 @@ class MatrixPowerReturnValue : public ReturnByValue(A)), m_p(p), m_del(true) { } - - MatrixPowerReturnValue(MatrixPower& pow, RealScalar p) - : m_pow(pow), m_p(p), m_del(false) { } - - ~MatrixPowerReturnValue() - { if (m_del) delete &m_pow; } + MatrixPowerReturnValue(const Derived& A, RealScalar p) : m_A(A), m_p(p) + { } /** * \brief Compute the matrix power. @@ -310,7 +306,7 @@ class MatrixPowerReturnValue : public ReturnByValue inline void evalTo(ResultType& res) const - { m_pow.compute(res, m_p); } + { MatrixPower(m_A.eval()).compute(res, m_p); } /** * \brief Return the expression \f$ A^p b \f$. @@ -321,16 +317,45 @@ class MatrixPowerReturnValue : public ReturnByValue const MatrixPowerMatrixProduct operator*(const MatrixBase& b) const - { return MatrixPowerMatrixProduct(m_pow, b.derived(), m_p); } + { + MatrixPower Apow(m_A.eval()); + return MatrixPowerMatrixProduct(Apow, b.derived(), m_p); + } + + Index rows() const { return m_A.rows(); } + Index cols() const { return m_A.cols(); } + + private: + const Derived& m_A; + const RealScalar m_p; + MatrixPowerReturnValue& operator=(const MatrixPowerReturnValue&); +}; + +template +class MatrixPowerEvaluator : public ReturnByValue > +{ + public: + typedef typename MatrixType::RealScalar RealScalar; + typedef typename MatrixType::Index Index; + + MatrixPowerEvaluator(MatrixPower& pow, RealScalar p) : m_pow(pow), m_p(p) + { } + + template + inline void evalTo(ResultType& res) const + { m_pow.compute(res, m_p); } + + template + const MatrixPowerMatrixProduct operator*(const MatrixBase& b) const + { return MatrixPowerMatrixProduct(m_pow, b.derived(), m_p); } Index rows() const { return m_pow.rows(); } Index cols() const { return m_pow.cols(); } private: - MatrixPower& m_pow; + MatrixPower& m_pow; const RealScalar m_p; - const bool m_del; // whether to delete the pointer at destruction - MatrixPowerReturnValue& operator=(const MatrixPowerReturnValue&); + MatrixPowerEvaluator& operator=(const MatrixPowerEvaluator&); }; namespace internal { @@ -342,6 +367,10 @@ template struct traits > { typedef typename Derived::PlainObject ReturnType; }; +template +struct traits > +{ typedef MatrixType ReturnType; }; + template struct traits > : traits,Lhs,Rhs> > @@ -350,10 +379,7 @@ struct traits > template const MatrixPowerReturnValue MatrixBase::pow(RealScalar p) const -{ - eigen_assert(rows() == cols()); - return MatrixPowerReturnValue(derived(), p); -} +{ return MatrixPowerReturnValue(derived(), p); } } // namespace Eigen -- cgit v1.2.3