diff options
author | Benoit Jacob <jacob.benoit.1@gmail.com> | 2009-08-04 17:47:27 +0200 |
---|---|---|
committer | Benoit Jacob <jacob.benoit.1@gmail.com> | 2009-08-04 17:47:27 +0200 |
commit | b183a4f879d16b6a8d001b83b21300329291e569 (patch) | |
tree | 8014201b12bb60a457ac1b056759b94f4d409af9 | |
parent | ab6302376cc07886d3f31b38cbba55ead84ff353 (diff) | |
parent | 7d607048a926052e8acfb5cc18cb0be557fa6447 (diff) |
merge
-rw-r--r-- | Eigen/Core | 1 | ||||
-rw-r--r-- | Eigen/src/Core/Matrix.h | 20 | ||||
-rw-r--r-- | Eigen/src/Core/MatrixBase.h | 19 | ||||
-rw-r--r-- | Eigen/src/Core/ProductBase.h | 153 | ||||
-rw-r--r-- | Eigen/src/Core/SelfAdjointView.h | 84 | ||||
-rw-r--r-- | Eigen/src/Core/products/TriangularMatrixMatrix.h | 48 | ||||
-rw-r--r-- | Eigen/src/Core/products/TriangularMatrixVector.h | 43 | ||||
-rw-r--r-- | Eigen/src/Core/util/ForwardDeclarations.h | 1 | ||||
-rw-r--r-- | Eigen/src/Geometry/Homogeneous.h | 16 | ||||
-rw-r--r-- | Eigen/src/Geometry/RotationBase.h | 7 | ||||
-rw-r--r-- | Eigen/src/Geometry/Transform.h | 10 | ||||
-rw-r--r-- | Eigen/src/Geometry/Translation.h | 6 | ||||
-rw-r--r-- | test/product_notemporary.cpp | 10 |
13 files changed, 239 insertions, 179 deletions
diff --git a/Eigen/Core b/Eigen/Core index 463529123..cd942b3c6 100644 --- a/Eigen/Core +++ b/Eigen/Core @@ -178,6 +178,7 @@ namespace Eigen { #include "src/Core/Swap.h" #include "src/Core/CommaInitializer.h" #include "src/Core/util/BlasUtil.h" +#include "src/Core/ProductBase.h" #include "src/Core/Product.h" #include "src/Core/products/GeneralMatrixMatrix.h" #include "src/Core/products/GeneralMatrixVector.h" diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h index c31acabca..848236bac 100644 --- a/Eigen/src/Core/Matrix.h +++ b/Eigen/src/Core/Matrix.h @@ -339,11 +339,18 @@ class Matrix return Base::operator=(func); } + template<typename ProductDerived, typename Lhs, typename Rhs> + EIGEN_STRONG_INLINE Matrix& operator=(const ProductBase<ProductDerived,Lhs,Rhs>& other) + { + resize(other.rows(), other.cols()); + return Base::operator=(other); + } + using Base::operator +=; using Base::operator -=; using Base::operator *=; using Base::operator /=; - + /** Default constructor. * * For fixed-size matrices, does nothing. @@ -444,6 +451,15 @@ class Matrix resize(other.rows(), other.cols()); other.evalTo(*this); } + + template<typename ProductDerived, typename Lhs, typename Rhs> + EIGEN_STRONG_INLINE Matrix(const ProductBase<ProductDerived,Lhs,Rhs>& other) + { + _check_template_params(); + resize(other.rows(), other.cols()); + other.evalTo(*this); + } + /** Destructor */ inline ~Matrix() {} @@ -605,7 +621,7 @@ class Matrix #ifdef EIGEN_DEBUG_MATRIX_CTOR EIGEN_DEBUG_MATRIX_CTOR(Matrix); #endif - + EIGEN_STATIC_ASSERT(((_Rows >= _MaxRows) && (_Cols >= _MaxCols) && (_MaxRows >= 0) diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index f23188e77..f94764731 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -38,14 +38,14 @@ template<typename Derived> struct AnyMatrixBase { typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType; - + Derived& derived() { return *static_cast<Derived*>(this); } const Derived& derived() const { return *static_cast<const Derived*>(this); } /** \returns the number of rows. \sa cols(), RowsAtCompileTime */ inline int rows() const { return derived().rows(); } /** \returns the number of columns. \sa rows(), ColsAtCompileTime*/ inline int cols() const { return derived().cols(); } - + template<typename Dest> inline void evalTo(Dest& dst) const { derived().evalTo(dst); } @@ -55,7 +55,7 @@ template<typename Derived> struct AnyMatrixBase evalToDense(res); dst += res; } - + template<typename Dest> inline void subToDense(Dest& dst) const { typename Dest::PlainMatrixType res(rows(),cols()); @@ -318,6 +318,17 @@ template<typename Derived> class MatrixBase Derived& operator-=(const AnyMatrixBase<OtherDerived> &other) { other.derived().subToDense(derived()); return derived(); } + + template<typename ProductDerived, typename Lhs, typename Rhs> + Derived& operator=(const ProductBase<ProductDerived, Lhs, Rhs> &other); + + template<typename ProductDerived, typename Lhs, typename Rhs> + Derived& operator+=(const ProductBase<ProductDerived, Lhs, Rhs> &other); + + template<typename ProductDerived, typename Lhs, typename Rhs> + Derived& operator-=(const ProductBase<ProductDerived, Lhs, Rhs> &other); + + template<typename OtherDerived,typename OtherEvalType> Derived& operator=(const ReturnByValue<OtherDerived,OtherEvalType>& func); @@ -776,7 +787,7 @@ template<typename Derived> class MatrixBase template<typename EssentialPart> void applyHouseholderOnTheRight(const EssentialPart& essential, const RealScalar& beta); - + #ifdef EIGEN_MATRIXBASE_PLUGIN #include EIGEN_MATRIXBASE_PLUGIN diff --git a/Eigen/src/Core/ProductBase.h b/Eigen/src/Core/ProductBase.h new file mode 100644 index 000000000..1f146babf --- /dev/null +++ b/Eigen/src/Core/ProductBase.h @@ -0,0 +1,153 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. +// +// Copyright (C) 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 +// 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_PRODUCTBASE_H +#define EIGEN_PRODUCTBASE_H + +/** \class ProductBase + * + */ +template<typename Derived, typename _Lhs, typename _Rhs> +struct ei_traits<ProductBase<Derived,_Lhs,_Rhs> > +{ + typedef typename ei_cleantype<_Lhs>::type Lhs; + typedef typename ei_cleantype<_Rhs>::type Rhs; + typedef typename ei_traits<Lhs>::Scalar Scalar; + enum { + RowsAtCompileTime = ei_traits<Lhs>::RowsAtCompileTime, + ColsAtCompileTime = ei_traits<Rhs>::ColsAtCompileTime, + MaxRowsAtCompileTime = ei_traits<Lhs>::MaxRowsAtCompileTime, + MaxColsAtCompileTime = ei_traits<Rhs>::MaxColsAtCompileTime, + Flags = EvalBeforeNestingBit, + CoeffReadCost = 0 // FIXME why is it needed ? + }; +}; +* +// enforce evaluation before nesting +template<typename Derived, typename Lhs, typename Rhs,int N,typename EvalType> +struct ei_nested<ProductBase<Derived,Lhs,Rhs>, N, EvalType> +{ + typedef EvalType type; +}; + +#define EIGEN_PRODUCT_PUBLIC_INTERFACE(Derived) \ + typedef ProductBase<Derived, Lhs, Rhs > ProductBaseType; \ + _EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, ProductBaseType) \ + typedef typename Base::LhsNested LhsNested; \ + typedef typename Base::_LhsNested _LhsNested; \ + typedef typename Base::LhsBlasTraits LhsBlasTraits; \ + typedef typename Base::ActualLhsType ActualLhsType; \ + typedef typename Base::_ActualLhsType _ActualLhsType; \ + typedef typename Base::RhsNested RhsNested; \ + typedef typename Base::_RhsNested _RhsNested; \ + typedef typename Base::RhsBlasTraits RhsBlasTraits; \ + typedef typename Base::ActualRhsType ActualRhsType; \ + typedef typename Base::_ActualRhsType _ActualRhsType; \ + using Base::m_lhs; \ + using Base::m_rhs; + +template<typename Derived, typename Lhs, typename Rhs> +class ProductBase : public MatrixBase<Derived> +{ + public: + _EIGEN_GENERIC_PUBLIC_INTERFACE(ProductBase,MatrixBase<Derived>) + + typedef typename Lhs::Nested LhsNested; + typedef typename ei_cleantype<LhsNested>::type _LhsNested; + typedef ei_blas_traits<_LhsNested> LhsBlasTraits; + typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType; + typedef typename ei_cleantype<ActualLhsType>::type _ActualLhsType; + + typedef typename Rhs::Nested RhsNested; + typedef typename ei_cleantype<RhsNested>::type _RhsNested; + typedef ei_blas_traits<_RhsNested> RhsBlasTraits; + typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType; + typedef typename ei_cleantype<ActualRhsType>::type _ActualRhsType; + + using Base::derived; + typedef typename Base::PlainMatrixType PlainMatrixType; + + ProductBase(const Lhs& lhs, const Rhs& rhs) + : m_lhs(lhs), m_rhs(rhs) + {} + + inline int rows() const { return m_lhs.rows(); } + inline int cols() const { return m_rhs.cols(); } + + template<typename Dest> + inline void evalTo(Dest& dst) const { dst.setZero(); addTo(dst,1); } + + template<typename Dest> + inline void addTo(Dest& dst) const { addTo(dst,1); } + + template<typename Dest> + inline void subTo(Dest& dst) const { addTo(dst,-1); } + + template<typename Dest> + inline void addTo(Dest& dst,Scalar alpha) const { derived().addTo(dst,alpha); } + + PlainMatrixType eval() const + { + PlainMatrixType res(rows(), cols()); + res.setZero(); + evalTo(res); + return res; + } + + protected: + + const LhsNested m_lhs; + const RhsNested m_rhs; + + private: + + // discard coeff methods + void coeff(int,int) const; + void coeffRef(int,int); + void coeff(int) const; + void coeffRef(int); +}; + +template<typename Derived> +template<typename ProductDerived, typename Lhs, typename Rhs> +Derived& MatrixBase<Derived>::operator=(const ProductBase<ProductDerived,Lhs,Rhs>& other) +{ + other.evalTo(derived()); return derived(); +} + +template<typename Derived> +template<typename ProductDerived, typename Lhs, typename Rhs> +Derived& MatrixBase<Derived>::operator+=(const ProductBase<ProductDerived,Lhs,Rhs>& other) +{ + other.addTo(derived()); return derived(); +} + +template<typename Derived> +template<typename ProductDerived, typename Lhs, typename Rhs> +Derived& MatrixBase<Derived>::operator-=(const ProductBase<ProductDerived,Lhs,Rhs>& other) +{ + other.subTo(derived()); return derived(); +} + +#endif // EIGEN_PRODUCTBASE_H diff --git a/Eigen/src/Core/SelfAdjointView.h b/Eigen/src/Core/SelfAdjointView.h index 0a4ba17c0..883edd165 100644 --- a/Eigen/src/Core/SelfAdjointView.h +++ b/Eigen/src/Core/SelfAdjointView.h @@ -202,50 +202,22 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, SelfAdjoint, Dynami template<typename Lhs, int LhsMode, typename Rhs> struct ei_traits<SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true> > - : ei_traits<Matrix<typename ei_traits<Rhs>::Scalar,Lhs::RowsAtCompileTime,Rhs::ColsAtCompileTime> > + : ei_traits<ProductBase<SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true>, Lhs, Rhs> > {}; template<typename Lhs, int LhsMode, typename Rhs> struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true> - : public AnyMatrixBase<SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true> > + : public ProductBase<SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true>, Lhs, Rhs > { - typedef typename Lhs::Scalar Scalar; - - typedef typename Lhs::Nested LhsNested; - typedef typename ei_cleantype<LhsNested>::type _LhsNested; - typedef ei_blas_traits<_LhsNested> LhsBlasTraits; - typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType; - typedef typename ei_cleantype<ActualLhsType>::type _ActualLhsType; - - typedef typename Rhs::Nested RhsNested; - typedef typename ei_cleantype<RhsNested>::type _RhsNested; - typedef ei_blas_traits<_RhsNested> RhsBlasTraits; - typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType; - typedef typename ei_cleantype<ActualRhsType>::type _ActualRhsType; + EIGEN_PRODUCT_PUBLIC_INTERFACE(SelfadjointProductMatrix) enum { LhsUpLo = LhsMode&(UpperTriangularBit|LowerTriangularBit) }; - SelfadjointProductMatrix(const Lhs& lhs, const Rhs& rhs) - : m_lhs(lhs), m_rhs(rhs) - {} - - inline int rows() const { return m_lhs.rows(); } - inline int cols() const { return m_rhs.cols(); } + SelfadjointProductMatrix(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {} - template<typename Dest> inline void addToDense(Dest& dst) const - { evalTo(dst,1); } - template<typename Dest> inline void subToDense(Dest& dst) const - { evalTo(dst,-1); } - - template<typename Dest> void evalToDense(Dest& dst) const - { - dst.setZero(); - evalTo(dst,1); - } - - template<typename Dest> void evalTo(Dest& dst, Scalar alpha) const + template<typename Dest> void addTo(Dest& dst, Scalar alpha) const { ei_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols()); @@ -265,9 +237,6 @@ struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true> actualAlpha // scale factor ); } - - const LhsNested m_lhs; - const RhsNested m_rhs; }; /*************************************************************************** @@ -276,33 +245,16 @@ struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,0,true> template<typename Lhs, int LhsMode, typename Rhs, int RhsMode> struct ei_traits<SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,RhsMode,false> > - : ei_traits<Matrix<typename ei_traits<Rhs>::Scalar,Lhs::RowsAtCompileTime,Rhs::ColsAtCompileTime> > + : ei_traits<ProductBase<SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,RhsMode,false>, Lhs, Rhs> > {}; template<typename Lhs, int LhsMode, typename Rhs, int RhsMode> struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,RhsMode,false> - : public AnyMatrixBase<SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,RhsMode,false> > + : public ProductBase<SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,RhsMode,false>, Lhs, Rhs > { - SelfadjointProductMatrix(const Lhs& lhs, const Rhs& rhs) - : m_lhs(lhs), m_rhs(rhs) - {} - - inline int rows() const { return m_lhs.rows(); } - inline int cols() const { return m_rhs.cols(); } + EIGEN_PRODUCT_PUBLIC_INTERFACE(SelfadjointProductMatrix) - typedef typename Lhs::Scalar Scalar; - - typedef typename Lhs::Nested LhsNested; - typedef typename ei_cleantype<LhsNested>::type _LhsNested; - typedef ei_blas_traits<_LhsNested> LhsBlasTraits; - typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType; - typedef typename ei_cleantype<ActualLhsType>::type _ActualLhsType; - - typedef typename Rhs::Nested RhsNested; - typedef typename ei_cleantype<RhsNested>::type _RhsNested; - typedef ei_blas_traits<_RhsNested> RhsBlasTraits; - typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType; - typedef typename ei_cleantype<ActualRhsType>::type _ActualRhsType; + SelfadjointProductMatrix(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {} enum { LhsUpLo = LhsMode&(UpperTriangularBit|LowerTriangularBit), @@ -311,21 +263,10 @@ struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,RhsMode,false> RhsIsSelfAdjoint = (RhsMode&SelfAdjointBit)==SelfAdjointBit }; - template<typename Dest> inline void addToDense(Dest& dst) const - { evalTo(dst,1); } - template<typename Dest> inline void subToDense(Dest& dst) const - { evalTo(dst,-1); } - - template<typename Dest> void evalToDense(Dest& dst) const - { - dst.setZero(); - evalTo(dst,1); - } - - template<typename Dest> void evalTo(Dest& dst, Scalar alpha) const + template<typename Dest> void addTo(Dest& dst, Scalar alpha) const { ei_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols()); - + const ActualLhsType lhs = LhsBlasTraits::extract(m_lhs); const ActualRhsType rhs = RhsBlasTraits::extract(m_rhs); @@ -348,9 +289,6 @@ struct SelfadjointProductMatrix<Lhs,LhsMode,false,Rhs,RhsMode,false> actualAlpha // alpha ); } - - const LhsNested m_lhs; - const RhsNested m_rhs; }; /*************************************************************************** diff --git a/Eigen/src/Core/products/TriangularMatrixMatrix.h b/Eigen/src/Core/products/TriangularMatrixMatrix.h index f69c04365..c2ee39e79 100644 --- a/Eigen/src/Core/products/TriangularMatrixMatrix.h +++ b/Eigen/src/Core/products/TriangularMatrixMatrix.h @@ -103,7 +103,7 @@ struct ei_product_triangular_matrix_matrix<Scalar,Mode,true, Scalar alpha) { int rows = size; - + ei_const_blas_data_mapper<Scalar, LhsStorageOrder> lhs(_lhs,lhsStride); ei_const_blas_data_mapper<Scalar, RhsStorageOrder> rhs(_rhs,rhsStride); @@ -152,7 +152,7 @@ struct ei_product_triangular_matrix_matrix<Scalar,Mode,true, int lengthTarget = IsLowerTriangular ? actual_kc-k1-actualPanelWidth : k1; int startBlock = actual_k2+k1; int blockBOffset = k1; - + // => GEBP with the micro triangular block // The trick is to pack this micro block while filling the opposite triangular part with zeros. // To this end we do an extra triangular copy to small temporary buffer @@ -269,7 +269,7 @@ struct ei_product_triangular_matrix_matrix<Scalar,Mode,false, &rhs(actual_k2+panelOffset, actual_j2), rhsStride, alpha, panelLength, actualPanelWidth, actual_kc, panelOffset); - + // append the triangular part via a temporary buffer for (int j=0;j<actualPanelWidth;++j) { @@ -322,47 +322,18 @@ struct ei_product_triangular_matrix_matrix<Scalar,Mode,false, template<int Mode, bool LhsIsTriangular, typename Lhs, typename Rhs> struct ei_traits<TriangularProduct<Mode,LhsIsTriangular,Lhs,false,Rhs,false> > - : ei_traits<Matrix<typename ei_traits<Rhs>::Scalar,Lhs::RowsAtCompileTime,Rhs::ColsAtCompileTime> > + : ei_traits<ProductBase<TriangularProduct<Mode,LhsIsTriangular,Lhs,false,Rhs,false>, Lhs, Rhs> > {}; template<int Mode, bool LhsIsTriangular, typename Lhs, typename Rhs> struct TriangularProduct<Mode,LhsIsTriangular,Lhs,false,Rhs,false> - : public AnyMatrixBase<TriangularProduct<Mode,LhsIsTriangular,Lhs,false,Rhs,false> > + : public ProductBase<TriangularProduct<Mode,LhsIsTriangular,Lhs,false,Rhs,false>, Lhs, Rhs > { - TriangularProduct(const Lhs& lhs, const Rhs& rhs) - : m_lhs(lhs), m_rhs(rhs) - {} - - inline int rows() const { return m_lhs.rows(); } - inline int cols() const { return m_rhs.cols(); } - - typedef typename Lhs::Scalar Scalar; - - typedef typename Lhs::Nested LhsNested; - typedef typename ei_cleantype<LhsNested>::type _LhsNested; - typedef ei_blas_traits<_LhsNested> LhsBlasTraits; - typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType; - typedef typename ei_cleantype<ActualLhsType>::type _ActualLhsType; + EIGEN_PRODUCT_PUBLIC_INTERFACE(TriangularProduct) - typedef typename Rhs::Nested RhsNested; - typedef typename ei_cleantype<RhsNested>::type _RhsNested; - typedef ei_blas_traits<_RhsNested> RhsBlasTraits; - typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType; - typedef typename ei_cleantype<ActualRhsType>::type _ActualRhsType; + TriangularProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {} - template<typename Dest> inline void addToDense(Dest& dst) const - { evalTo(dst,1); } - template<typename Dest> inline void subToDense(Dest& dst) const - { evalTo(dst,-1); } - - template<typename Dest> void evalToDense(Dest& dst) const - { - dst.resize(m_lhs.rows(), m_rhs.cols()); - dst.setZero(); - evalTo(dst,1); - } - - template<typename Dest> void evalTo(Dest& dst, Scalar alpha) const + template<typename Dest> void addTo(Dest& dst, Scalar alpha) const { const ActualLhsType lhs = LhsBlasTraits::extract(m_lhs); const ActualRhsType rhs = RhsBlasTraits::extract(m_rhs); @@ -383,9 +354,6 @@ struct TriangularProduct<Mode,LhsIsTriangular,Lhs,false,Rhs,false> actualAlpha // alpha ); } - - const LhsNested m_lhs; - const RhsNested m_rhs; }; #endif // EIGEN_TRIANGULAR_MATRIX_MATRIX_H diff --git a/Eigen/src/Core/products/TriangularMatrixVector.h b/Eigen/src/Core/products/TriangularMatrixVector.h index 42239fac0..a21afa2f6 100644 --- a/Eigen/src/Core/products/TriangularMatrixVector.h +++ b/Eigen/src/Core/products/TriangularMatrixVector.h @@ -119,49 +119,21 @@ struct ei_product_triangular_vector_selector<Lhs,Rhs,Result,Mode,ConjLhs,ConjRhs template<int Mode, /*bool LhsIsTriangular, */typename Lhs, typename Rhs> struct ei_traits<TriangularProduct<Mode,true,Lhs,false,Rhs,true> > - : ei_traits<Matrix<typename ei_traits<Rhs>::Scalar,Lhs::RowsAtCompileTime,Rhs::ColsAtCompileTime> > + : ei_traits<ProductBase<TriangularProduct<Mode,true,Lhs,false,Rhs,true>, Lhs, Rhs> > {}; template<int Mode, /*bool LhsIsTriangular, */typename Lhs, typename Rhs> struct TriangularProduct<Mode,true,Lhs,false,Rhs,true> - : public AnyMatrixBase<TriangularProduct<Mode,true,Lhs,false,Rhs,true> > + : public ProductBase<TriangularProduct<Mode,true,Lhs,false,Rhs,true>, Lhs, Rhs > { - typedef typename Lhs::Scalar Scalar; + EIGEN_PRODUCT_PUBLIC_INTERFACE(TriangularProduct) - typedef typename Lhs::Nested LhsNested; - typedef typename ei_cleantype<LhsNested>::type _LhsNested; - typedef ei_blas_traits<_LhsNested> LhsBlasTraits; - typedef typename LhsBlasTraits::DirectLinearAccessType ActualLhsType; - typedef typename ei_cleantype<ActualLhsType>::type _ActualLhsType; + TriangularProduct(const Lhs& lhs, const Rhs& rhs) : Base(lhs,rhs) {} - typedef typename Rhs::Nested RhsNested; - typedef typename ei_cleantype<RhsNested>::type _RhsNested; - typedef ei_blas_traits<_RhsNested> RhsBlasTraits; - typedef typename RhsBlasTraits::DirectLinearAccessType ActualRhsType; - typedef typename ei_cleantype<ActualRhsType>::type _ActualRhsType; - - TriangularProduct(const Lhs& lhs, const Rhs& rhs) - : m_lhs(lhs), m_rhs(rhs) - {} - - inline int rows() const { return m_lhs.rows(); } - inline int cols() const { return m_rhs.cols(); } - - template<typename Dest> inline void addToDense(Dest& dst) const - { evalTo(dst,1); } - template<typename Dest> inline void subToDense(Dest& dst) const - { evalTo(dst,-1); } - - template<typename Dest> void evalToDense(Dest& dst) const - { - dst.setZero(); - evalTo(dst,1); - } - - template<typename Dest> void evalTo(Dest& dst, Scalar alpha) const + template<typename Dest> void addTo(Dest& dst, Scalar alpha) const { ei_assert(dst.rows()==m_lhs.rows() && dst.cols()==m_rhs.cols()); - + const ActualLhsType lhs = LhsBlasTraits::extract(m_lhs); const ActualRhsType rhs = RhsBlasTraits::extract(m_rhs); @@ -176,9 +148,6 @@ struct TriangularProduct<Mode,true,Lhs,false,Rhs,true> ei_traits<Lhs>::Flags&RowMajorBit> ::run(lhs,rhs,dst,actualAlpha); } - - const LhsNested m_lhs; - const RhsNested m_rhs; }; #endif // EIGEN_TRIANGULARMATRIXVECTOR_H diff --git a/Eigen/src/Core/util/ForwardDeclarations.h b/Eigen/src/Core/util/ForwardDeclarations.h index 310d0fbde..d755445c1 100644 --- a/Eigen/src/Core/util/ForwardDeclarations.h +++ b/Eigen/src/Core/util/ForwardDeclarations.h @@ -48,6 +48,7 @@ template<typename NullaryOp, typename MatrixType> class CwiseNullaryOp; template<typename UnaryOp, typename MatrixType> class CwiseUnaryOp; template<typename ViewOp, typename MatrixType> class CwiseUnaryView; template<typename BinaryOp, typename Lhs, typename Rhs> class CwiseBinaryOp; +template<typename Derived, typename Lhs, typename Rhs> class ProductBase; template<typename Lhs, typename Rhs, int ProductMode> class Product; template<typename Derived> class DiagonalBase; diff --git a/Eigen/src/Geometry/Homogeneous.h b/Eigen/src/Geometry/Homogeneous.h index 5f4cddcea..0b154f47b 100644 --- a/Eigen/src/Geometry/Homogeneous.h +++ b/Eigen/src/Geometry/Homogeneous.h @@ -75,13 +75,13 @@ template<typename MatrixType,int _Direction> class Homogeneous : m_matrix(matrix) {} - inline int rows() const { return m_matrix.rows() + (Direction==Vertical ? 1 : 0); } - inline int cols() const { return m_matrix.cols() + (Direction==Horizontal ? 1 : 0); } + inline int rows() const { return m_matrix.rows() + (int(Direction)==Vertical ? 1 : 0); } + inline int cols() const { return m_matrix.cols() + (int(Direction)==Horizontal ? 1 : 0); } inline Scalar coeff(int row, int col) const { - if( (Direction==Vertical && row==m_matrix.rows()) - || (Direction==Horizontal && col==m_matrix.cols())) + if( (int(Direction)==Vertical && row==m_matrix.rows()) + || (int(Direction)==Horizontal && col==m_matrix.cols())) return 1; return m_matrix.coeff(row, col); } @@ -90,7 +90,7 @@ template<typename MatrixType,int _Direction> class Homogeneous inline const ei_homogeneous_right_product_impl<Homogeneous,Rhs> operator* (const MatrixBase<Rhs>& rhs) const { - ei_assert(Direction==Horizontal); + ei_assert(int(Direction)==Horizontal); return ei_homogeneous_right_product_impl<Homogeneous,Rhs>(m_matrix,rhs.derived()); } @@ -98,7 +98,7 @@ template<typename MatrixType,int _Direction> class Homogeneous inline const ei_homogeneous_left_product_impl<Homogeneous,Lhs> operator* (const MatrixBase<Lhs>& lhs, const Homogeneous& rhs) { - ei_assert(Direction==Vertical); + ei_assert(int(Direction)==Vertical); return ei_homogeneous_left_product_impl<Homogeneous,Lhs>(lhs.derived(),rhs.m_matrix); } @@ -107,7 +107,7 @@ template<typename MatrixType,int _Direction> class Homogeneous typename Transform<Scalar,Dim,Mode>::AffinePartNested> operator* (const Transform<Scalar,Dim,Mode>& tr, const Homogeneous& rhs) { - ei_assert(Direction==Vertical); + ei_assert(int(Direction)==Vertical); return ei_homogeneous_left_product_impl<Homogeneous,typename Transform<Scalar,Dim,Mode>::AffinePartNested > (tr.affine(),rhs.m_matrix); } @@ -117,7 +117,7 @@ template<typename MatrixType,int _Direction> class Homogeneous typename Transform<Scalar,Dim,Projective>::MatrixType> operator* (const Transform<Scalar,Dim,Projective>& tr, const Homogeneous& rhs) { - ei_assert(Direction==Vertical); + ei_assert(int(Direction)==Vertical); return ei_homogeneous_left_product_impl<Homogeneous,typename Transform<Scalar,Dim,Projective>::MatrixType> (tr.matrix(),rhs.m_matrix); } diff --git a/Eigen/src/Geometry/RotationBase.h b/Eigen/src/Geometry/RotationBase.h index b129b706b..baffd8e24 100644 --- a/Eigen/src/Geometry/RotationBase.h +++ b/Eigen/src/Geometry/RotationBase.h @@ -68,17 +68,18 @@ class RotationBase /** \returns the concatenation of the rotation \c *this with a generic expression \a e * \a e can be: - * - a DimxDim linear transformation matrix (including an axis aligned scaling) + * - a DimxDim linear transformation matrix + * - a DimxDim diagonal matrix (axis aligned scaling) * - a vector of size Dim */ template<typename OtherDerived> inline typename ei_rotation_base_generic_product_selector<Derived,OtherDerived,OtherDerived::IsVectorAtCompileTime>::ReturnType - operator*(const MatrixBase<OtherDerived>& e) const + operator*(const AnyMatrixBase<OtherDerived>& e) const { return ei_rotation_base_generic_product_selector<Derived,OtherDerived>::run(derived(), e.derived()); } /** \returns the concatenation of a linear transformation \a l with the rotation \a r */ template<typename OtherDerived> friend - inline RotationMatrixType operator*(const MultiplierBase<OtherDerived>& l, const Derived& r) + inline RotationMatrixType operator*(const AnyMatrixBase<OtherDerived>& l, const Derived& r) { return l.derived() * r.toRotationMatrix(); } /** \returns the concatenation of the rotation \c *this with a transformation \a t */ diff --git a/Eigen/src/Geometry/Transform.h b/Eigen/src/Geometry/Transform.h index b1f3de301..da3187e3c 100644 --- a/Eigen/src/Geometry/Transform.h +++ b/Eigen/src/Geometry/Transform.h @@ -310,7 +310,7 @@ public: // note: this function is defined here because some compilers cannot find the respective declaration template<typename OtherDerived> inline const typename ei_transform_right_product_impl<OtherDerived,Mode,_Dim,_Dim+1>::ResultType - operator * (const MultiplierBase<OtherDerived> &other) const + operator * (const AnyMatrixBase<OtherDerived> &other) const { return ei_transform_right_product_impl<OtherDerived,Mode,Dim,HDim>::run(*this,other.derived()); } /** \returns the product expression of a transformation matrix \a a times a transform \a b @@ -322,11 +322,11 @@ public: */ template<typename OtherDerived> friend inline const typename ei_transform_left_product_impl<OtherDerived,Mode,_Dim,_Dim+1>::ResultType - operator * (const MultiplierBase<OtherDerived> &a, const Transform &b) + operator * (const AnyMatrixBase<OtherDerived> &a, const Transform &b) { return ei_transform_left_product_impl<OtherDerived,Mode,Dim,HDim>::run(a.derived(),b); } template<typename OtherDerived> - inline Transform& operator*=(const MultiplierBase<OtherDerived>& other) { return *this = *this * other; } + inline Transform& operator*=(const AnyMatrixBase<OtherDerived>& other) { return *this = *this * other; } /** Contatenates two transformations */ inline const Transform operator * (const Transform& other) const @@ -977,7 +977,7 @@ struct ei_transform_construct_from_matrix<Other, AffineCompact,Dim,HDim, HDim,HD }; /********************************************************* -*** Specializations of operator* with a MultiplierBase *** +*** Specializations of operator* with a AnyMatrixBase *** *********************************************************/ // ei_general_product_return_type is a generalization of ProductReturnType, for all types (including e.g. DiagonalBase...), @@ -989,7 +989,7 @@ template<typename Lhs, typename D2> struct ei_general_product_return_type<Lhs, M { typedef D2 Type; }; template<typename D1, typename Rhs> struct ei_general_product_return_type<MatrixBase<D1>, Rhs > { typedef D1 Type; }; - + // Projective * set of homogeneous column vectors diff --git a/Eigen/src/Geometry/Translation.h b/Eigen/src/Geometry/Translation.h index a90e1b2f2..1fff03810 100644 --- a/Eigen/src/Geometry/Translation.h +++ b/Eigen/src/Geometry/Translation.h @@ -93,7 +93,7 @@ public: /** Concatenates a translation and a linear transformation */ template<typename OtherDerived> - inline AffineTransformType operator* (const MultiplierBase<OtherDerived>& linear) const; + inline AffineTransformType operator* (const AnyMatrixBase<OtherDerived>& linear) const; /** Concatenates a translation and a rotation */ template<typename Derived> @@ -103,7 +103,7 @@ public: /** \returns the concatenation of a linear transformation \a l with the translation \a t */ // its a nightmare to define a templated friend function outside its declaration template<typename OtherDerived> friend - inline AffineTransformType operator*(const MultiplierBase<OtherDerived>& linear, const Translation& t) + inline AffineTransformType operator*(const AnyMatrixBase<OtherDerived>& linear, const Translation& t) { AffineTransformType res; res.matrix().setZero(); @@ -182,7 +182,7 @@ Translation<Scalar,Dim>::operator* (const UniformScaling<Scalar>& other) const template<typename Scalar, int Dim> template<typename OtherDerived> inline typename Translation<Scalar,Dim>::AffineTransformType -Translation<Scalar,Dim>::operator* (const MultiplierBase<OtherDerived>& linear) const +Translation<Scalar,Dim>::operator* (const AnyMatrixBase<OtherDerived>& linear) const { AffineTransformType res; res.matrix().setZero(); diff --git a/test/product_notemporary.cpp b/test/product_notemporary.cpp index 62f61672f..1e8dff4be 100644 --- a/test/product_notemporary.cpp +++ b/test/product_notemporary.cpp @@ -41,9 +41,9 @@ static int nb_temporaries; template<typename MatrixType> void product_notemporary(const MatrixType& m) { - /* This test checks the number of tempories created + /* This test checks the number of tempories created * during the evaluation of a complex expression */ - + typedef typename MatrixType::Scalar Scalar; typedef Matrix<Scalar, 1, Dynamic> RowVectorType; typedef Matrix<Scalar, Dynamic, 1> ColVectorType; @@ -70,8 +70,10 @@ template<typename MatrixType> void product_notemporary(const MatrixType& m) VERIFY_EVALUATION_COUNT( m3 = (m1 * m2.adjoint()), 1); VERIFY_EVALUATION_COUNT( m3 = (m1 * m2.adjoint()).lazy(), 0); + // NOTE in this case the slow product is used: VERIFY_EVALUATION_COUNT( m3 = s1 * (m1 * m2.transpose()).lazy(), 0); + VERIFY_EVALUATION_COUNT( m3 = (s1 * m1 * s2 * m2.adjoint()).lazy(), 0); VERIFY_EVALUATION_COUNT( m3 = (s1 * m1 * s2 * (m1*s3+m2*s2).adjoint()).lazy(), 1); VERIFY_EVALUATION_COUNT( m3 = ((s1 * m1).adjoint() * s2 * m2).lazy(), 0); @@ -80,6 +82,7 @@ template<typename MatrixType> void product_notemporary(const MatrixType& m) VERIFY_EVALUATION_COUNT(( m3.block(r0,r0,r1,r1) += (-m1.block(r0,c0,r1,c1) * (s2*m2.block(r0,c0,r1,c1)).adjoint()).lazy() ), 0); VERIFY_EVALUATION_COUNT(( m3.block(r0,r0,r1,r1) -= (s1 * m1.block(r0,c0,r1,c1) * m2.block(c0,r0,c1,r1)).lazy() ), 0); + // NOTE this is because the Block expression is not handled yet by our expression analyser VERIFY_EVALUATION_COUNT(( m3.block(r0,r0,r1,r1) = (s1 * m1.block(r0,c0,r1,c1) * (s1*m2).block(c0,r0,c1,r1)).lazy() ), 1); @@ -90,8 +93,7 @@ template<typename MatrixType> void product_notemporary(const MatrixType& m) VERIFY_EVALUATION_COUNT( rm3.col(c0) = (s1 * m1.adjoint()).template triangularView<UnitUpperTriangular>() * (s2*m2.row(c0)).adjoint(), 0); VERIFY_EVALUATION_COUNT( m1.template triangularView<LowerTriangular>().solveInPlace(m3), 0); - // FIXME this is because the rhs/result must be column major: - VERIFY_EVALUATION_COUNT( m1.adjoint().template triangularView<LowerTriangular>().solveInPlace(m3.transpose()), 1); + VERIFY_EVALUATION_COUNT( m1.adjoint().template triangularView<LowerTriangular>().solveInPlace(m3.transpose()), 0); VERIFY_EVALUATION_COUNT( m3 -= (s1 * m1).adjoint().template selfadjointView<LowerTriangular>() * (-m2*s3).adjoint(), 0); VERIFY_EVALUATION_COUNT( m3 = s2 * m2.adjoint() * (s1 * m1.adjoint()).template selfadjointView<UpperTriangular>(), 0); |