diff options
author | Gael Guennebaud <g.gael@free.fr> | 2010-02-10 14:08:47 +0100 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2010-02-10 14:08:47 +0100 |
commit | 0ca67afe6abbe9c19a8254d50daaddd2a343531c (patch) | |
tree | e832b7636a793c649ad947304c0369ed94167ac5 /Eigen | |
parent | 71b64d34987ae7d3fbe70f0098c12a7c65b41084 (diff) |
finally here is a simple solution making (a*b).diagonal() even faster than a.lazyProduct(b).diagonal() !!
Diffstat (limited to 'Eigen')
-rw-r--r-- | Eigen/src/Core/Product.h | 15 | ||||
-rw-r--r-- | Eigen/src/Core/ProductBase.h | 13 | ||||
-rw-r--r-- | Eigen/src/Core/products/CoeffBasedProduct.h | 16 |
3 files changed, 34 insertions, 10 deletions
diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index 5903476b5..af05773ee 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -447,17 +447,12 @@ MatrixBase<Derived>::operator*(const MatrixBase<OtherDerived> &other) const /** \returns an expression of the matrix product of \c *this and \a other without implicit evaluation. * - * The coefficients of the product will be computed as requested that is particularly useful when you - * only want to compute a small fraction of the result's coefficients. - * Here is an example: - * \code - * MatrixXf a(10,10), b(10,10); - * (a*b).diagonal().sum(); // here a*b is entirely computed into a 10x10 temporary matrix - * a.lazyProduct(b).diagonal().sum(); // here a*b is evaluated in a lazy manner, - * // so only the diagonal coefficients will be computed - * \endcode + * The returned product will behave like any other expressions: the coefficients of the product will be + * computed once at a time as requested. This might be useful in some extremely rare cases when only + * a small and no coherent fraction of the result's coefficients have to be computed. * - * \warning This version of the matrix product can be much much slower if all coefficients have to be computed anyways. + * \warning This version of the matrix product can be much much slower. So use it only if you know + * what you are doing and that you measured a true speed improvement. * * \sa operator*(const MatrixBase&) */ diff --git a/Eigen/src/Core/ProductBase.h b/Eigen/src/Core/ProductBase.h index bbd77f059..481e7c760 100644 --- a/Eigen/src/Core/ProductBase.h +++ b/Eigen/src/Core/ProductBase.h @@ -83,6 +83,9 @@ class ProductBase : public MatrixBase<Derived> typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType; typedef typename ei_cleantype<ActualRhsType>::type _ActualRhsType; + // Diagonal of a product: no need to evaluate the arguments because they are going to be evaluated only once + typedef CoeffBasedProduct<LhsNested, RhsNested, 0> FullyLazyCoeffBaseProductType; + public: typedef typename Base::PlainMatrixType PlainMatrixType; @@ -121,6 +124,16 @@ class ProductBase : public MatrixBase<Derived> return m_result; } + const Diagonal<FullyLazyCoeffBaseProductType,0> diagonal() const + { return FullyLazyCoeffBaseProductType(m_lhs, m_rhs); } + + template<int Index> + const Diagonal<FullyLazyCoeffBaseProductType,Index> diagonal() const + { return FullyLazyCoeffBaseProductType(m_lhs, m_rhs); } + + const Diagonal<FullyLazyCoeffBaseProductType,Dynamic> diagonal(int index) const + { return FullyLazyCoeffBaseProductType(m_lhs, m_rhs).diagonal(index); } + protected: const LhsNested m_lhs; diff --git a/Eigen/src/Core/products/CoeffBasedProduct.h b/Eigen/src/Core/products/CoeffBasedProduct.h index c9d333072..f030d59b5 100644 --- a/Eigen/src/Core/products/CoeffBasedProduct.h +++ b/Eigen/src/Core/products/CoeffBasedProduct.h @@ -127,8 +127,14 @@ class CoeffBasedProduct Unroll ? InnerSize-1 : Dynamic, _LhsNested, _RhsNested, Scalar> ScalarCoeffImpl; + typedef CoeffBasedProduct<LhsNested,RhsNested,NestByRefBit> LazyCoeffBasedProductType; + public: + inline CoeffBasedProduct(const CoeffBasedProduct& other) + : Base(), m_lhs(other.m_lhs), m_rhs(other.m_rhs) + {} + template<typename Lhs, typename Rhs> inline CoeffBasedProduct(const Lhs& lhs, const Rhs& rhs) : m_lhs(lhs), m_rhs(rhs) @@ -185,6 +191,16 @@ class CoeffBasedProduct const _LhsNested& lhs() const { return m_lhs; } const _RhsNested& rhs() const { return m_rhs; } + const Diagonal<LazyCoeffBasedProductType,0> diagonal() const + { return reinterpret_cast<const LazyCoeffBasedProductType&>(*this); } + + template<int Index> + const Diagonal<LazyCoeffBasedProductType,Index> diagonal() const + { return reinterpret_cast<const LazyCoeffBasedProductType&>(*this); } + + const Diagonal<LazyCoeffBasedProductType,Dynamic> diagonal(int index) const + { return reinterpret_cast<const LazyCoeffBasedProductType&>(*this).diagonal(index); } + protected: const LhsNested m_lhs; const RhsNested m_rhs; |