diff options
author | Gael Guennebaud <g.gael@free.fr> | 2009-12-22 22:51:08 +0100 |
---|---|---|
committer | Gael Guennebaud <g.gael@free.fr> | 2009-12-22 22:51:08 +0100 |
commit | eaaba30cacf078335ad41314bf1e4ce993f0b3b4 (patch) | |
tree | 61156273b56dc19fc4e661a5aeb42d8e6112a307 /Eigen/src/Core | |
parent | e182e9c6166840b8db44e0be459a2e26d26fda0f (diff) | |
parent | eeec7d842e05394703c42e7569230835f7842089 (diff) |
merge with default branch
Diffstat (limited to 'Eigen/src/Core')
36 files changed, 659 insertions, 467 deletions
diff --git a/Eigen/src/Core/AnyMatrixBase.h b/Eigen/src/Core/AnyMatrixBase.h index 0522c1d5e..d1c16923b 100644 --- a/Eigen/src/Core/AnyMatrixBase.h +++ b/Eigen/src/Core/AnyMatrixBase.h @@ -57,7 +57,7 @@ template<typename Derived> struct AnyMatrixBase { derived().evalTo(dst); } /** \internal Don't use it, but do the equivalent: \code dst += *this; \endcode */ - template<typename Dest> inline void addToDense(Dest& dst) const + template<typename Dest> inline void addTo(Dest& dst) const { // This is the default implementation, // derived class can reimplement it in a more optimized way. @@ -67,7 +67,7 @@ template<typename Derived> struct AnyMatrixBase } /** \internal Don't use it, but do the equivalent: \code dst -= *this; \endcode */ - template<typename Dest> inline void subToDense(Dest& dst) const + template<typename Dest> inline void subTo(Dest& dst) const { // This is the default implementation, // derived class can reimplement it in a more optimized way. @@ -114,7 +114,7 @@ template<typename Derived> template<typename OtherDerived> Derived& DenseBase<Derived>::operator+=(const AnyMatrixBase<OtherDerived> &other) { - other.derived().addToDense(derived()); + other.derived().addTo(derived()); return derived(); } @@ -122,7 +122,7 @@ template<typename Derived> template<typename OtherDerived> Derived& DenseBase<Derived>::operator-=(const AnyMatrixBase<OtherDerived> &other) { - other.derived().subToDense(derived()); + other.derived().subTo(derived()); return derived(); } diff --git a/Eigen/src/Core/Assign.h b/Eigen/src/Core/Assign.h index 466205208..d6bf37c6e 100644 --- a/Eigen/src/Core/Assign.h +++ b/Eigen/src/Core/Assign.h @@ -28,7 +28,7 @@ #define EIGEN_ASSIGN_H /*************************************************************************** -* Part 1 : the logic deciding a strategy for vectorization and unrolling +* Part 1 : the logic deciding a strategy for traversal and unrolling * ***************************************************************************/ template <typename Derived, typename OtherDerived> @@ -53,44 +53,53 @@ private: }; enum { - MightVectorize = (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit) - && ((int(Derived::Flags)&RowMajorBit)==(int(OtherDerived::Flags)&RowMajorBit)), + StorageOrdersAgree = (int(Derived::Flags)&RowMajorBit)==(int(OtherDerived::Flags)&RowMajorBit), + MightVectorize = StorageOrdersAgree + && (int(Derived::Flags) & int(OtherDerived::Flags) & ActualPacketAccessBit), MayInnerVectorize = MightVectorize && int(InnerSize)!=Dynamic && int(InnerSize)%int(PacketSize)==0 && int(DstIsAligned) && int(SrcIsAligned), - MayLinearVectorize = MightVectorize && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit) - && (DstIsAligned || InnerMaxSize == Dynamic),/* If the destination isn't aligned, - we have to do runtime checks and we don't unroll, so it's only good for large enough sizes. See remark below - about InnerMaxSize. */ - MaySliceVectorize = MightVectorize && int(InnerMaxSize)>=3*PacketSize /* slice vectorization can be slow, so we only - want it if the slices are big, which is indicated by InnerMaxSize rather than InnerSize, think of the case - of a dynamic block in a fixed-size matrix */ + MayLinearize = StorageOrdersAgree && (int(Derived::Flags) & int(OtherDerived::Flags) & LinearAccessBit), + MayLinearVectorize = MightVectorize && MayLinearize + && (DstIsAligned || InnerMaxSize == Dynamic), + /* If the destination isn't aligned, we have to do runtime checks and we don't unroll, + so it's only good for large enough sizes. See remark below about InnerMaxSize. */ + MaySliceVectorize = MightVectorize && int(InnerMaxSize)>=3*PacketSize + /* slice vectorization can be slow, so we only want it if the slices are big, which is + indicated by InnerMaxSize rather than InnerSize, think of the case of a dynamic block + in a fixed-size matrix */ }; public: enum { - Vectorization = int(MayInnerVectorize) ? int(InnerVectorization) - : int(MayLinearVectorize) ? int(LinearVectorization) - : int(MaySliceVectorize) ? int(SliceVectorization) - : int(NoVectorization) + Traversal = int(MayInnerVectorize) ? int(InnerVectorizedTraversal) + : int(MayLinearVectorize) ? int(LinearVectorizedTraversal) + : int(MaySliceVectorize) ? int(SliceVectorizedTraversal) + : int(MayLinearize) ? int(LinearTraversal) + : int(DefaultTraversal), + Vectorized = int(Traversal) == InnerVectorizedTraversal + || int(Traversal) == LinearVectorizedTraversal + || int(Traversal) == SliceVectorizedTraversal }; private: enum { - UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Vectorization) == int(NoVectorization) ? 1 : int(PacketSize)), + UnrollingLimit = EIGEN_UNROLLING_LIMIT * (Vectorized ? int(PacketSize) : 1), MayUnrollCompletely = int(Derived::SizeAtCompileTime) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit), - MayUnrollInner = int(InnerSize * OtherDerived::CoeffReadCost) <= int(UnrollingLimit) + MayUnrollInner = int(InnerSize) * int(OtherDerived::CoeffReadCost) <= int(UnrollingLimit) }; public: enum { - Unrolling = (int(Vectorization) == int(InnerVectorization) || int(Vectorization) == int(NoVectorization)) - ? ( - int(MayUnrollCompletely) ? int(CompleteUnrolling) - : int(MayUnrollInner) ? int(InnerUnrolling) - : int(NoUnrolling) - ) - : int(Vectorization) == int(LinearVectorization) - ? ( int(MayUnrollCompletely) && int(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) ) + Unrolling = (int(Traversal) == int(InnerVectorizedTraversal) || int(Traversal) == int(DefaultTraversal)) + ? ( + int(MayUnrollCompletely) ? int(CompleteUnrolling) + : int(MayUnrollInner) ? int(InnerUnrolling) + : int(NoUnrolling) + ) + : int(Traversal) == int(LinearVectorizedTraversal) + ? ( int(MayUnrollCompletely) && int(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) ) + : int(Traversal) == int(LinearTraversal) + ? ( int(MayUnrollCompletely) ? int(CompleteUnrolling) : int(NoUnrolling) ) : int(NoUnrolling) }; @@ -102,11 +111,12 @@ public: EIGEN_DEBUG_VAR(InnerSize) EIGEN_DEBUG_VAR(InnerMaxSize) EIGEN_DEBUG_VAR(PacketSize) + EIGEN_DEBUG_VAR(StorageOrdersAgree) EIGEN_DEBUG_VAR(MightVectorize) EIGEN_DEBUG_VAR(MayInnerVectorize) EIGEN_DEBUG_VAR(MayLinearVectorize) EIGEN_DEBUG_VAR(MaySliceVectorize) - EIGEN_DEBUG_VAR(Vectorization) + EIGEN_DEBUG_VAR(Traversal) EIGEN_DEBUG_VAR(UnrollingLimit) EIGEN_DEBUG_VAR(MayUnrollCompletely) EIGEN_DEBUG_VAR(MayUnrollInner) @@ -118,12 +128,12 @@ public: * Part 2 : meta-unrollers ***************************************************************************/ -/*********************** -*** No vectorization *** -***********************/ +/************************ +*** Default traversal *** +************************/ template<typename Derived1, typename Derived2, int Index, int Stop> -struct ei_assign_novec_CompleteUnrolling +struct ei_assign_DefaultTraversal_CompleteUnrolling { enum { row = int(Derived1::Flags)&RowMajorBit @@ -137,18 +147,18 @@ struct ei_assign_novec_CompleteUnrolling EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) { dst.copyCoeff(row, col, src); - ei_assign_novec_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src); + ei_assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src); } }; template<typename Derived1, typename Derived2, int Stop> -struct ei_assign_novec_CompleteUnrolling<Derived1, Derived2, Stop, Stop> +struct ei_assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop> { EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {} }; template<typename Derived1, typename Derived2, int Index, int Stop> -struct ei_assign_novec_InnerUnrolling +struct ei_assign_DefaultTraversal_InnerUnrolling { EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src, int row_or_col) { @@ -156,16 +166,36 @@ struct ei_assign_novec_InnerUnrolling const int row = rowMajor ? row_or_col : Index; const int col = rowMajor ? Index : row_or_col; dst.copyCoeff(row, col, src); - ei_assign_novec_InnerUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src, row_or_col); + ei_assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src, row_or_col); } }; template<typename Derived1, typename Derived2, int Stop> -struct ei_assign_novec_InnerUnrolling<Derived1, Derived2, Stop, Stop> +struct ei_assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, Stop, Stop> { EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &, int) {} }; +/*********************** +*** Linear traversal *** +***********************/ + +template<typename Derived1, typename Derived2, int Index, int Stop> +struct ei_assign_LinearTraversal_CompleteUnrolling +{ + EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + { + dst.copyCoeff(Index, src); + ei_assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Index+1, Stop>::run(dst, src); + } +}; + +template<typename Derived1, typename Derived2, int Stop> +struct ei_assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, Stop, Stop> +{ + EIGEN_STRONG_INLINE static void run(Derived1 &, const Derived2 &) {} +}; + /************************** *** Inner vectorization *** **************************/ @@ -221,16 +251,16 @@ struct ei_assign_innervec_InnerUnrolling<Derived1, Derived2, Stop, Stop> ***************************************************************************/ template<typename Derived1, typename Derived2, - int Vectorization = ei_assign_traits<Derived1, Derived2>::Vectorization, + int Traversal = ei_assign_traits<Derived1, Derived2>::Traversal, int Unrolling = ei_assign_traits<Derived1, Derived2>::Unrolling> struct ei_assign_impl; -/*********************** -*** No vectorization *** -***********************/ +/************************ +*** Default traversal *** +************************/ template<typename Derived1, typename Derived2> -struct ei_assign_impl<Derived1, Derived2, NoVectorization, NoUnrolling> +struct ei_assign_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling> { inline static void run(Derived1 &dst, const Derived2 &src) { @@ -248,17 +278,17 @@ struct ei_assign_impl<Derived1, Derived2, NoVectorization, NoUnrolling> }; template<typename Derived1, typename Derived2> -struct ei_assign_impl<Derived1, Derived2, NoVectorization, CompleteUnrolling> +struct ei_assign_impl<Derived1, Derived2, DefaultTraversal, CompleteUnrolling> { EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) { - ei_assign_novec_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime> + ei_assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime> ::run(dst, src); } }; template<typename Derived1, typename Derived2> -struct ei_assign_impl<Derived1, Derived2, NoVectorization, InnerUnrolling> +struct ei_assign_impl<Derived1, Derived2, DefaultTraversal, InnerUnrolling> { EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) { @@ -266,17 +296,42 @@ struct ei_assign_impl<Derived1, Derived2, NoVectorization, InnerUnrolling> const int innerSize = rowMajor ? Derived1::ColsAtCompileTime : Derived1::RowsAtCompileTime; const int outerSize = dst.outerSize(); for(int j = 0; j < outerSize; ++j) - ei_assign_novec_InnerUnrolling<Derived1, Derived2, 0, innerSize> + ei_assign_DefaultTraversal_InnerUnrolling<Derived1, Derived2, 0, innerSize> ::run(dst, src, j); } }; +/*********************** +*** Linear traversal *** +***********************/ + +template<typename Derived1, typename Derived2> +struct ei_assign_impl<Derived1, Derived2, LinearTraversal, NoUnrolling> +{ + inline static void run(Derived1 &dst, const Derived2 &src) + { + const int size = dst.size(); + for(int i = 0; i < size; ++i) + dst.copyCoeff(i, src); + } +}; + +template<typename Derived1, typename Derived2> +struct ei_assign_impl<Derived1, Derived2, LinearTraversal, CompleteUnrolling> +{ + EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) + { + ei_assign_LinearTraversal_CompleteUnrolling<Derived1, Derived2, 0, Derived1::SizeAtCompileTime> + ::run(dst, src); + } +}; + /************************** *** Inner vectorization *** **************************/ template<typename Derived1, typename Derived2> -struct ei_assign_impl<Derived1, Derived2, InnerVectorization, NoUnrolling> +struct ei_assign_impl<Derived1, Derived2, InnerVectorizedTraversal, NoUnrolling> { inline static void run(Derived1 &dst, const Derived2 &src) { @@ -295,7 +350,7 @@ struct ei_assign_impl<Derived1, Derived2, InnerVectorization, NoUnrolling> }; template<typename Derived1, typename Derived2> -struct ei_assign_impl<Derived1, Derived2, InnerVectorization, CompleteUnrolling> +struct ei_assign_impl<Derived1, Derived2, InnerVectorizedTraversal, CompleteUnrolling> { EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) { @@ -305,7 +360,7 @@ struct ei_assign_impl<Derived1, Derived2, InnerVectorization, CompleteUnrolling> }; template<typename Derived1, typename Derived2> -struct ei_assign_impl<Derived1, Derived2, InnerVectorization, InnerUnrolling> +struct ei_assign_impl<Derived1, Derived2, InnerVectorizedTraversal, InnerUnrolling> { EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) { @@ -323,7 +378,7 @@ struct ei_assign_impl<Derived1, Derived2, InnerVectorization, InnerUnrolling> ***************************/ template<typename Derived1, typename Derived2> -struct ei_assign_impl<Derived1, Derived2, LinearVectorization, NoUnrolling> +struct ei_assign_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling> { inline static void run(Derived1 &dst, const Derived2 &src) { @@ -347,7 +402,7 @@ struct ei_assign_impl<Derived1, Derived2, LinearVectorization, NoUnrolling> }; template<typename Derived1, typename Derived2> -struct ei_assign_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling> +struct ei_assign_impl<Derived1, Derived2, LinearVectorizedTraversal, CompleteUnrolling> { EIGEN_STRONG_INLINE static void run(Derived1 &dst, const Derived2 &src) { @@ -356,7 +411,7 @@ struct ei_assign_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling const int alignedSize = (size/packetSize)*packetSize; ei_assign_innervec_CompleteUnrolling<Derived1, Derived2, 0, alignedSize>::run(dst, src); - ei_assign_novec_CompleteUnrolling<Derived1, Derived2, alignedSize, size>::run(dst, src); + ei_assign_DefaultTraversal_CompleteUnrolling<Derived1, Derived2, alignedSize, size>::run(dst, src); } }; @@ -365,7 +420,7 @@ struct ei_assign_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling ***************************/ template<typename Derived1, typename Derived2> -struct ei_assign_impl<Derived1, Derived2, SliceVectorization, NoUnrolling> +struct ei_assign_impl<Derived1, Derived2, SliceVectorizedTraversal, NoUnrolling> { inline static void run(Derived1 &dst, const Derived2 &src) { @@ -430,6 +485,9 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived> #ifdef EIGEN_DEBUG_ASSIGN ei_assign_traits<Derived, OtherDerived>::debug(); #endif +#ifndef EIGEN_NO_DEBUG + checkTransposeAliasing(other.derived()); +#endif return derived(); } diff --git a/Eigen/src/Core/BandMatrix.h b/Eigen/src/Core/BandMatrix.h index 841d1786a..7943e6280 100644 --- a/Eigen/src/Core/BandMatrix.h +++ b/Eigen/src/Core/BandMatrix.h @@ -70,7 +70,7 @@ class BandMatrix : public AnyMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs MaxColsAtCompileTime = ei_traits<BandMatrix>::MaxColsAtCompileTime }; typedef typename ei_traits<BandMatrix>::Scalar Scalar; - typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> PlainMatrixType; + typedef Matrix<Scalar,RowsAtCompileTime,ColsAtCompileTime> DenseMatrixType; protected: enum { @@ -87,7 +87,7 @@ class BandMatrix : public AnyMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs : m_data(1+supers+subs,cols), m_rows(rows), m_supers(supers), m_subs(subs) { - m_data.setConstant(666); + //m_data.setConstant(666); } /** \returns the number of columns */ @@ -141,7 +141,7 @@ class BandMatrix : public AnyMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs }; typedef Block<DataType,1, DiagonalSize> BuildType; typedef typename ei_meta_if<Conjugate, - CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>,NestByValue<BuildType> >, + CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>,BuildType >, BuildType>::ret Type; }; @@ -171,9 +171,9 @@ class BandMatrix : public AnyMatrixBase<BandMatrix<_Scalar,Rows,Cols,Supers,Subs return Block<DataType,1,Dynamic>(m_data, supers()-i, std::max(0,i), 1, diagonalLength(i)); } - PlainMatrixType toDense() const + DenseMatrixType toDenseMatrix() const { - PlainMatrixType res(rows(),cols()); + DenseMatrixType res(rows(),cols()); res.setZero(); res.diagonal() = diagonal(); for (int i=1; i<=supers();++i) diff --git a/Eigen/src/Core/Coeffs.h b/Eigen/src/Core/Coeffs.h index c8bc9db85..b8af2531e 100644 --- a/Eigen/src/Core/Coeffs.h +++ b/Eigen/src/Core/Coeffs.h @@ -379,6 +379,38 @@ EIGEN_STRONG_INLINE void DenseBase<Derived>::copyPacket(int index, const DenseBa other.derived().template packet<LoadMode>(index)); } + +template<typename Derived, typename Integer, bool JustReturnZero> +struct ei_alignmentOffset_impl +{ + inline static Integer run(const DenseBase<Derived>&, Integer) + { return 0; } +}; + +template<typename Derived, typename Integer> +struct ei_alignmentOffset_impl<Derived, Integer, false> +{ + inline static Integer run(const DenseBase<Derived>& m, Integer maxOffset) + { + return ei_alignmentOffset(&m.const_cast_derived().coeffRef(0,0), maxOffset); + } +}; + +/** \internal \returns the number of elements which have to be skipped, starting + * from the address of coeffRef(0,0), to find the first 16-byte aligned element. + * + * \note If the expression doesn't have the DirectAccessBit, this function returns 0. + * + * There is also the variant ei_alignmentOffset(const Scalar*, Integer) defined in Memory.h. + */ +template<typename Derived, typename Integer> +inline static Integer ei_alignmentOffset(const DenseBase<Derived>& m, Integer maxOffset) +{ + return ei_alignmentOffset_impl<Derived, Integer, + (Derived::Flags & AlignedBit) || !(Derived::Flags & DirectAccessBit)> + ::run(m, maxOffset); +} + #endif #endif // EIGEN_COEFFS_H diff --git a/Eigen/src/Core/CommaInitializer.h b/Eigen/src/Core/CommaInitializer.h index 428e4d82d..a312b40f5 100644 --- a/Eigen/src/Core/CommaInitializer.h +++ b/Eigen/src/Core/CommaInitializer.h @@ -116,9 +116,6 @@ struct CommaInitializer int m_row; // current row id int m_col; // current col id int m_currentBlockRows; // current block height - -private: - CommaInitializer& operator=(const CommaInitializer&); }; /** \anchor MatrixBaseCommaInitRef diff --git a/Eigen/src/Core/CwiseBinaryOp.h b/Eigen/src/Core/CwiseBinaryOp.h index 954ea9275..4d7ab6598 100644 --- a/Eigen/src/Core/CwiseBinaryOp.h +++ b/Eigen/src/Core/CwiseBinaryOp.h @@ -65,11 +65,16 @@ struct ei_traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > : ei_traits<Lhs> RhsCoeffReadCost = _RhsNested::CoeffReadCost, LhsFlags = _LhsNested::Flags, RhsFlags = _RhsNested::Flags, + StorageOrdersAgree = (int(Lhs::Flags)&RowMajorBit)==(int(Rhs::Flags)&RowMajorBit), Flags = (int(LhsFlags) | int(RhsFlags)) & ( HereditaryBits - | (int(LhsFlags) & int(RhsFlags) & (LinearAccessBit | AlignedBit)) - | (ei_functor_traits<BinaryOp>::PacketAccess && ((int(LhsFlags) & RowMajorBit)==(int(RhsFlags) & RowMajorBit)) - ? (int(LhsFlags) & int(RhsFlags) & PacketAccessBit) : 0)), + | (int(LhsFlags) & int(RhsFlags) & + ( AlignedBit + | (StorageOrdersAgree ? LinearAccessBit : 0) + | (ei_functor_traits<BinaryOp>::PacketAccess && StorageOrdersAgree ? PacketAccessBit : 0) + ) + ) + ), CoeffReadCost = LhsCoeffReadCost + RhsCoeffReadCost + ei_functor_traits<BinaryOp>::Cost }; }; diff --git a/Eigen/src/Core/DenseBase.h b/Eigen/src/Core/DenseBase.h index ea6383998..a7e74b81d 100644 --- a/Eigen/src/Core/DenseBase.h +++ b/Eigen/src/Core/DenseBase.h @@ -274,21 +274,12 @@ template<typename Derived> class DenseBase Eigen::Transpose<Derived> transpose(); const Eigen::Transpose<Derived> transpose() const; void transposeInPlace(); - #ifndef EIGEN_NO_DEBUG - template<typename OtherDerived> - Derived& lazyAssign(const Transpose<OtherDerived>& other); - template<typename DerivedA, typename DerivedB> - Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,Transpose<DerivedA>,DerivedB>& other); - template<typename DerivedA, typename DerivedB> - Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,Transpose<DerivedB> >& other); - +#ifndef EIGEN_NO_DEBUG + protected: template<typename OtherDerived> - Derived& lazyAssign(const CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<OtherDerived> > >& other); - template<typename DerivedA, typename DerivedB> - Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedA> > >,DerivedB>& other); - template<typename DerivedA, typename DerivedB> - Derived& lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedB> > > >& other); - #endif + void checkTransposeAliasing(const OtherDerived& other) const; + public: +#endif RowXpr row(int i); const RowXpr row(int i) const; @@ -382,18 +373,19 @@ template<typename Derived> class DenseBase template<typename OtherDerived> bool isApprox(const DenseBase<OtherDerived>& other, - RealScalar prec = precision<Scalar>()) const; + RealScalar prec = dummy_precision<Scalar>()) const; bool isMuchSmallerThan(const RealScalar& other, - RealScalar prec = precision<Scalar>()) const; + RealScalar prec = dummy_precision<Scalar>()) const; template<typename OtherDerived> bool isMuchSmallerThan(const DenseBase<OtherDerived>& other, - RealScalar prec = precision<Scalar>()) const; + RealScalar prec = dummy_precision<Scalar>()) const; - bool isApproxToConstant(const Scalar& value, RealScalar prec = precision<Scalar>()) const; - bool isConstant(const Scalar& value, RealScalar prec = precision<Scalar>()) const; - bool isZero(RealScalar prec = precision<Scalar>()) const; - bool isOnes(RealScalar prec = precision<Scalar>()) const; + bool isApproxToConstant(const Scalar& value, RealScalar prec = dummy_precision<Scalar>()) const; + bool isConstant(const Scalar& value, RealScalar prec = dummy_precision<Scalar>()) const; + bool isZero(RealScalar prec = dummy_precision<Scalar>()) const; + bool isOnes(RealScalar prec = dummy_precision<Scalar>()) const; + // FIXME EIGEN_STRONG_INLINE Derived& operator*=(const Scalar& other) { SelfCwiseBinaryOp<ei_scalar_product_op<Scalar>, Derived> tmp(derived()); @@ -409,6 +401,7 @@ template<typename Derived> class DenseBase return derived(); } + // FIXME // template<typename OtherDerived> // inline bool operator==(const DenseBase<OtherDerived>& other) const // { return cwiseEqual(other).all(); } @@ -487,11 +480,11 @@ template<typename Derived> class DenseBase const DenseBase<ElseDerived>& elseMatrix) const; template<typename ThenDerived> - inline const Select<Derived,ThenDerived, NestByValue<typename ThenDerived::ConstantReturnType> > + inline const Select<Derived,ThenDerived, typename ThenDerived::ConstantReturnType> select(const DenseBase<ThenDerived>& thenMatrix, typename ThenDerived::Scalar elseScalar) const; template<typename ElseDerived> - inline const Select<Derived, NestByValue<typename ElseDerived::ConstantReturnType>, ElseDerived > + inline const Select<Derived, typename ElseDerived::ConstantReturnType, ElseDerived > select(typename ElseDerived::Scalar thenScalar, const DenseBase<ElseDerived>& elseMatrix) const; template<int p> RealScalar lpNorm() const; diff --git a/Eigen/src/Core/DenseStorageBase.h b/Eigen/src/Core/DenseStorageBase.h index ed116d708..7dc8d38c4 100644 --- a/Eigen/src/Core/DenseStorageBase.h +++ b/Eigen/src/Core/DenseStorageBase.h @@ -175,8 +175,14 @@ class DenseStorageBase : public _Base<Derived> && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) && (MaxColsAtCompileTime == Dynamic || MaxColsAtCompileTime >= cols) && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)); - m_storage.resize(rows * cols, rows, cols); - EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO + int size = rows*cols; + bool size_changed = size != this->size(); + m_storage.resize(size, rows, cols); + if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + #else + m_storage.resize(rows*cols, rows, cols); + #endif } /** Resizes \c *this to a vector of length \a size @@ -194,11 +200,16 @@ class DenseStorageBase : public _Base<Derived> { EIGEN_STATIC_ASSERT_VECTOR_ONLY(DenseStorageBase) ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == size); + #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO + bool size_changed = size != this->size(); + #endif if(RowsAtCompileTime == 1) m_storage.resize(size, 1, size); else m_storage.resize(size, size, 1); - EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + #ifdef EIGEN_INITIALIZE_MATRICES_BY_ZERO + if(size_changed) EIGEN_INITIALIZE_BY_ZERO_IF_THAT_OPTION_IS_ENABLED + #endif } /** Resizes the matrix, changing only the number of columns. For the parameter of type NoChange_t, just pass the special value \c NoChange diff --git a/Eigen/src/Core/DiagonalMatrix.h b/Eigen/src/Core/DiagonalMatrix.h index 6f93737ff..bd23b2e09 100644 --- a/Eigen/src/Core/DiagonalMatrix.h +++ b/Eigen/src/Core/DiagonalMatrix.h @@ -26,6 +26,7 @@ #ifndef EIGEN_DIAGONALMATRIX_H #define EIGEN_DIAGONALMATRIX_H +#ifndef EIGEN_PARSED_BY_DOXYGEN template<typename Derived> class DiagonalBase : public AnyMatrixBase<Derived> { @@ -44,19 +45,17 @@ class DiagonalBase : public AnyMatrixBase<Derived> typedef Matrix<Scalar, RowsAtCompileTime, ColsAtCompileTime, 0, MaxRowsAtCompileTime, MaxColsAtCompileTime> DenseMatrixType; - #ifndef EIGEN_PARSED_BY_DOXYGEN inline const Derived& derived() const { return *static_cast<const Derived*>(this); } inline Derived& derived() { return *static_cast<Derived*>(this); } - #endif // not EIGEN_PARSED_BY_DOXYGEN DenseMatrixType toDenseMatrix() const { return derived(); } template<typename DenseDerived> void evalTo(MatrixBase<DenseDerived> &other) const; template<typename DenseDerived> - void addToDense(MatrixBase<DenseDerived> &other) const + void addTo(MatrixBase<DenseDerived> &other) const { other.diagonal() += diagonal(); } template<typename DenseDerived> - void subToDense(MatrixBase<DenseDerived> &other) const + void subTo(MatrixBase<DenseDerived> &other) const { other.diagonal() -= diagonal(); } inline const DiagonalVectorType& diagonal() const { return derived().diagonal(); } @@ -83,16 +82,18 @@ void DiagonalBase<Derived>::evalTo(MatrixBase<DenseDerived> &other) const other.setZero(); other.diagonal() = diagonal(); } +#endif /** \class DiagonalMatrix - * \nonstableyet * * \brief Represents a diagonal matrix with its storage * * \param _Scalar the type of coefficients - * \param _Size the dimension of the matrix, or Dynamic + * \param SizeAtCompileTime the dimension of the matrix, or Dynamic + * \param MaxSizeAtCompileTime the dimension of the matrix, or Dynamic. This parameter is optional and defaults + * to SizeAtCompileTime. Most of the time, you do not need to specify it. * - * \sa class Matrix + * \sa class DiagonalWrapper */ template<typename _Scalar, int SizeAtCompileTime, int MaxSizeAtCompileTime> struct ei_traits<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> > @@ -106,10 +107,11 @@ class DiagonalMatrix : public DiagonalBase<DiagonalMatrix<_Scalar,SizeAtCompileTime,MaxSizeAtCompileTime> > { public: - + #ifndef EIGEN_PARSED_BY_DOXYGEN typedef typename ei_traits<DiagonalMatrix>::DiagonalVectorType DiagonalVectorType; typedef const DiagonalMatrix& Nested; typedef _Scalar Scalar; + #endif protected: @@ -117,7 +119,9 @@ class DiagonalMatrix public: + /** const version of diagonal(). */ inline const DiagonalVectorType& diagonal() const { return m_diagonal; } + /** \returns a reference to the stored vector of diagonal coefficients. */ inline DiagonalVectorType& diagonal() { return m_diagonal; } /** Default constructor without initialization */ @@ -126,23 +130,27 @@ class DiagonalMatrix /** Constructs a diagonal matrix with given dimension */ inline DiagonalMatrix(int dim) : m_diagonal(dim) {} - /** 2D only */ + /** 2D constructor. */ inline DiagonalMatrix(const Scalar& x, const Scalar& y) : m_diagonal(x,y) {} - /** 3D only */ + /** 3D constructor. */ inline DiagonalMatrix(const Scalar& x, const Scalar& y, const Scalar& z) : m_diagonal(x,y,z) {} + /** Copy constructor. */ template<typename OtherDerived> inline DiagonalMatrix(const DiagonalBase<OtherDerived>& other) : m_diagonal(other.diagonal()) {} + #ifndef EIGEN_PARSED_BY_DOXYGEN /** copy constructor. prevent a default copy constructor from hiding the other templated constructor */ inline DiagonalMatrix(const DiagonalMatrix& other) : m_diagonal(other.diagonal()) {} + #endif /** generic constructor from expression of the diagonal coefficients */ template<typename OtherDerived> explicit inline DiagonalMatrix(const MatrixBase<OtherDerived>& other) : m_diagonal(other) {} + /** Copy operator. */ template<typename OtherDerived> DiagonalMatrix& operator=(const DiagonalBase<OtherDerived>& other) { @@ -150,6 +158,7 @@ class DiagonalMatrix return *this; } + #ifndef EIGEN_PARSED_BY_DOXYGEN /** This is a special case of the templated operator=. Its purpose is to * prevent a default operator= from hiding the templated operator=. */ @@ -158,23 +167,28 @@ class DiagonalMatrix m_diagonal = other.m_diagonal(); return *this; } + #endif + /** Resizes to given size. */ inline void resize(int size) { m_diagonal.resize(size); } + /** Sets all coefficients to zero. */ inline void setZero() { m_diagonal.setZero(); } + /** Resizes and sets all coefficients to zero. */ inline void setZero(int size) { m_diagonal.setZero(size); } + /** Sets this matrix to be the identity matrix of the current size. */ inline void setIdentity() { m_diagonal.setOnes(); } + /** Sets this matrix to be the identity matrix of the given size. */ inline void setIdentity(int size) { m_diagonal.setOnes(size); } }; /** \class DiagonalWrapper - * \nonstableyet * * \brief Expression of a diagonal matrix * * \param _DiagonalVectorType the type of the vector of diagonal coefficients * - * This class is an expression of a diagonal matrix with given vector of diagonal - * coefficients. It is the return type of MatrixBase::asDiagonal() + * This class is an expression of a diagonal matrix, but not storing its own vector of diagonal coefficients, + * instead wrapping an existing vector expression. It is the return type of MatrixBase::asDiagonal() * and most of the time this is the only way that it is used. * * \sa class DiagonalMatrix, class DiagonalBase, MatrixBase::asDiagonal() @@ -198,18 +212,22 @@ class DiagonalWrapper : public DiagonalBase<DiagonalWrapper<_DiagonalVectorType> >, ei_no_assignment_operator { public: + #ifndef EIGEN_PARSED_BY_DOXYGEN typedef _DiagonalVectorType DiagonalVectorType; typedef DiagonalWrapper Nested; + #endif + /** Constructor from expression of diagonal coefficients to wrap. */ inline DiagonalWrapper(const DiagonalVectorType& diagonal) : m_diagonal(diagonal) {} + + /** \returns a const reference to the wrapped expression of diagonal coefficients. */ const DiagonalVectorType& diagonal() const { return m_diagonal; } protected: const typename DiagonalVectorType::Nested m_diagonal; }; -/** \nonstableyet - * \returns a pseudo-expression of a diagonal matrix with *this as vector of diagonal coefficients +/** \returns a pseudo-expression of a diagonal matrix with *this as vector of diagonal coefficients * * \only_for_vectors * @@ -225,8 +243,7 @@ MatrixBase<Derived>::asDiagonal() const return derived(); } -/** \nonstableyet - * \returns true if *this is approximately equal to a diagonal matrix, +/** \returns true if *this is approximately equal to a diagonal matrix, * within the precision given by \a prec. * * Example: \include MatrixBase_isDiagonal.cpp diff --git a/Eigen/src/Core/Dot.h b/Eigen/src/Core/Dot.h index 4a164a99e..f0c520b1f 100644 --- a/Eigen/src/Core/Dot.h +++ b/Eigen/src/Core/Dot.h @@ -34,10 +34,10 @@ struct ei_dot_traits { public: enum { - Vectorization = (int(Derived1::Flags)&int(Derived2::Flags)&ActualPacketAccessBit) + Traversal = (int(Derived1::Flags)&int(Derived2::Flags)&ActualPacketAccessBit) && (int(Derived1::Flags)&int(Derived2::Flags)&LinearAccessBit) - ? LinearVectorization - : NoVectorization + ? LinearVectorizedTraversal + : DefaultTraversal }; private: @@ -46,7 +46,7 @@ private: PacketSize = ei_packet_traits<Scalar>::size, Cost = Derived1::SizeAtCompileTime * (Derived1::CoeffReadCost + Derived2::CoeffReadCost + NumTraits<Scalar>::MulCost) + (Derived1::SizeAtCompileTime-1) * NumTraits<Scalar>::AddCost, - UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Vectorization) == int(NoVectorization) ? 1 : int(PacketSize)) + UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize)) }; public: @@ -142,13 +142,13 @@ struct ei_dot_vec_unroller<Derived1, Derived2, Index, Stop, true> ***************************************************************************/ template<typename Derived1, typename Derived2, - int Vectorization = ei_dot_traits<Derived1, Derived2>::Vectorization, + int Traversal = ei_dot_traits<Derived1, Derived2>::Traversal, int Unrolling = ei_dot_traits<Derived1, Derived2>::Unrolling > struct ei_dot_impl; template<typename Derived1, typename Derived2> -struct ei_dot_impl<Derived1, Derived2, NoVectorization, NoUnrolling> +struct ei_dot_impl<Derived1, Derived2, DefaultTraversal, NoUnrolling> { typedef typename Derived1::Scalar Scalar; static Scalar run(const Derived1& v1, const Derived2& v2) @@ -163,12 +163,12 @@ struct ei_dot_impl<Derived1, Derived2, NoVectorization, NoUnrolling> }; template<typename Derived1, typename Derived2> -struct ei_dot_impl<Derived1, Derived2, NoVectorization, CompleteUnrolling> +struct ei_dot_impl<Derived1, Derived2, DefaultTraversal, CompleteUnrolling> : public ei_dot_novec_unroller<Derived1, Derived2, 0, Derived1::SizeAtCompileTime> {}; template<typename Derived1, typename Derived2> -struct ei_dot_impl<Derived1, Derived2, LinearVectorization, NoUnrolling> +struct ei_dot_impl<Derived1, Derived2, LinearVectorizedTraversal, NoUnrolling> { typedef typename Derived1::Scalar Scalar; typedef typename ei_packet_traits<Scalar>::type PacketScalar; @@ -221,20 +221,20 @@ struct ei_dot_impl<Derived1, Derived2, LinearVectorization, NoUnrolling> }; template<typename Derived1, typename Derived2> -struct ei_dot_impl<Derived1, Derived2, LinearVectorization, CompleteUnrolling> +struct ei_dot_impl<Derived1, Derived2, LinearVectorizedTraversal, CompleteUnrolling> { typedef typename Derived1::Scalar Scalar; typedef typename ei_packet_traits<Scalar>::type PacketScalar; enum { PacketSize = ei_packet_traits<Scalar>::size, Size = Derived1::SizeAtCompileTime, - VectorizationSize = (Size / PacketSize) * PacketSize + VectorizedSize = (Size / PacketSize) * PacketSize }; static Scalar run(const Derived1& v1, const Derived2& v2) { - Scalar res = ei_predux(ei_dot_vec_unroller<Derived1, Derived2, 0, VectorizationSize>::run(v1, v2)); - if (VectorizationSize != Size) - res += ei_dot_novec_unroller<Derived1, Derived2, VectorizationSize, Size-VectorizationSize>::run(v1, v2); + Scalar res = ei_predux(ei_dot_vec_unroller<Derived1, Derived2, 0, VectorizedSize>::run(v1, v2)); + if (VectorizedSize != Size) + res += ei_dot_novec_unroller<Derived1, Derived2, VectorizedSize, Size-VectorizedSize>::run(v1, v2); return res; } }; diff --git a/Eigen/src/Core/ExpressionMaker.h b/Eigen/src/Core/ExpressionMaker.h index 1d265b63c..7e2b81d4a 100644 --- a/Eigen/src/Core/ExpressionMaker.h +++ b/Eigen/src/Core/ExpressionMaker.h @@ -37,12 +37,6 @@ template<typename XprType> struct ei_shape_of // matrix. Unless we change the overall design, here is a workaround. // There is an example in unsuported/Eigen/src/AutoDiff/AutoDiffScalar. -template<typename XprType, int Shape = ei_shape_of<XprType>::ret> -struct MakeNestByValue -{ - typedef NestByValue<XprType> Type; -}; - template<typename Func, typename XprType, int Shape = ei_shape_of<XprType>::ret> struct MakeCwiseUnaryOp { diff --git a/Eigen/src/Core/Functors.h b/Eigen/src/Core/Functors.h index 259f40244..aa3eba5cc 100644 --- a/Eigen/src/Core/Functors.h +++ b/Eigen/src/Core/Functors.h @@ -32,7 +32,8 @@ * * \sa class CwiseBinaryOp, MatrixBase::operator+, class VectorwiseOp, MatrixBase::sum() */ -template<typename Scalar> struct ei_scalar_sum_op EIGEN_EMPTY_STRUCT { +template<typename Scalar> struct ei_scalar_sum_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_sum_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a + b; } template<typename PacketScalar> EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const @@ -54,7 +55,8 @@ struct ei_functor_traits<ei_scalar_sum_op<Scalar> > { * * \sa class CwiseBinaryOp, Cwise::operator*(), class VectorwiseOp, MatrixBase::redux() */ -template<typename Scalar> struct ei_scalar_product_op EIGEN_EMPTY_STRUCT { +template<typename Scalar> struct ei_scalar_product_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_product_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a * b; } template<typename PacketScalar> EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const @@ -76,7 +78,8 @@ struct ei_functor_traits<ei_scalar_product_op<Scalar> > { * * \sa class CwiseBinaryOp, MatrixBase::cwiseMin, class VectorwiseOp, MatrixBase::minCoeff() */ -template<typename Scalar> struct ei_scalar_min_op EIGEN_EMPTY_STRUCT { +template<typename Scalar> struct ei_scalar_min_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_min_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::min(a, b); } template<typename PacketScalar> EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const @@ -98,7 +101,8 @@ struct ei_functor_traits<ei_scalar_min_op<Scalar> > { * * \sa class CwiseBinaryOp, MatrixBase::cwiseMax, class VectorwiseOp, MatrixBase::maxCoeff() */ -template<typename Scalar> struct ei_scalar_max_op EIGEN_EMPTY_STRUCT { +template<typename Scalar> struct ei_scalar_max_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_max_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return std::max(a, b); } template<typename PacketScalar> EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const @@ -120,7 +124,8 @@ struct ei_functor_traits<ei_scalar_max_op<Scalar> > { * * \sa MatrixBase::stableNorm(), class Redux */ -template<typename Scalar> struct ei_scalar_hypot_op EIGEN_EMPTY_STRUCT { +template<typename Scalar> struct ei_scalar_hypot_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_hypot_op) // typedef typename NumTraits<Scalar>::Real result_type; EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& _x, const Scalar& _y) const { @@ -142,7 +147,8 @@ struct ei_functor_traits<ei_scalar_hypot_op<Scalar> > { * * \sa class CwiseBinaryOp, MatrixBase::operator- */ -template<typename Scalar> struct ei_scalar_difference_op EIGEN_EMPTY_STRUCT { +template<typename Scalar> struct ei_scalar_difference_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_difference_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a - b; } template<typename PacketScalar> EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const @@ -161,7 +167,8 @@ struct ei_functor_traits<ei_scalar_difference_op<Scalar> > { * * \sa class CwiseBinaryOp, Cwise::operator/() */ -template<typename Scalar> struct ei_scalar_quotient_op EIGEN_EMPTY_STRUCT { +template<typename Scalar> struct ei_scalar_quotient_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_quotient_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a, const Scalar& b) const { return a / b; } template<typename PacketScalar> EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a, const PacketScalar& b) const @@ -185,7 +192,8 @@ struct ei_functor_traits<ei_scalar_quotient_op<Scalar> > { * * \sa class CwiseUnaryOp, MatrixBase::operator- */ -template<typename Scalar> struct ei_scalar_opposite_op EIGEN_EMPTY_STRUCT { +template<typename Scalar> struct ei_scalar_opposite_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_opposite_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return -a; } template<typename PacketScalar> EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const @@ -203,7 +211,8 @@ struct ei_functor_traits<ei_scalar_opposite_op<Scalar> > * * \sa class CwiseUnaryOp, Cwise::abs */ -template<typename Scalar> struct ei_scalar_abs_op EIGEN_EMPTY_STRUCT { +template<typename Scalar> struct ei_scalar_abs_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_abs_op) typedef typename NumTraits<Scalar>::Real result_type; EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return ei_abs(a); } template<typename PacketScalar> @@ -224,7 +233,8 @@ struct ei_functor_traits<ei_scalar_abs_op<Scalar> > * * \sa class CwiseUnaryOp, Cwise::abs2 */ -template<typename Scalar> struct ei_scalar_abs2_op EIGEN_EMPTY_STRUCT { +template<typename Scalar> struct ei_scalar_abs2_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_abs2_op) typedef typename NumTraits<Scalar>::Real result_type; EIGEN_STRONG_INLINE const result_type operator() (const Scalar& a) const { return ei_abs2(a); } template<typename PacketScalar> @@ -240,7 +250,8 @@ struct ei_functor_traits<ei_scalar_abs2_op<Scalar> > * * \sa class CwiseUnaryOp, MatrixBase::conjugate() */ -template<typename Scalar> struct ei_scalar_conjugate_op EIGEN_EMPTY_STRUCT { +template<typename Scalar> struct ei_scalar_conjugate_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_conjugate_op) EIGEN_STRONG_INLINE const Scalar operator() (const Scalar& a) const { return ei_conj(a); } template<typename PacketScalar> EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const { return a; } @@ -260,7 +271,8 @@ struct ei_functor_traits<ei_scalar_conjugate_op<Scalar> > * \sa class CwiseUnaryOp, MatrixBase::cast() */ template<typename Scalar, typename NewType> -struct ei_scalar_cast_op EIGEN_EMPTY_STRUCT { +struct ei_scalar_cast_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_cast_op) typedef NewType result_type; EIGEN_STRONG_INLINE const NewType operator() (const Scalar& a) const { return static_cast<NewType>(a); } }; @@ -274,7 +286,8 @@ struct ei_functor_traits<ei_scalar_cast_op<Scalar,NewType> > * \sa class CwiseUnaryOp, MatrixBase::real() */ template<typename Scalar> -struct ei_scalar_real_op EIGEN_EMPTY_STRUCT { +struct ei_scalar_real_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_real_op) typedef typename NumTraits<Scalar>::Real result_type; EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return ei_real(a); } EIGEN_STRONG_INLINE result_type& operator() (Scalar& a) const { return ei_real_ref(a); } @@ -289,7 +302,8 @@ struct ei_functor_traits<ei_scalar_real_op<Scalar> > * \sa class CwiseUnaryOp, MatrixBase::imag() */ template<typename Scalar> -struct ei_scalar_imag_op EIGEN_EMPTY_STRUCT { +struct ei_scalar_imag_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_imag_op) typedef typename NumTraits<Scalar>::Real result_type; EIGEN_STRONG_INLINE result_type operator() (const Scalar& a) const { return ei_imag(a); } EIGEN_STRONG_INLINE result_type& operator() (Scalar& a) const { return ei_imag_ref(a); } @@ -304,7 +318,8 @@ struct ei_functor_traits<ei_scalar_imag_op<Scalar> > * * \sa class CwiseUnaryOp, Cwise::exp() */ -template<typename Scalar> struct ei_scalar_exp_op EIGEN_EMPTY_STRUCT { +template<typename Scalar> struct ei_scalar_exp_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_exp_op) inline const Scalar operator() (const Scalar& a) const { return ei_exp(a); } typedef typename ei_packet_traits<Scalar>::type Packet; inline Packet packetOp(const Packet& a) const { return ei_pexp(a); } @@ -319,7 +334,8 @@ struct ei_functor_traits<ei_scalar_exp_op<Scalar> > * * \sa class CwiseUnaryOp, Cwise::log() */ -template<typename Scalar> struct ei_scalar_log_op EIGEN_EMPTY_STRUCT { +template<typename Scalar> struct ei_scalar_log_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_log_op) inline const Scalar operator() (const Scalar& a) const { return ei_log(a); } typedef typename ei_packet_traits<Scalar>::type Packet; inline Packet packetOp(const Packet& a) const { return ei_plog(a); } @@ -351,8 +367,6 @@ struct ei_scalar_multiple_op { EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const { return ei_pmul(a, ei_pset1(m_other)); } typename ei_makeconst<typename NumTraits<Scalar>::Nested>::type m_other; -private: - ei_scalar_multiple_op& operator=(const ei_scalar_multiple_op&); }; template<typename Scalar> struct ei_functor_traits<ei_scalar_multiple_op<Scalar> > @@ -380,8 +394,6 @@ struct ei_scalar_quotient1_impl { EIGEN_STRONG_INLINE const PacketScalar packetOp(const PacketScalar& a) const { return ei_pmul(a, ei_pset1(m_other)); } const Scalar m_other; -private: - ei_scalar_quotient1_impl& operator=(const ei_scalar_quotient1_impl&); }; template<typename Scalar> struct ei_functor_traits<ei_scalar_quotient1_impl<Scalar,true> > @@ -427,15 +439,13 @@ struct ei_scalar_constant_op { EIGEN_STRONG_INLINE const Scalar operator() (int, int = 0) const { return m_other; } EIGEN_STRONG_INLINE const PacketScalar packetOp() const { return ei_pset1(m_other); } const Scalar m_other; -private: - ei_scalar_constant_op& operator=(const ei_scalar_constant_op&); }; template<typename Scalar> struct ei_functor_traits<ei_scalar_constant_op<Scalar> > { enum { Cost = 1, PacketAccess = ei_packet_traits<Scalar>::size>1, IsRepeatable = true }; }; -template<typename Scalar> struct ei_scalar_identity_op EIGEN_EMPTY_STRUCT { - EIGEN_STRONG_INLINE ei_scalar_identity_op(void) {} +template<typename Scalar> struct ei_scalar_identity_op { + EIGEN_EMPTY_STRUCT_CTOR(ei_scalar_identity_op) EIGEN_STRONG_INLINE const Scalar operator() (int row, int col) const { return row==col ? Scalar(1) : Scalar(0); } }; template<typename Scalar> diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index 05469b340..7ffddcbf8 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -30,7 +30,7 @@ template<typename T> inline typename NumTraits<T>::Real epsilon() return std::numeric_limits<typename NumTraits<T>::Real>::epsilon(); } -template<typename T> inline typename NumTraits<T>::Real precision(); +template<typename T> inline typename NumTraits<T>::Real dummy_precision(); template<typename T> inline T ei_random(T a, T b); template<typename T> inline T ei_random(); @@ -55,7 +55,7 @@ template<typename T> inline typename NumTraits<T>::Real ei_hypot(T x, T y) *** int *** **************/ -template<> inline int precision<int>() { return 0; } +template<> inline int dummy_precision<int>() { return 0; } inline int ei_real(int x) { return x; } inline int& ei_real_ref(int& x) { return x; } inline int ei_imag(int) { return 0; } @@ -92,15 +92,15 @@ template<> inline int ei_random() { return ei_random<int>(-ei_random_amplitude<int>(), ei_random_amplitude<int>()); } -inline bool ei_isMuchSmallerThan(int a, int, int = precision<int>()) +inline bool ei_isMuchSmallerThan(int a, int, int = dummy_precision<int>()) { return a == 0; } -inline bool ei_isApprox(int a, int b, int = precision<int>()) +inline bool ei_isApprox(int a, int b, int = dummy_precision<int>()) { return a == b; } -inline bool ei_isApproxOrLessThan(int a, int b, int = precision<int>()) +inline bool ei_isApproxOrLessThan(int a, int b, int = dummy_precision<int>()) { return a <= b; } @@ -109,7 +109,7 @@ inline bool ei_isApproxOrLessThan(int a, int b, int = precision<int>()) *** float *** **************/ -template<> inline float precision<float>() { return 1e-5f; } +template<> inline float dummy_precision<float>() { return 1e-5f; } inline float ei_real(float x) { return x; } inline float& ei_real_ref(float& x) { return x; } inline float ei_imag(float) { return 0.f; } @@ -140,15 +140,15 @@ template<> inline float ei_random() { return ei_random<float>(-ei_random_amplitude<float>(), ei_random_amplitude<float>()); } -inline bool ei_isMuchSmallerThan(float a, float b, float prec = precision<float>()) +inline bool ei_isMuchSmallerThan(float a, float b, float prec = dummy_precision<float>()) { return ei_abs(a) <= ei_abs(b) * prec; } -inline bool ei_isApprox(float a, float b, float prec = precision<float>()) +inline bool ei_isApprox(float a, float b, float prec = dummy_precision<float>()) { return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec; } -inline bool ei_isApproxOrLessThan(float a, float b, float prec = precision<float>()) +inline bool ei_isApproxOrLessThan(float a, float b, float prec = dummy_precision<float>()) { return a <= b || ei_isApprox(a, b, prec); } @@ -157,7 +157,7 @@ inline bool ei_isApproxOrLessThan(float a, float b, float prec = precision<float *** double *** **************/ -template<> inline double precision<double>() { return 1e-12; } +template<> inline double dummy_precision<double>() { return 1e-12; } inline double ei_real(double x) { return x; } inline double& ei_real_ref(double& x) { return x; } @@ -189,15 +189,15 @@ template<> inline double ei_random() { return ei_random<double>(-ei_random_amplitude<double>(), ei_random_amplitude<double>()); } -inline bool ei_isMuchSmallerThan(double a, double b, double prec = precision<double>()) +inline bool ei_isMuchSmallerThan(double a, double b, double prec = dummy_precision<double>()) { return ei_abs(a) <= ei_abs(b) * prec; } -inline bool ei_isApprox(double a, double b, double prec = precision<double>()) +inline bool ei_isApprox(double a, double b, double prec = dummy_precision<double>()) { return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec; } -inline bool ei_isApproxOrLessThan(double a, double b, double prec = precision<double>()) +inline bool ei_isApproxOrLessThan(double a, double b, double prec = dummy_precision<double>()) { return a <= b || ei_isApprox(a, b, prec); } @@ -206,7 +206,7 @@ inline bool ei_isApproxOrLessThan(double a, double b, double prec = precision<do *** complex<float> *** *********************/ -template<> inline float precision<std::complex<float> >() { return precision<float>(); } +template<> inline float dummy_precision<std::complex<float> >() { return dummy_precision<float>(); } inline float ei_real(const std::complex<float>& x) { return std::real(x); } inline float ei_imag(const std::complex<float>& x) { return std::imag(x); } inline float& ei_real_ref(std::complex<float>& x) { return reinterpret_cast<float*>(&x)[0]; } @@ -224,15 +224,15 @@ template<> inline std::complex<float> ei_random() { return std::complex<float>(ei_random<float>(), ei_random<float>()); } -inline bool ei_isMuchSmallerThan(const std::complex<float>& a, const std::complex<float>& b, float prec = precision<float>()) +inline bool ei_isMuchSmallerThan(const std::complex<float>& a, const std::complex<float>& b, float prec = dummy_precision<float>()) { return ei_abs2(a) <= ei_abs2(b) * prec * prec; } -inline bool ei_isMuchSmallerThan(const std::complex<float>& a, float b, float prec = precision<float>()) +inline bool ei_isMuchSmallerThan(const std::complex<float>& a, float b, float prec = dummy_precision<float>()) { return ei_abs2(a) <= ei_abs2(b) * prec * prec; } -inline bool ei_isApprox(const std::complex<float>& a, const std::complex<float>& b, float prec = precision<float>()) +inline bool ei_isApprox(const std::complex<float>& a, const std::complex<float>& b, float prec = dummy_precision<float>()) { return ei_isApprox(ei_real(a), ei_real(b), prec) && ei_isApprox(ei_imag(a), ei_imag(b), prec); @@ -243,7 +243,7 @@ inline bool ei_isApprox(const std::complex<float>& a, const std::complex<float>& *** complex<double> *** **********************/ -template<> inline double precision<std::complex<double> >() { return precision<double>(); } +template<> inline double dummy_precision<std::complex<double> >() { return dummy_precision<double>(); } inline double ei_real(const std::complex<double>& x) { return std::real(x); } inline double ei_imag(const std::complex<double>& x) { return std::imag(x); } inline double& ei_real_ref(std::complex<double>& x) { return reinterpret_cast<double*>(&x)[0]; } @@ -261,15 +261,15 @@ template<> inline std::complex<double> ei_random() { return std::complex<double>(ei_random<double>(), ei_random<double>()); } -inline bool ei_isMuchSmallerThan(const std::complex<double>& a, const std::complex<double>& b, double prec = precision<double>()) +inline bool ei_isMuchSmallerThan(const std::complex<double>& a, const std::complex<double>& b, double prec = dummy_precision<double>()) { return ei_abs2(a) <= ei_abs2(b) * prec * prec; } -inline bool ei_isMuchSmallerThan(const std::complex<double>& a, double b, double prec = precision<double>()) +inline bool ei_isMuchSmallerThan(const std::complex<double>& a, double b, double prec = dummy_precision<double>()) { return ei_abs2(a) <= ei_abs2(b) * prec * prec; } -inline bool ei_isApprox(const std::complex<double>& a, const std::complex<double>& b, double prec = precision<double>()) +inline bool ei_isApprox(const std::complex<double>& a, const std::complex<double>& b, double prec = dummy_precision<double>()) { return ei_isApprox(ei_real(a), ei_real(b), prec) && ei_isApprox(ei_imag(a), ei_imag(b), prec); @@ -281,7 +281,7 @@ inline bool ei_isApprox(const std::complex<double>& a, const std::complex<double *** long double *** ******************/ -template<> inline long double precision<long double>() { return precision<double>(); } +template<> inline long double dummy_precision<long double>() { return dummy_precision<double>(); } inline long double ei_real(long double x) { return x; } inline long double& ei_real_ref(long double& x) { return x; } inline long double ei_imag(long double) { return 0.; } @@ -304,15 +304,15 @@ template<> inline long double ei_random() { return ei_random<double>(-ei_random_amplitude<double>(), ei_random_amplitude<double>()); } -inline bool ei_isMuchSmallerThan(long double a, long double b, long double prec = precision<long double>()) +inline bool ei_isMuchSmallerThan(long double a, long double b, long double prec = dummy_precision<long double>()) { return ei_abs(a) <= ei_abs(b) * prec; } -inline bool ei_isApprox(long double a, long double b, long double prec = precision<long double>()) +inline bool ei_isApprox(long double a, long double b, long double prec = dummy_precision<long double>()) { return ei_abs(a - b) <= std::min(ei_abs(a), ei_abs(b)) * prec; } -inline bool ei_isApproxOrLessThan(long double a, long double b, long double prec = precision<long double>()) +inline bool ei_isApproxOrLessThan(long double a, long double b, long double prec = dummy_precision<long double>()) { return a <= b || ei_isApprox(a, b, prec); } @@ -321,7 +321,7 @@ inline bool ei_isApproxOrLessThan(long double a, long double b, long double prec *** bool *** **************/ -template<> inline bool precision<bool>() { return 0; } +template<> inline bool dummy_precision<bool>() { return 0; } inline bool ei_real(bool x) { return x; } inline bool& ei_real_ref(bool& x) { return x; } inline bool ei_imag(bool) { return 0; } @@ -334,15 +334,15 @@ template<> inline bool ei_random() { return (ei_random<int>(0,1) == 1); } -inline bool ei_isMuchSmallerThan(bool a, bool, bool = precision<bool>()) +inline bool ei_isMuchSmallerThan(bool a, bool, bool = dummy_precision<bool>()) { return !a; } -inline bool ei_isApprox(bool a, bool b, bool = precision<bool>()) +inline bool ei_isApprox(bool a, bool b, bool = dummy_precision<bool>()) { return a == b; } -inline bool ei_isApproxOrLessThan(bool a, bool b, bool = precision<bool>()) +inline bool ei_isApproxOrLessThan(bool a, bool b, bool = dummy_precision<bool>()) { return int(a) <= int(b); } diff --git a/Eigen/src/Core/Matrix.h b/Eigen/src/Core/Matrix.h index 75c0a73b5..24c618549 100644 --- a/Eigen/src/Core/Matrix.h +++ b/Eigen/src/Core/Matrix.h @@ -152,7 +152,6 @@ class Matrix using Base::coeff; using Base::coeffRef; - /** Copies the value of the expression \a other into \c *this with automatic resizing. * * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized), @@ -286,9 +285,6 @@ class Matrix other.evalTo(*this); } - /** Destructor */ - inline ~Matrix() {} - /** \sa MatrixBase::operator=(const AnyMatrixBase<OtherDerived>&) */ template<typename OtherDerived> EIGEN_STRONG_INLINE Matrix(const AnyMatrixBase<OtherDerived> &other) diff --git a/Eigen/src/Core/MatrixBase.h b/Eigen/src/Core/MatrixBase.h index 53dd6f991..f7b32a650 100644 --- a/Eigen/src/Core/MatrixBase.h +++ b/Eigen/src/Core/MatrixBase.h @@ -144,7 +144,7 @@ template<typename Derived> class MatrixBase typedef CwiseNullaryOp<ei_scalar_constant_op<Scalar>,Derived> ConstantReturnType; /** \internal the return type of MatrixBase::adjoint() */ typedef typename ei_meta_if<NumTraits<Scalar>::IsComplex, - CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<Derived> > >, + CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, Eigen::Transpose<Derived> >, Transpose<Derived> >::ret AdjointReturnType; /** \internal the return type of MatrixBase::eigenvalues() */ @@ -259,16 +259,16 @@ template<typename Derived> class MatrixBase Derived& setIdentity(); - bool isIdentity(RealScalar prec = precision<Scalar>()) const; - bool isDiagonal(RealScalar prec = precision<Scalar>()) const; + bool isIdentity(RealScalar prec = dummy_precision<Scalar>()) const; + bool isDiagonal(RealScalar prec = dummy_precision<Scalar>()) const; - bool isUpperTriangular(RealScalar prec = precision<Scalar>()) const; - bool isLowerTriangular(RealScalar prec = precision<Scalar>()) const; + bool isUpperTriangular(RealScalar prec = dummy_precision<Scalar>()) const; + bool isLowerTriangular(RealScalar prec = dummy_precision<Scalar>()) const; template<typename OtherDerived> bool isOrthogonal(const MatrixBase<OtherDerived>& other, - RealScalar prec = precision<Scalar>()) const; - bool isUnitary(RealScalar prec = precision<Scalar>()) const; + RealScalar prec = dummy_precision<Scalar>()) const; + bool isUnitary(RealScalar prec = dummy_precision<Scalar>()) const; /** \returns true if each coefficients of \c *this and \a other are all exactly equal. * \warning When using floating point scalar values you probably should rather use a @@ -332,13 +332,13 @@ template<typename Derived> class MatrixBase ResultType& inverse, typename ResultType::Scalar& determinant, bool& invertible, - const RealScalar& absDeterminantThreshold = precision<Scalar>() + const RealScalar& absDeterminantThreshold = dummy_precision<Scalar>() ) const; template<typename ResultType> void computeInverseWithCheck( ResultType& inverse, bool& invertible, - const RealScalar& absDeterminantThreshold = precision<Scalar>() + const RealScalar& absDeterminantThreshold = dummy_precision<Scalar>() ) const; Scalar determinant() const; @@ -376,7 +376,7 @@ template<typename Derived> class MatrixBase ei_traits<Derived>::ColsAtCompileTime==1 ? SizeMinusOne : 1, ei_traits<Derived>::ColsAtCompileTime==1 ? 1 : SizeMinusOne> StartMinusOne; typedef CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<Derived>::Scalar>, - NestByValue<StartMinusOne> > HNormalizedReturnType; + StartMinusOne > HNormalizedReturnType; const HNormalizedReturnType hnormalized() const; typedef Homogeneous<Derived,MatrixBase<Derived>::ColsAtCompileTime==1?Vertical:Horizontal> HomogeneousReturnType; diff --git a/Eigen/src/Core/MatrixStorage.h b/Eigen/src/Core/MatrixStorage.h index 73b17e63e..8bfa728b6 100644 --- a/Eigen/src/Core/MatrixStorage.h +++ b/Eigen/src/Core/MatrixStorage.h @@ -117,7 +117,6 @@ template<typename T, int Size, int _Options> class ei_matrix_storage<T, Size, Dy inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert) : m_data(ei_constructor_without_unaligned_array_assert()), m_rows(0), m_cols(0) {} inline ei_matrix_storage(int, int rows, int cols) : m_rows(rows), m_cols(cols) {} - inline ~ei_matrix_storage() {} inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); std::swap(m_cols,other.m_cols); } inline int rows(void) const {return m_rows;} @@ -141,7 +140,6 @@ template<typename T, int Size, int _Cols, int _Options> class ei_matrix_storage< inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert) : m_data(ei_constructor_without_unaligned_array_assert()), m_rows(0) {} inline ei_matrix_storage(int, int rows, int) : m_rows(rows) {} - inline ~ei_matrix_storage() {} inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_rows,other.m_rows); } inline int rows(void) const {return m_rows;} inline int cols(void) const {return _Cols;} @@ -163,7 +161,6 @@ template<typename T, int Size, int _Rows, int _Options> class ei_matrix_storage< inline ei_matrix_storage(ei_constructor_without_unaligned_array_assert) : m_data(ei_constructor_without_unaligned_array_assert()), m_cols(0) {} inline ei_matrix_storage(int, int, int cols) : m_cols(cols) {} - inline ~ei_matrix_storage() {} inline void swap(ei_matrix_storage& other) { std::swap(m_data,other.m_data); std::swap(m_cols,other.m_cols); } inline int rows(void) const {return _Rows;} inline int cols(void) const {return m_cols;} diff --git a/Eigen/src/Core/Minor.h b/Eigen/src/Core/Minor.h index 3ed0fec6b..629dbe609 100644 --- a/Eigen/src/Core/Minor.h +++ b/Eigen/src/Core/Minor.h @@ -1,7 +1,7 @@ // This file is part of Eigen, a lightweight C++ template library // for linear algebra. // -// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> +// Copyright (C) 2006-2009 Benoit Jacob <jacob.benoit.1@gmail.com> // // Eigen is free software; you can redistribute it and/or // modify it under the terms of the GNU Lesser General Public @@ -54,7 +54,8 @@ struct ei_traits<Minor<MatrixType> > MaxColsAtCompileTime = (MatrixType::MaxColsAtCompileTime != Dynamic) ? int(MatrixType::MaxColsAtCompileTime) - 1 : Dynamic, Flags = _MatrixTypeNested::Flags & HereditaryBits, - CoeffReadCost = _MatrixTypeNested::CoeffReadCost + CoeffReadCost = _MatrixTypeNested::CoeffReadCost // minor is used typically on tiny matrices, + // where loops are unrolled and the 'if' evaluates at compile time }; }; diff --git a/Eigen/src/Core/NestByValue.h b/Eigen/src/Core/NestByValue.h index 94a8f8078..85a672779 100644 --- a/Eigen/src/Core/NestByValue.h +++ b/Eigen/src/Core/NestByValue.h @@ -102,9 +102,6 @@ template<typename ExpressionType> class NestByValue protected: const ExpressionType m_expression; - - private: - NestByValue& operator=(const NestByValue&); }; /** \returns an expression of the temporary version of *this. diff --git a/Eigen/src/Core/NoAlias.h b/Eigen/src/Core/NoAlias.h index 7ed848bce..bfea5c91d 100644 --- a/Eigen/src/Core/NoAlias.h +++ b/Eigen/src/Core/NoAlias.h @@ -73,9 +73,6 @@ class NoAlias protected: ExpressionType& m_expression; - - private: - NoAlias& operator=(const NoAlias&); }; /** \returns a pseudo expression of \c *this with an operator= assuming diff --git a/Eigen/src/Core/PermutationMatrix.h b/Eigen/src/Core/PermutationMatrix.h index aaccb4e7b..284baf678 100644 --- a/Eigen/src/Core/PermutationMatrix.h +++ b/Eigen/src/Core/PermutationMatrix.h @@ -25,18 +25,24 @@ #ifndef EIGEN_PERMUTATIONMATRIX_H #define EIGEN_PERMUTATIONMATRIX_H -/** \nonstableyet - * \class PermutationMatrix +/** \class PermutationMatrix * * \brief Permutation matrix * * \param SizeAtCompileTime the number of rows/cols, or Dynamic - * \param MaxSizeAtCompileTime the maximum number of rows/cols, or Dynamic. This optional parameter defaults to SizeAtCompileTime. + * \param MaxSizeAtCompileTime the maximum number of rows/cols, or Dynamic. This optional parameter defaults to SizeAtCompileTime. Most of the time, you should not have to specify it. * * This class represents a permutation matrix, internally stored as a vector of integers. - * The convention followed here is the same as on <a href="http://en.wikipedia.org/wiki/Permutation_matrix">Wikipedia</a>, - * namely: the matrix of permutation \a p is the matrix such that on each row \a i, the only nonzero coefficient is - * in column p(i). + * The convention followed here is that if \f$ \sigma \f$ is a permutation, the corresponding permutation matrix + * \f$ P_\sigma \f$ is such that if \f$ (e_1,\ldots,e_p) \f$ is the canonical basis, we have: + * \f[ P_\sigma(e_i) = e_{\sigma(i)}. \f] + * This convention ensures that for any two permutations \f$ \sigma, \tau \f$, we have: + * \f[ P_{\sigma\circ\tau} = P_\sigma P_\tau. \f] + * + * Permutation matrices are square and invertible. + * + * Notice that in addition to the member functions and operators listed here, there also are non-member + * operator* to multiply a PermutationMatrix with any kind of matrix expression (MatrixBase) on either side. * * \sa class DiagonalMatrix */ @@ -53,6 +59,7 @@ class PermutationMatrix : public AnyMatrixBase<PermutationMatrix<SizeAtCompileTi { public: + #ifndef EIGEN_PARSED_BY_DOXYGEN typedef ei_traits<PermutationMatrix> Traits; typedef Matrix<int,SizeAtCompileTime,SizeAtCompileTime,0,MaxSizeAtCompileTime,MaxSizeAtCompileTime> DenseMatrixType; @@ -65,25 +72,37 @@ class PermutationMatrix : public AnyMatrixBase<PermutationMatrix<SizeAtCompileTi MaxColsAtCompileTime = Traits::MaxColsAtCompileTime }; typedef typename Traits::Scalar Scalar; + #endif - typedef Matrix<int, RowsAtCompileTime, 1, 0, MaxRowsAtCompileTime, 1> IndicesType; + typedef Matrix<int, SizeAtCompileTime, 1, 0, MaxSizeAtCompileTime, 1> IndicesType; inline PermutationMatrix() { } + /** Copy constructor. */ template<int OtherSize, int OtherMaxSize> inline PermutationMatrix(const PermutationMatrix<OtherSize, OtherMaxSize>& other) : m_indices(other.indices()) {} - /** copy constructor. prevent a default copy constructor from hiding the other templated constructor */ + #ifndef EIGEN_PARSED_BY_DOXYGEN + /** Standard copy constructor. Defined only to prevent a default copy constructor + * from hiding the other templated constructor */ inline PermutationMatrix(const PermutationMatrix& other) : m_indices(other.indices()) {} + #endif - /** generic constructor from expression of the indices */ + /** Generic constructor from expression of the indices. The indices + * array has the meaning that the permutations sends each integer i to indices[i]. + * + * \warning It is your responsibility to check that the indices array that you passes actually + * describes a permutation, i.e., each value between 0 and n-1 occurs exactly once, where n is the + * array's size. + */ template<typename Other> - explicit inline PermutationMatrix(const MatrixBase<Other>& other) : m_indices(other) + explicit inline PermutationMatrix(const MatrixBase<Other>& indices) : m_indices(indices) {} + /** Copies the other permutation into *this */ template<int OtherSize, int OtherMaxSize> PermutationMatrix& operator=(const PermutationMatrix<OtherSize, OtherMaxSize>& other) { @@ -91,42 +110,143 @@ class PermutationMatrix : public AnyMatrixBase<PermutationMatrix<SizeAtCompileTi return *this; } + #ifndef EIGEN_PARSED_BY_DOXYGEN /** This is a special case of the templated operator=. Its purpose is to * prevent a default operator= from hiding the templated operator=. */ PermutationMatrix& operator=(const PermutationMatrix& other) { - m_indices = other.m_indices(); + m_indices = other.m_indices; return *this; } + #endif - inline PermutationMatrix(int rows, int cols) : m_indices(rows) - { - ei_assert(rows == cols); - } + /** Constructs an uninitialized permutation matrix of given size. + */ + inline PermutationMatrix(int size) : m_indices(size) + {} - /** \returns the number of columns */ + /** \returns the number of rows */ inline int rows() const { return m_indices.size(); } - /** \returns the number of rows */ + /** \returns the number of columns */ inline int cols() const { return m_indices.size(); } + #ifndef EIGEN_PARSED_BY_DOXYGEN template<typename DenseDerived> void evalTo(MatrixBase<DenseDerived>& other) const { other.setZero(); for (int i=0; i<rows();++i) - other.coeffRef(i,m_indices.coeff(i)) = typename DenseDerived::Scalar(1); + other.coeffRef(m_indices.coeff(i),i) = typename DenseDerived::Scalar(1); } + #endif + /** \returns a Matrix object initialized from this permutation matrix. Notice that it + * is inefficient to return this Matrix object by value. For efficiency, favor using + * the Matrix constructor taking AnyMatrixBase objects. + */ DenseMatrixType toDenseMatrix() const { return *this; } + /** const version of indices(). */ const IndicesType& indices() const { return m_indices; } + /** \returns a reference to the stored array representing the permutation. */ IndicesType& indices() { return m_indices; } - + + /** Resizes to given size. + */ + inline void resize(int size) + { + m_indices.resize(size); + } + + /** Sets *this to be the identity permutation matrix */ + void setIdentity() + { + for(int i = 0; i < m_indices.size(); ++i) + m_indices.coeffRef(i) = i; + } + + /** Sets *this to be the identity permutation matrix of given size. + */ + void setIdentity(int size) + { + resize(size); + setIdentity(); + } + + /** Multiplies *this by the transposition \f$(ij)\f$ on the left. + * + * \returns a reference to *this. + * + * \warning This is much slower than applyTranspositionOnTheRight(int,int): + * this has linear complexity and requires a lot of branching. + * + * \sa applyTranspositionOnTheRight(int,int) + */ + PermutationMatrix& applyTranspositionOnTheLeft(int i, int j) + { + ei_assert(i>=0 && j>=0 && i<m_indices.size() && j<m_indices.size()); + for(int k = 0; k < m_indices.size(); ++k) + { + if(m_indices.coeff(k) == i) m_indices.coeffRef(k) = j; + else if(m_indices.coeff(k) == j) m_indices.coeffRef(k) = i; + } + return *this; + } + + /** Multiplies *this by the transposition \f$(ij)\f$ on the right. + * + * \returns a reference to *this. + * + * This is a fast operation, it only consists in swapping two indices. + * + * \sa applyTranspositionOnTheLeft(int,int) + */ + PermutationMatrix& applyTranspositionOnTheRight(int i, int j) + { + ei_assert(i>=0 && j>=0 && i<m_indices.size() && j<m_indices.size()); + std::swap(m_indices.coeffRef(i), m_indices.coeffRef(j)); + return *this; + } + + /**** inversion and multiplication helpers to hopefully get RVO ****/ + +#ifndef EIGEN_PARSED_BY_DOXYGEN + protected: + enum Inverse_t {Inverse}; + PermutationMatrix(Inverse_t, const PermutationMatrix& other) + : m_indices(other.m_indices.size()) + { + for (int i=0; i<rows();++i) m_indices.coeffRef(other.m_indices.coeff(i)) = i; + } + enum Product_t {Product}; + PermutationMatrix(Product_t, const PermutationMatrix& lhs, const PermutationMatrix& rhs) + : m_indices(lhs.m_indices.size()) + { + ei_assert(lhs.cols() == rhs.rows()); + for (int i=0; i<rows();++i) m_indices.coeffRef(i) = lhs.m_indices.coeff(rhs.m_indices.coeff(i)); + } +#endif + + public: + /** \returns the inverse permutation matrix. + * + * \note \note_try_to_help_rvo + */ + inline PermutationMatrix inverse() const + { return PermutationMatrix(Inverse, *this); } + /** \returns the product permutation matrix. + * + * \note \note_try_to_help_rvo + */ + template<int OtherSize, int OtherMaxSize> + inline PermutationMatrix operator*(const PermutationMatrix<OtherSize, OtherMaxSize>& other) const + { return PermutationMatrix(Product, *this, other); } + protected: IndicesType m_indices; @@ -185,7 +305,7 @@ struct ei_permut_matrix_product_retval Dest, Side==OnTheLeft ? 1 : Dest::RowsAtCompileTime, Side==OnTheRight ? 1 : Dest::ColsAtCompileTime - >(dst, Side==OnTheRight ? m_permutation.indices().coeff(i) : i) + >(dst, Side==OnTheLeft ? m_permutation.indices().coeff(i) : i) = @@ -193,7 +313,7 @@ struct ei_permut_matrix_product_retval MatrixTypeNestedCleaned, Side==OnTheLeft ? 1 : MatrixType::RowsAtCompileTime, Side==OnTheRight ? 1 : MatrixType::ColsAtCompileTime - >(m_matrix, Side==OnTheLeft ? m_permutation.indices().coeff(i) : i); + >(m_matrix, Side==OnTheRight ? m_permutation.indices().coeff(i) : i); } } diff --git a/Eigen/src/Core/Product.h b/Eigen/src/Core/Product.h index 7db35eaad..15f44de89 100644 --- a/Eigen/src/Core/Product.h +++ b/Eigen/src/Core/Product.h @@ -58,10 +58,12 @@ enum { OuterProduct, InnerProduct, UnrolledProduct, GemvProduct, GemmProduct }; template<typename Lhs, typename Rhs> struct ei_product_type { + typedef typename ei_cleantype<Lhs>::type _Lhs; + typedef typename ei_cleantype<Rhs>::type _Rhs; enum { - Rows = Lhs::RowsAtCompileTime, - Cols = Rhs::ColsAtCompileTime, - Depth = EIGEN_ENUM_MIN(Lhs::ColsAtCompileTime,Rhs::RowsAtCompileTime) + Rows = _Lhs::RowsAtCompileTime, + Cols = _Rhs::ColsAtCompileTime, + Depth = EIGEN_ENUM_MIN(_Lhs::ColsAtCompileTime,_Rhs::RowsAtCompileTime) }; // the splitting into different lines of code here, introducing the _select enums and the typedef below, @@ -211,9 +213,6 @@ class GeneralProduct<Lhs, Rhs, OuterProduct> { ei_outer_product_selector<(int(Dest::Flags)&RowMajorBit) ? RowMajor : ColMajor>::run(*this, dest, alpha); } - - private: - GeneralProduct& operator=(const GeneralProduct&); }; template<> struct ei_outer_product_selector<ColMajor> { @@ -279,9 +278,6 @@ class GeneralProduct<Lhs, Rhs, GemvProduct> ei_gemv_selector<Side,(int(MatrixType::Flags)&RowMajorBit) ? RowMajor : ColMajor, bool(ei_blas_traits<MatrixType>::ActualAccess)>::run(*this, dst, alpha); } - -private: - GeneralProduct& operator=(const GeneralProduct&); }; // The vector is on the left => transposition diff --git a/Eigen/src/Core/ProductBase.h b/Eigen/src/Core/ProductBase.h index d835f16b7..3248e7293 100644 --- a/Eigen/src/Core/ProductBase.h +++ b/Eigen/src/Core/ProductBase.h @@ -114,14 +114,6 @@ class ProductBase : public MatrixBase<Derived> template<typename Dest> inline void scaleAndAddTo(Dest& dst,Scalar alpha) const { derived().scaleAndAddTo(dst,alpha); } - PlainMatrixType eval() const - { - PlainMatrixType res(rows(), cols()); - res.setZero(); - derived().evalTo(res); - return res; - } - EIGEN_DEPRECATED const Flagged<ProductBase, 0, EvalBeforeAssigningBit> lazy() const { return *this; } @@ -140,8 +132,6 @@ class ProductBase : public MatrixBase<Derived> void coeffRef(int,int); void coeff(int) const; void coeffRef(int); - - ProductBase& operator=(const ProductBase&); }; template<typename NestedProduct> diff --git a/Eigen/src/Core/Redux.h b/Eigen/src/Core/Redux.h index b6b28c00b..92522f86c 100644 --- a/Eigen/src/Core/Redux.h +++ b/Eigen/src/Core/Redux.h @@ -54,16 +54,16 @@ private: public: enum { - Vectorization = int(MayLinearVectorize) ? int(LinearVectorization) - : int(MaySliceVectorize) ? int(SliceVectorization) - : int(NoVectorization) + Traversal = int(MayLinearVectorize) ? int(LinearVectorizedTraversal) + : int(MaySliceVectorize) ? int(SliceVectorizedTraversal) + : int(DefaultTraversal) }; private: enum { Cost = Derived::SizeAtCompileTime * Derived::CoeffReadCost + (Derived::SizeAtCompileTime-1) * NumTraits<typename Derived::Scalar>::AddCost, - UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Vectorization) == int(NoVectorization) ? 1 : int(PacketSize)) + UnrollingLimit = EIGEN_UNROLLING_LIMIT * (int(Traversal) == int(DefaultTraversal) ? 1 : int(PacketSize)) }; public: @@ -171,13 +171,13 @@ struct ei_redux_vec_unroller<Func, Derived, Start, 1> ***************************************************************************/ template<typename Func, typename Derived, - int Vectorization = ei_redux_traits<Func, Derived>::Vectorization, + int Traversal = ei_redux_traits<Func, Derived>::Traversal, int Unrolling = ei_redux_traits<Func, Derived>::Unrolling > struct ei_redux_impl; template<typename Func, typename Derived> -struct ei_redux_impl<Func, Derived, NoVectorization, NoUnrolling> +struct ei_redux_impl<Func, Derived, DefaultTraversal, NoUnrolling> { typedef typename Derived::Scalar Scalar; static Scalar run(const Derived& mat, const Func& func) @@ -195,12 +195,12 @@ struct ei_redux_impl<Func, Derived, NoVectorization, NoUnrolling> }; template<typename Func, typename Derived> -struct ei_redux_impl<Func,Derived, NoVectorization, CompleteUnrolling> +struct ei_redux_impl<Func,Derived, DefaultTraversal, CompleteUnrolling> : public ei_redux_novec_unroller<Func,Derived, 0, Derived::SizeAtCompileTime> {}; template<typename Func, typename Derived> -struct ei_redux_impl<Func, Derived, LinearVectorization, NoUnrolling> +struct ei_redux_impl<Func, Derived, LinearVectorizedTraversal, NoUnrolling> { typedef typename Derived::Scalar Scalar; typedef typename ei_packet_traits<Scalar>::type PacketScalar; @@ -209,10 +209,7 @@ struct ei_redux_impl<Func, Derived, LinearVectorization, NoUnrolling> { const int size = mat.size(); const int packetSize = ei_packet_traits<Scalar>::size; - const int alignedStart = (Derived::Flags & AlignedBit) - || !(Derived::Flags & DirectAccessBit) - ? 0 - : ei_alignmentOffset(&mat.const_cast_derived().coeffRef(0), size); + const int alignedStart = ei_alignmentOffset(mat,size); enum { alignment = (Derived::Flags & DirectAccessBit) || (Derived::Flags & AlignedBit) ? Aligned : Unaligned @@ -246,7 +243,7 @@ struct ei_redux_impl<Func, Derived, LinearVectorization, NoUnrolling> }; template<typename Func, typename Derived> -struct ei_redux_impl<Func, Derived, SliceVectorization, NoUnrolling> +struct ei_redux_impl<Func, Derived, SliceVectorizedTraversal, NoUnrolling> { typedef typename Derived::Scalar Scalar; typedef typename ei_packet_traits<Scalar>::type PacketScalar; @@ -277,7 +274,7 @@ struct ei_redux_impl<Func, Derived, SliceVectorization, NoUnrolling> else // too small to vectorize anything. // since this is dynamic-size hence inefficient anyway for such small sizes, don't try to optimize. { - res = ei_redux_impl<Func, Derived, NoVectorization, NoUnrolling>::run(mat, func); + res = ei_redux_impl<Func, Derived, DefaultTraversal, NoUnrolling>::run(mat, func); } return res; @@ -285,20 +282,20 @@ struct ei_redux_impl<Func, Derived, SliceVectorization, NoUnrolling> }; template<typename Func, typename Derived> -struct ei_redux_impl<Func, Derived, LinearVectorization, CompleteUnrolling> +struct ei_redux_impl<Func, Derived, LinearVectorizedTraversal, CompleteUnrolling> { typedef typename Derived::Scalar Scalar; typedef typename ei_packet_traits<Scalar>::type PacketScalar; enum { PacketSize = ei_packet_traits<Scalar>::size, Size = Derived::SizeAtCompileTime, - VectorizationSize = (Size / PacketSize) * PacketSize + VectorizedSize = (Size / PacketSize) * PacketSize }; EIGEN_STRONG_INLINE static Scalar run(const Derived& mat, const Func& func) { Scalar res = func.predux(ei_redux_vec_unroller<Func, Derived, 0, Size / PacketSize>::run(mat,func)); - if (VectorizationSize != Size) - res = func(res,ei_redux_novec_unroller<Func, Derived, VectorizationSize, Size-VectorizationSize>::run(mat,func)); + if (VectorizedSize != Size) + res = func(res,ei_redux_novec_unroller<Func, Derived, VectorizedSize, Size-VectorizedSize>::run(mat,func)); return res; } }; diff --git a/Eigen/src/Core/SelfAdjointView.h b/Eigen/src/Core/SelfAdjointView.h index 3e435853c..9ab8cb2c1 100644 --- a/Eigen/src/Core/SelfAdjointView.h +++ b/Eigen/src/Core/SelfAdjointView.h @@ -150,7 +150,6 @@ template<typename MatrixType, unsigned int UpLo> class SelfAdjointView const LDLT<PlainMatrixType> ldlt() const; protected: - const typename MatrixType::Nested m_matrix; }; diff --git a/Eigen/src/Core/Swap.h b/Eigen/src/Core/Swap.h index 2af78485b..010d8bb8b 100644 --- a/Eigen/src/Core/Swap.h +++ b/Eigen/src/Core/Swap.h @@ -106,9 +106,6 @@ template<typename ExpressionType> class SwapWrapper protected: ExpressionType& m_expression; - - private: - SwapWrapper& operator=(const SwapWrapper&); }; /** swaps *this with the expression \a other. diff --git a/Eigen/src/Core/Transpose.h b/Eigen/src/Core/Transpose.h index 513ce522a..63d77f134 100644 --- a/Eigen/src/Core/Transpose.h +++ b/Eigen/src/Core/Transpose.h @@ -215,7 +215,7 @@ template<typename Derived> inline const typename MatrixBase<Derived>::AdjointReturnType MatrixBase<Derived>::adjoint() const { - return this->transpose().nestByValue(); + return this->transpose(); } /*************************************************************************** @@ -297,13 +297,7 @@ inline void MatrixBase<Derived>::adjointInPlace() #ifndef EIGEN_NO_DEBUG -// The following is to detect aliasing problems in the following common cases: -// a = a.transpose() -// a = a.transpose() + X -// a = X + a.transpose() -// a = a.adjoint() -// a = a.adjoint() + X -// a = X + a.adjoint() +// The following is to detect aliasing problems in most common cases. template<typename T, int Access=ei_blas_traits<T>::ActualAccess> struct ei_extract_data_selector { @@ -323,63 +317,31 @@ template<typename T> typename T::Scalar* ei_extract_data(const T& m) return ei_extract_data_selector<T>::run(m); } -template<typename Derived> -template<typename OtherDerived> -Derived& DenseBase<Derived>::lazyAssign(const Transpose<OtherDerived>& other) -{ - ei_assert(ei_extract_data(other) != ei_extract_data(derived()) - && "aliasing detected during tranposition, please use transposeInPlace()"); - return lazyAssign(static_cast<const DenseBase<Transpose<OtherDerived> >& >(other)); -} - -template<typename Derived> -template<typename DerivedA, typename DerivedB> -Derived& DenseBase<Derived>:: -lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,Transpose<DerivedA>,DerivedB>& other) -{ - ei_assert(ei_extract_data(derived()) != ei_extract_data(other.lhs()) - && "aliasing detected during tranposition, please evaluate your expression"); - return lazyAssign(static_cast<const DenseBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,Transpose<DerivedA>,DerivedB> >& >(other)); -} - -template<typename Derived> -template<typename DerivedA, typename DerivedB> -Derived& DenseBase<Derived>:: -lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,Transpose<DerivedB> >& other) -{ - ei_assert(ei_extract_data(derived()) != ei_extract_data(other.rhs()) - && "aliasing detected during tranposition, please evaluate your expression"); - return lazyAssign(static_cast<const DenseBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,Transpose<DerivedB> > >& >(other)); -} - -template<typename Derived> -template<typename OtherDerived> Derived& -DenseBase<Derived>:: -lazyAssign(const CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<OtherDerived> > >& other) +template<typename Scalar, bool DestIsTranposed, typename OtherDerived> +struct ei_check_transpose_aliasing_selector { - ei_assert(ei_extract_data(other) != ei_extract_data(derived()) - && "aliasing detected during tranposition, please use adjointInPlace()"); - return lazyAssign(static_cast<const DenseBase<CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<OtherDerived> > > >& >(other)); -} + static bool run(const Scalar* dest, const OtherDerived& src) + { + return (ei_blas_traits<OtherDerived>::IsTransposed != DestIsTranposed) && (dest==(Scalar*)ei_extract_data(src)); + } +}; -template<typename Derived> -template<typename DerivedA, typename DerivedB> -Derived& DenseBase<Derived>:: -lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedA> > >,DerivedB>& other) +template<typename Scalar, bool DestIsTranposed, typename BinOp, typename DerivedA, typename DerivedB> +struct ei_check_transpose_aliasing_selector<Scalar,DestIsTranposed,CwiseBinaryOp<BinOp,DerivedA,DerivedB> > { - ei_assert(ei_extract_data(derived()) != ei_extract_data(other.lhs()) - && "aliasing detected during tranposition, please evaluate your expression"); - return lazyAssign(static_cast<const DenseBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedA> > >,DerivedB> >& >(other)); -} + static bool run(const Scalar* dest, const CwiseBinaryOp<BinOp,DerivedA,DerivedB>& src) + { + return ((ei_blas_traits<DerivedA>::IsTransposed != DestIsTranposed) && dest==(Scalar*)ei_extract_data(src.lhs())) + || ((ei_blas_traits<DerivedB>::IsTransposed != DestIsTranposed) && dest==(Scalar*)ei_extract_data(src.rhs())); + } +}; template<typename Derived> -template<typename DerivedA, typename DerivedB> -Derived& DenseBase<Derived>:: -lazyAssign(const CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedB> > > >& other) +template<typename OtherDerived> +void DenseBase<Derived>::checkTransposeAliasing(const OtherDerived& other) const { - ei_assert(ei_extract_data(derived()) != ei_extract_data(other.rhs()) - && "aliasing detected during tranposition, please evaluate your expression"); - return lazyAssign(static_cast<const DenseBase<CwiseBinaryOp<ei_scalar_sum_op<Scalar>,DerivedA,CwiseUnaryOp<ei_scalar_conjugate_op<Scalar>, NestByValue<Eigen::Transpose<DerivedB> > > > >& >(other)); + ei_assert((!ei_check_transpose_aliasing_selector<Scalar,ei_blas_traits<Derived>::IsTransposed,OtherDerived>::run(ei_extract_data(derived()), other)) + && "aliasing detected during tranposition, use transposeInPlace() or evaluate the rhs into a temporary using .eval()"); } #endif diff --git a/Eigen/src/Core/TriangularMatrix.h b/Eigen/src/Core/TriangularMatrix.h index e60d57e70..aaf781d1f 100644 --- a/Eigen/src/Core/TriangularMatrix.h +++ b/Eigen/src/Core/TriangularMatrix.h @@ -26,22 +26,11 @@ #ifndef EIGEN_TRIANGULARMATRIX_H #define EIGEN_TRIANGULARMATRIX_H -/** \nonstableyet - * \class TriangularBase - * - * \brief Expression of a triangular matrix extracted from a given matrix - * - * \param MatrixType the type of the object in which we are taking the triangular part - * \param Mode the kind of triangular matrix expression to construct. Can be UpperTriangular, - * LowerTriangular, UpperSelfadjoint, or LowerSelfadjoint. This is in fact a bit field; - * it must have either UpperBit or LowerBit, and additionnaly it may have either - * TraingularBit or SelfadjointBit. +/** \internal * - * This class represents an expression of the upper or lower triangular part of - * a square matrix, possibly with a further assumption on the diagonal. It is the return type - * of MatrixBase::part() and most of the time this is the only way it is used. + * \class TriangularBase * - * \sa MatrixBase::part() + * \brief Base class for triangular part in a matrix */ template<typename Derived> class TriangularBase : public AnyMatrixBase<Derived> { @@ -99,11 +88,11 @@ template<typename Derived> class TriangularBase : public AnyMatrixBase<Derived> void check_coordinates(int row, int col) { - ei_assert(col>0 && col<cols() && row>0 && row<rows()); + ei_assert(col>=0 && col<cols() && row>=0 && row<rows()); ei_assert( (Mode==UpperTriangular && col>=row) || (Mode==LowerTriangular && col<=row) - || (Mode==StrictlyUpperTriangular && col>row) - || (Mode==StrictlyLowerTriangular && col<row)); + || ((Mode==StrictlyUpperTriangular || Mode==UnitUpperTriangular) && col>row) + || ((Mode==StrictlyLowerTriangular || Mode==UnitLowerTriangular) && col<row)); } void check_coordinates_internal(int row, int col) @@ -115,19 +104,21 @@ template<typename Derived> class TriangularBase : public AnyMatrixBase<Derived> }; - /** \class TriangularView - * \nonstableyet * - * \brief Expression of a triangular part of a dense matrix + * \brief Base class for triangular part in a matrix * - * \param MatrixType the type of the dense matrix storing the coefficients + * \param MatrixType the type of the object in which we are taking the triangular part + * \param Mode the kind of triangular matrix expression to construct. Can be UpperTriangular, + * LowerTriangular, UpperSelfadjoint, or LowerSelfadjoint. This is in fact a bit field; + * it must have either UpperBit or LowerBit, and additionnaly it may have either + * TraingularBit or SelfadjointBit. * - * This class is an expression of a triangular part of a matrix with given dense - * storage of the coefficients. It is the return type of MatrixBase::triangularPart() - * and most of the time this is the only way that it is used. + * This class represents a triangular part of a matrix, not necessarily square. Strictly speaking, for rectangular + * matrices one should speak ok "trapezoid" parts. This class is the return type + * of MatrixBase::triangularView() and most of the time this is the only way it is used. * - * \sa class TriangularBase, MatrixBase::triangularPart(), class DiagonalWrapper + * \sa MatrixBase::triangularView() */ template<typename MatrixType, unsigned int _Mode> struct ei_traits<TriangularView<MatrixType, _Mode> > : ei_traits<MatrixType> @@ -155,7 +146,7 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView typedef TriangularBase<TriangularView> Base; typedef typename ei_traits<TriangularView>::Scalar Scalar; typedef _MatrixType MatrixType; - typedef typename MatrixType::PlainMatrixType PlainMatrixType; + typedef typename MatrixType::PlainMatrixType DenseMatrixType; typedef typename MatrixType::Nested MatrixTypeNested; typedef typename ei_cleantype<MatrixTypeNested>::type _MatrixTypeNested; @@ -231,23 +222,23 @@ template<typename _MatrixType, unsigned int _Mode> class TriangularView /** \sa MatrixBase::adjoint() */ - inline TriangularView<NestByValue<typename MatrixType::AdjointReturnType>,TransposeMode> adjoint() - { return m_matrix.adjoint().nestByValue(); } + inline TriangularView<typename MatrixType::AdjointReturnType,TransposeMode> adjoint() + { return m_matrix.adjoint(); } /** \sa MatrixBase::adjoint() const */ - inline const TriangularView<NestByValue<typename MatrixType::AdjointReturnType>,TransposeMode> adjoint() const - { return m_matrix.adjoint().nestByValue(); } + inline const TriangularView<typename MatrixType::AdjointReturnType,TransposeMode> adjoint() const + { return m_matrix.adjoint(); } /** \sa MatrixBase::transpose() */ - inline TriangularView<NestByValue<Transpose<MatrixType> >,TransposeMode> transpose() - { return m_matrix.transpose().nestByValue(); } + inline TriangularView<Transpose<MatrixType>,TransposeMode> transpose() + { return m_matrix.transpose(); } /** \sa MatrixBase::transpose() const */ - inline const TriangularView<NestByValue<Transpose<MatrixType> >,TransposeMode> transpose() const - { return m_matrix.transpose().nestByValue(); } + inline const TriangularView<Transpose<MatrixType>,TransposeMode> transpose() const + { return m_matrix.transpose(); } - PlainMatrixType toDense() const + DenseMatrixType toDenseMatrix() const { - PlainMatrixType res(rows(), cols()); - res = *this; + DenseMatrixType res(rows(), cols()); + evalToLazy(res); return res; } @@ -351,20 +342,7 @@ struct ei_triangular_assignment_selector } } }; -template<typename Derived1, typename Derived2, unsigned int Mode, bool ClearOpposite> -struct ei_triangular_assignment_selector<Derived1, Derived2, Mode, 1, ClearOpposite> -{ - inline static void run(Derived1 &dst, const Derived2 &src) - { - if(Mode&UnitDiagBit) - { - if(ClearOpposite) - dst.coeffRef(0, 0) = 1; - } - else if(!(Mode & ZeroDiagBit)) - dst.copyCoeff(0, 0, src); - } -}; + // prevent buggy user code from causing an infinite recursion template<typename Derived1, typename Derived2, unsigned int Mode, bool ClearOpposite> struct ei_triangular_assignment_selector<Derived1, Derived2, Mode, 0, ClearOpposite> @@ -379,14 +357,16 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, UpperTriangular, Dy { for(int j = 0; j < dst.cols(); ++j) { - for(int i = 0; i <= j; ++i) + int maxi = std::min(j, dst.rows()-1); + for(int i = 0; i <= maxi; ++i) dst.copyCoeff(i, j, src); if (ClearOpposite) - for(int i = j+1; i < dst.rows(); ++i) + for(int i = maxi+1; i < dst.rows(); ++i) dst.coeffRef(i, j) = 0; } } }; + template<typename Derived1, typename Derived2, bool ClearOpposite> struct ei_triangular_assignment_selector<Derived1, Derived2, LowerTriangular, Dynamic, ClearOpposite> { @@ -396,8 +376,9 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, LowerTriangular, Dy { for(int i = j; i < dst.rows(); ++i) dst.copyCoeff(i, j, src); + int maxi = std::min(j, dst.rows()); if (ClearOpposite) - for(int i = 0; i < j; ++i) + for(int i = 0; i < maxi; ++i) dst.coeffRef(i, j) = 0; } } @@ -410,14 +391,16 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, StrictlyUpperTriang { for(int j = 0; j < dst.cols(); ++j) { - for(int i = 0; i < j; ++i) + int maxi = std::min(j, dst.rows()); + for(int i = 0; i < maxi; ++i) dst.copyCoeff(i, j, src); if (ClearOpposite) - for(int i = j; i < dst.rows(); ++i) + for(int i = maxi; i < dst.rows(); ++i) dst.coeffRef(i, j) = 0; } } }; + template<typename Derived1, typename Derived2, bool ClearOpposite> struct ei_triangular_assignment_selector<Derived1, Derived2, StrictlyLowerTriangular, Dynamic, ClearOpposite> { @@ -427,8 +410,9 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, StrictlyLowerTriang { for(int i = j+1; i < dst.rows(); ++i) dst.copyCoeff(i, j, src); + int maxi = std::min(j, dst.rows()-1); if (ClearOpposite) - for(int i = 0; i <= j; ++i) + for(int i = 0; i <= maxi; ++i) dst.coeffRef(i, j) = 0; } } @@ -441,15 +425,16 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, UnitUpperTriangular { for(int j = 0; j < dst.cols(); ++j) { - for(int i = 0; i < j; ++i) + int maxi = std::min(j, dst.rows()); + for(int i = 0; i < maxi; ++i) dst.copyCoeff(i, j, src); if (ClearOpposite) { - for(int i = j+1; i < dst.rows(); ++i) + for(int i = maxi+1; i < dst.rows(); ++i) dst.coeffRef(i, j) = 0; - dst.coeffRef(j, j) = 1; } } + dst.diagonal().setOnes(); } }; template<typename Derived1, typename Derived2, bool ClearOpposite> @@ -459,15 +444,16 @@ struct ei_triangular_assignment_selector<Derived1, Derived2, UnitLowerTriangular { for(int j = 0; j < dst.cols(); ++j) { - for(int i = j+1; i < dst.rows(); ++i) + int maxi = std::min(j, dst.rows()); + for(int i = maxi+1; i < dst.rows(); ++i) dst.copyCoeff(i, j, src); if (ClearOpposite) { - for(int i = 0; i < j; ++i) + for(int i = 0; i < maxi; ++i) dst.coeffRef(i, j) = 0; - dst.coeffRef(j, j) = 1; } } + dst.diagonal().setOnes(); } }; @@ -514,7 +500,7 @@ TriangularView<MatrixType, Mode>::operator=(const TriangularBase<OtherDerived>& ei_assert(Mode == OtherDerived::Mode); if(ei_traits<OtherDerived>::Flags & EvalBeforeAssigningBit) { - typename OtherDerived::PlainMatrixType other_evaluated(other.rows(), other.cols()); + typename OtherDerived::DenseMatrixType other_evaluated(other.rows(), other.cols()); other_evaluated.template triangularView<Mode>().lazyAssign(other.derived()); lazyAssign(other_evaluated); } @@ -633,17 +619,20 @@ const TriangularView<Derived, Mode> MatrixBase<Derived>::triangularView() const template<typename Derived> bool MatrixBase<Derived>::isUpperTriangular(RealScalar prec) const { - if(cols() != rows()) return false; RealScalar maxAbsOnUpperTriangularPart = static_cast<RealScalar>(-1); for(int j = 0; j < cols(); ++j) - for(int i = 0; i <= j; ++i) + { + int maxi = std::min(j, rows()-1); + for(int i = 0; i <= maxi; ++i) { RealScalar absValue = ei_abs(coeff(i,j)); if(absValue > maxAbsOnUpperTriangularPart) maxAbsOnUpperTriangularPart = absValue; } - for(int j = 0; j < cols()-1; ++j) + } + RealScalar threshold = maxAbsOnUpperTriangularPart * prec; + for(int j = 0; j < cols(); ++j) for(int i = j+1; i < rows(); ++i) - if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnUpperTriangularPart, prec)) return false; + if(ei_abs(coeff(i, j)) > threshold) return false; return true; } @@ -655,7 +644,6 @@ bool MatrixBase<Derived>::isUpperTriangular(RealScalar prec) const template<typename Derived> bool MatrixBase<Derived>::isLowerTriangular(RealScalar prec) const { - if(cols() != rows()) return false; RealScalar maxAbsOnLowerTriangularPart = static_cast<RealScalar>(-1); for(int j = 0; j < cols(); ++j) for(int i = j; i < rows(); ++i) @@ -663,9 +651,13 @@ bool MatrixBase<Derived>::isLowerTriangular(RealScalar prec) const RealScalar absValue = ei_abs(coeff(i,j)); if(absValue > maxAbsOnLowerTriangularPart) maxAbsOnLowerTriangularPart = absValue; } + RealScalar threshold = maxAbsOnLowerTriangularPart * prec; for(int j = 1; j < cols(); ++j) - for(int i = 0; i < j; ++i) - if(!ei_isMuchSmallerThan(coeff(i, j), maxAbsOnLowerTriangularPart, prec)) return false; + { + int maxi = std::min(j, rows()-1); + for(int i = 0; i < maxi; ++i) + if(ei_abs(coeff(i, j)) > threshold) return false; + } return true; } diff --git a/Eigen/src/Core/arch/SSE/MathFunctions.h b/Eigen/src/Core/arch/SSE/MathFunctions.h index 8399aac30..3c0020248 100644 --- a/Eigen/src/Core/arch/SSE/MathFunctions.h +++ b/Eigen/src/Core/arch/SSE/MathFunctions.h @@ -365,6 +365,8 @@ static EIGEN_DONT_INLINE EIGEN_UNUSED Packet4f ei_pcos(Packet4f x) return _mm_xor_ps(y, sign_bit); } +// This is Quake3's fast inverse square root. +// For detail see here: http://www.beyond3d.com/content/articles/8/ static EIGEN_UNUSED Packet4f ei_psqrt(Packet4f _x) { Packet4f half = ei_pmul(_x, ei_pset1(.5f)); diff --git a/Eigen/src/Core/arch/SSE/PacketMath.h b/Eigen/src/Core/arch/SSE/PacketMath.h index 29c89c310..a633c7b7c 100644 --- a/Eigen/src/Core/arch/SSE/PacketMath.h +++ b/Eigen/src/Core/arch/SSE/PacketMath.h @@ -58,8 +58,8 @@ template<> struct ei_packet_traits<float> : ei_default_packet_traits { typedef Packet4f type; enum {size=4}; enum { - HasSin = 1, - HasCos = 1, + HasSin = EIGEN_FAST_MATH, + HasCos = EIGEN_FAST_MATH, HasLog = 1, HasExp = 1, HasSqrt = 1 @@ -118,6 +118,9 @@ template<> EIGEN_STRONG_INLINE Packet4f ei_pmul<Packet4f>(const Packet4f& a, con template<> EIGEN_STRONG_INLINE Packet2d ei_pmul<Packet2d>(const Packet2d& a, const Packet2d& b) { return _mm_mul_pd(a,b); } template<> EIGEN_STRONG_INLINE Packet4i ei_pmul<Packet4i>(const Packet4i& a, const Packet4i& b) { +#ifdef __SSE4_1__ + return _mm_mullo_epi32(a,b); +#else // this version is slightly faster than 4 scalar products return ei_vec4i_swizzle1( ei_vec4i_swizzle2( @@ -126,6 +129,7 @@ template<> EIGEN_STRONG_INLINE Packet4i ei_pmul<Packet4i>(const Packet4i& a, con ei_vec4i_swizzle1(b,1,0,3,2)), 0,2,0,2), 0,2,1,3); +#endif } template<> EIGEN_STRONG_INLINE Packet4f ei_pdiv<Packet4f>(const Packet4f& a, const Packet4f& b) { return _mm_div_ps(a,b); } diff --git a/Eigen/src/Core/products/GeneralUnrolled.h b/Eigen/src/Core/products/GeneralUnrolled.h index 7e2eebf08..f04c27a95 100644 --- a/Eigen/src/Core/products/GeneralUnrolled.h +++ b/Eigen/src/Core/products/GeneralUnrolled.h @@ -36,7 +36,7 @@ * Note that here the inner-loops should always be unrolled. */ -template<int VectorizationMode, int Index, typename Lhs, typename Rhs, typename RetScalar> +template<int Traversal, int Index, typename Lhs, typename Rhs, typename RetScalar> struct ei_product_coeff_impl; template<int StorageOrder, int Index, typename Lhs, typename Rhs, typename PacketScalar, int LoadMode> @@ -118,7 +118,7 @@ template<typename LhsNested, typename RhsNested> class GeneralProduct<LhsNested, CanVectorizeInner = ei_traits<GeneralProduct>::CanVectorizeInner }; - typedef ei_product_coeff_impl<CanVectorizeInner ? InnerVectorization : NoVectorization, + typedef ei_product_coeff_impl<CanVectorizeInner ? InnerVectorizedTraversal : DefaultTraversal, Unroll ? InnerSize-1 : Dynamic, _LhsNested, _RhsNested, Scalar> ScalarCoeffImpl; @@ -185,17 +185,17 @@ template<typename LhsNested, typename RhsNested> class GeneralProduct<LhsNested, **************************************/ template<int Index, typename Lhs, typename Rhs, typename RetScalar> -struct ei_product_coeff_impl<NoVectorization, Index, Lhs, Rhs, RetScalar> +struct ei_product_coeff_impl<DefaultTraversal, Index, Lhs, Rhs, RetScalar> { EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) { - ei_product_coeff_impl<NoVectorization, Index-1, Lhs, Rhs, RetScalar>::run(row, col, lhs, rhs, res); + ei_product_coeff_impl<DefaultTraversal, Index-1, Lhs, Rhs, RetScalar>::run(row, col, lhs, rhs, res); res += lhs.coeff(row, Index) * rhs.coeff(Index, col); } }; template<typename Lhs, typename Rhs, typename RetScalar> -struct ei_product_coeff_impl<NoVectorization, 0, Lhs, Rhs, RetScalar> +struct ei_product_coeff_impl<DefaultTraversal, 0, Lhs, Rhs, RetScalar> { EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar &res) { @@ -204,7 +204,7 @@ struct ei_product_coeff_impl<NoVectorization, 0, Lhs, Rhs, RetScalar> }; template<typename Lhs, typename Rhs, typename RetScalar> -struct ei_product_coeff_impl<NoVectorization, Dynamic, Lhs, Rhs, RetScalar> +struct ei_product_coeff_impl<DefaultTraversal, Dynamic, Lhs, Rhs, RetScalar> { EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, RetScalar& res) { @@ -217,7 +217,7 @@ struct ei_product_coeff_impl<NoVectorization, Dynamic, Lhs, Rhs, RetScalar> // prevent buggy user code from causing an infinite recursion template<typename Lhs, typename Rhs, typename RetScalar> -struct ei_product_coeff_impl<NoVectorization, -1, Lhs, Rhs, RetScalar> +struct ei_product_coeff_impl<DefaultTraversal, -1, Lhs, Rhs, RetScalar> { EIGEN_STRONG_INLINE static void run(int, int, const Lhs&, const Rhs&, RetScalar&) {} }; @@ -247,7 +247,7 @@ struct ei_product_coeff_vectorized_unroller<0, Lhs, Rhs, PacketScalar> }; template<int Index, typename Lhs, typename Rhs, typename RetScalar> -struct ei_product_coeff_impl<InnerVectorization, Index, Lhs, Rhs, RetScalar> +struct ei_product_coeff_impl<InnerVectorizedTraversal, Index, Lhs, Rhs, RetScalar> { typedef typename Lhs::PacketScalar PacketScalar; enum { PacketSize = ei_packet_traits<typename Lhs::Scalar>::size }; @@ -255,7 +255,7 @@ struct ei_product_coeff_impl<InnerVectorization, Index, Lhs, Rhs, RetScalar> { PacketScalar pres; ei_product_coeff_vectorized_unroller<Index+1-PacketSize, Lhs, Rhs, PacketScalar>::run(row, col, lhs, rhs, pres); - ei_product_coeff_impl<NoVectorization,Index,Lhs,Rhs,RetScalar>::run(row, col, lhs, rhs, res); + ei_product_coeff_impl<DefaultTraversal,Index,Lhs,Rhs,RetScalar>::run(row, col, lhs, rhs, res); res = ei_predux(pres); } }; @@ -268,7 +268,7 @@ struct ei_product_coeff_vectorized_dyn_selector res = ei_dot_impl< Block<Lhs, 1, ei_traits<Lhs>::ColsAtCompileTime>, Block<Rhs, ei_traits<Rhs>::RowsAtCompileTime, 1>, - LinearVectorization, NoUnrolling>::run(lhs.row(row), rhs.col(col)); + LinearVectorizedTraversal, NoUnrolling>::run(lhs.row(row), rhs.col(col)); } }; @@ -282,7 +282,7 @@ struct ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,RhsCols> res = ei_dot_impl< Lhs, Block<Rhs, ei_traits<Rhs>::RowsAtCompileTime, 1>, - LinearVectorization, NoUnrolling>::run(lhs, rhs.col(col)); + LinearVectorizedTraversal, NoUnrolling>::run(lhs, rhs.col(col)); } }; @@ -294,7 +294,7 @@ struct ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs,LhsRows,1> res = ei_dot_impl< Block<Lhs, 1, ei_traits<Lhs>::ColsAtCompileTime>, Rhs, - LinearVectorization, NoUnrolling>::run(lhs.row(row), rhs); + LinearVectorizedTraversal, NoUnrolling>::run(lhs.row(row), rhs); } }; @@ -306,12 +306,12 @@ struct ei_product_coeff_vectorized_dyn_selector<Lhs,Rhs,1,1> res = ei_dot_impl< Lhs, Rhs, - LinearVectorization, NoUnrolling>::run(lhs, rhs); + LinearVectorizedTraversal, NoUnrolling>::run(lhs, rhs); } }; template<typename Lhs, typename Rhs, typename RetScalar> -struct ei_product_coeff_impl<InnerVectorization, Dynamic, Lhs, Rhs, RetScalar> +struct ei_product_coeff_impl<InnerVectorizedTraversal, Dynamic, Lhs, Rhs, RetScalar> { EIGEN_STRONG_INLINE static void run(int row, int col, const Lhs& lhs, const Rhs& rhs, typename Lhs::Scalar &res) { diff --git a/Eigen/src/Core/util/BlasUtil.h b/Eigen/src/Core/util/BlasUtil.h index 94154108c..fa21ceebb 100644 --- a/Eigen/src/Core/util/BlasUtil.h +++ b/Eigen/src/Core/util/BlasUtil.h @@ -160,6 +160,7 @@ template<typename XprType> struct ei_blas_traits typedef XprType _ExtractType; enum { IsComplex = NumTraits<Scalar>::IsComplex, + IsTransposed = false, NeedToConjugate = false, ActualAccess = int(ei_traits<XprType>::Flags)&DirectAccessBit ? HasDirectAccess : NoDirectAccess }; @@ -214,20 +215,6 @@ struct ei_blas_traits<CwiseUnaryOp<ei_scalar_opposite_op<Scalar>, NestedXpr> > { return - Base::extractScalarFactor(x._expression()); } }; -// pop NestByValue -template<typename NestedXpr> -struct ei_blas_traits<NestByValue<NestedXpr> > - : ei_blas_traits<NestedXpr> -{ - typedef typename NestedXpr::Scalar Scalar; - typedef ei_blas_traits<NestedXpr> Base; - typedef NestByValue<NestedXpr> XprType; - typedef typename Base::ExtractType ExtractType; - static inline ExtractType extract(const XprType& x) { return Base::extract(static_cast<const NestedXpr&>(x)); } - static inline Scalar extractScalarFactor(const XprType& x) - { return Base::extractScalarFactor(static_cast<const NestedXpr&>(x)); } -}; - // pop/push transpose template<typename NestedXpr> struct ei_blas_traits<Transpose<NestedXpr> > @@ -241,6 +228,9 @@ struct ei_blas_traits<Transpose<NestedXpr> > ExtractType, typename ExtractType::PlainMatrixType >::ret DirectLinearAccessType; + enum { + IsTransposed = Base::IsTransposed ? 0 : 1 + }; static inline const ExtractType extract(const XprType& x) { return Base::extract(x._expression()); } static inline Scalar extractScalarFactor(const XprType& x) { return Base::extractScalarFactor(x._expression()); } }; diff --git a/Eigen/src/Core/util/Constants.h b/Eigen/src/Core/util/Constants.h index beb19cdaa..8483772df 100644 --- a/Eigen/src/Core/util/Constants.h +++ b/Eigen/src/Core/util/Constants.h @@ -195,16 +195,19 @@ enum DirectionType { Vertical, Horizontal, BothDirections }; enum ProductEvaluationMode { NormalProduct, CacheFriendlyProduct }; enum { + /** \internal Default traversal, no vectorization, no index-based access */ + DefaultTraversal, + /** \internal No vectorization, use index-based access to have only one for loop instead of 2 nested loops */ + LinearTraversal, /** \internal Equivalent to a slice vectorization for fixed-size matrices having good alignment * and good size */ - InnerVectorization, + InnerVectorizedTraversal, /** \internal Vectorization path using a single loop plus scalar loops for the * unaligned boundaries */ - LinearVectorization, + LinearVectorizedTraversal, /** \internal Generic vectorization path using one vectorized loop per row/column with some * scalar loops to handle the unaligned boundaries */ - SliceVectorization, - NoVectorization + SliceVectorizedTraversal }; enum { @@ -218,8 +221,7 @@ enum { RowMajor = 0x1, // it is only a coincidence that this is equal to RowMajorBit -- don't rely on that /** \internal Align the matrix itself if it is vectorizable fixed-size */ AutoAlign = 0, - /** \internal Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be - requested to be aligned) */ + /** \internal Don't require alignment for the matrix itself (the array of coefficients, if dynamically allocated, may still be requested to be aligned) */ // FIXME --- clarify the situation DontAlign = 0x2 }; @@ -267,19 +269,23 @@ enum TransformTraits { Projective = 0x20 }; -const int EiArch_Generic = 0x0; -const int EiArch_SSE = 0x1; -const int EiArch_AltiVec = 0x2; - -enum DenseStorageMatrix {}; -enum DenseStorageArray {}; - +namespace Architecture +{ + enum Type { + Generic = 0x0, + SSE = 0x1, + AltiVec = 0x2, #if defined EIGEN_VECTORIZE_SSE - const int EiArch = EiArch_SSE; + Target = SSE #elif defined EIGEN_VECTORIZE_ALTIVEC - const int EiArch = EiArch_AltiVec; + Target = AltiVec #else - const int EiArch = EiArch_Generic; + Target = Generic #endif + }; +} + +enum DenseStorageMatrix {}; +enum DenseStorageArray {}; #endif // EIGEN_CONSTANTS_H diff --git a/Eigen/src/Core/util/DisableMSVCWarnings.h b/Eigen/src/Core/util/DisableMSVCWarnings.h index c08d0389f..dcc71143d 100644 --- a/Eigen/src/Core/util/DisableMSVCWarnings.h +++ b/Eigen/src/Core/util/DisableMSVCWarnings.h @@ -1,6 +1,9 @@ #ifdef _MSC_VER - // 4273 - QtAlignedMalloc, inconsistent dll linkage + // 4273 - QtAlignedMalloc, inconsistent DLL linkage + // 4100 - unreferenced formal parameter (occurred e.g. in aligned_allocator::destroy(pointer p)) + // 4101 - unreferenced local variable + // 4512 - assignment operator could not be generated #pragma warning( push ) - #pragma warning( disable : 4181 4244 4127 4211 4273 4522 4717 ) + #pragma warning( disable : 4100 4101 4181 4244 4127 4211 4273 4512 4522 4717 ) #endif diff --git a/Eigen/src/Core/util/Macros.h b/Eigen/src/Core/util/Macros.h index b3a1955fb..4ea5013f7 100644 --- a/Eigen/src/Core/util/Macros.h +++ b/Eigen/src/Core/util/Macros.h @@ -29,8 +29,8 @@ #undef minor #define EIGEN_WORLD_VERSION 2 -#define EIGEN_MAJOR_VERSION 90 -#define EIGEN_MINOR_VERSION 1 +#define EIGEN_MAJOR_VERSION 91 +#define EIGEN_MINOR_VERSION 0 #define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \ (EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \ diff --git a/Eigen/src/Core/util/Memory.h b/Eigen/src/Core/util/Memory.h index bc5235582..524bec2fc 100644 --- a/Eigen/src/Core/util/Memory.h +++ b/Eigen/src/Core/util/Memory.h @@ -209,16 +209,20 @@ template<typename T, bool Align> inline void ei_conditional_aligned_delete(T *pt ei_conditional_aligned_free<Align>(ptr); } -/** \internal \returns the number of elements which have to be skipped such that data are 16 bytes aligned */ -template<typename Scalar> -inline static int ei_alignmentOffset(const Scalar* ptr, int maxOffset) +/** \internal \returns the number of elements which have to be skipped to + * find the first 16-byte aligned element + * + * There is also the variant ei_alignmentOffset(const MatrixBase&, Integer) defined in Coeffs.h. + */ +template<typename Scalar, typename Integer> +inline static Integer ei_alignmentOffset(const Scalar* ptr, Integer maxOffset) { typedef typename ei_packet_traits<Scalar>::type Packet; - const int PacketSize = ei_packet_traits<Scalar>::size; - const int PacketAlignedMask = PacketSize-1; + const Integer PacketSize = ei_packet_traits<Scalar>::size; + const Integer PacketAlignedMask = PacketSize-1; const bool Vectorized = PacketSize>1; return Vectorized - ? std::min<int>( (PacketSize - (int((size_t(ptr)/sizeof(Scalar))) & PacketAlignedMask)) + ? std::min<Integer>( (PacketSize - (Integer((size_t(ptr)/sizeof(Scalar))) & PacketAlignedMask)) & PacketAlignedMask, maxOffset) : 0; } diff --git a/Eigen/src/Core/util/XprHelper.h b/Eigen/src/Core/util/XprHelper.h index 6d6540acc..6d4a5c7bc 100644 --- a/Eigen/src/Core/util/XprHelper.h +++ b/Eigen/src/Core/util/XprHelper.h @@ -28,10 +28,11 @@ // just a workaround because GCC seems to not really like empty structs #ifdef __GNUG__ - struct ei_empty_struct{char _ei_dummy_;}; - #define EIGEN_EMPTY_STRUCT : Eigen::ei_empty_struct + #define EIGEN_EMPTY_STRUCT_CTOR(X) \ + EIGEN_STRONG_INLINE X() {} \ + EIGEN_STRONG_INLINE X(const X&) {} #else - #define EIGEN_EMPTY_STRUCT + #define EIGEN_EMPTY_STRUCT_CTOR(X) #endif //classes inheriting ei_no_assignment_operator don't generate a default operator=. @@ -45,10 +46,10 @@ class ei_no_assignment_operator * can be accessed using value() and setValue(). * Otherwise, this class is an empty structure and value() just returns the template parameter Value. */ -template<int Value> class ei_int_if_dynamic EIGEN_EMPTY_STRUCT +template<int Value> class ei_int_if_dynamic { public: - ei_int_if_dynamic() {} + EIGEN_EMPTY_STRUCT_CTOR(ei_int_if_dynamic) explicit ei_int_if_dynamic(int) {} static int value() { return Value; } void setValue(int) {} @@ -214,8 +215,35 @@ template<typename T> struct ei_plain_matrix_type_row_major > type; }; +// we should be able to get rid of this one too template<typename T> struct ei_must_nest_by_value { enum { ret = false }; }; -template<typename T> struct ei_must_nest_by_value<NestByValue<T> > { enum { ret = true }; }; + +/** +* The reference selector for template expressions. The idea is that we don't +* need to use references for expressions since they are light weight proxy +* objects which should generate no copying overhead. +**/ +template <typename T> +struct ei_ref_selector +{ + typedef T type; +}; + +/** +* Matrices on the other hand side should only be copied, when it is sure +* we gain by copying (see arithmetic cost check and eval before nesting flag). +* Note: This is an optimization measure that comprises potential (though little) +* to create erroneous code. Any user, utilizing ei_nested outside of +* Eigen needs to take care that no references to temporaries are +* stored or that this potential danger is at least communicated +* to the user. +**/ +template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols> +struct ei_ref_selector< Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > +{ + typedef Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> MatrixType; + typedef MatrixType const& type; +}; /** \internal Determines how a given expression should be nested into another one. * For example, when you do a * (b+c), Eigen will determine how the expression b+c should be @@ -241,15 +269,12 @@ template<typename T, int n=1, typename PlainMatrixType = typename ei_eval<T>::ty CostEval = (n+1) * int(NumTraits<typename ei_traits<T>::Scalar>::ReadCost), CostNoEval = (n-1) * int(ei_traits<T>::CoeffReadCost) }; + typedef typename ei_meta_if< - ei_must_nest_by_value<T>::ret, - T, - typename ei_meta_if< - (int(ei_traits<T>::Flags) & EvalBeforeNestingBit) - || ( int(CostEval) <= int(CostNoEval) ), + ( int(ei_traits<T>::Flags) & EvalBeforeNestingBit ) || + ( int(CostEval) <= int(CostNoEval) ), PlainMatrixType, - const T& - >::ret + typename ei_ref_selector<T>::type >::ret type; }; @@ -302,7 +327,7 @@ template<typename ExpressionType> struct HNormalizedReturnType { ei_traits<ExpressionType>::ColsAtCompileTime==1 ? SizeMinusOne : 1, ei_traits<ExpressionType>::ColsAtCompileTime==1 ? 1 : SizeMinusOne> StartMinusOne; typedef CwiseUnaryOp<ei_scalar_quotient1_op<typename ei_traits<ExpressionType>::Scalar>, - NestByValue<StartMinusOne> > Type; + StartMinusOne > Type; }; template<typename XprType, typename CastType> struct ei_cast_return_type |