mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
merge with default branch
This commit is contained in:
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
@@ -429,6 +484,9 @@ EIGEN_STRONG_INLINE Derived& DenseBase<Derived>
|
||||
ei_assign_impl<Derived, OtherDerived>::run(derived(),other.derived());
|
||||
#ifdef EIGEN_DEBUG_ASSIGN
|
||||
ei_assign_traits<Derived, OtherDerived>::debug();
|
||||
#endif
|
||||
#ifndef EIGEN_NO_DEBUG
|
||||
checkTransposeAliasing(other.derived());
|
||||
#endif
|
||||
return derived();
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
};
|
||||
};
|
||||
|
||||
@@ -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
|
||||
#ifndef EIGEN_NO_DEBUG
|
||||
protected:
|
||||
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);
|
||||
|
||||
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;
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -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
|
||||
{
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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;}
|
||||
|
||||
@@ -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
|
||||
};
|
||||
};
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
/** \returns the number of columns */
|
||||
inline int rows() const { return m_indices.size(); }
|
||||
/** Constructs an uninitialized permutation matrix of given size.
|
||||
*/
|
||||
inline PermutationMatrix(int size) : m_indices(size)
|
||||
{}
|
||||
|
||||
/** \returns the number of rows */
|
||||
inline int rows() const { return m_indices.size(); }
|
||||
|
||||
/** \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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
@@ -150,7 +150,6 @@ template<typename MatrixType, unsigned int UpLo> class SelfAdjointView
|
||||
const LDLT<PlainMatrixType> ldlt() const;
|
||||
|
||||
protected:
|
||||
|
||||
const typename MatrixType::Nested m_matrix;
|
||||
};
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 Scalar, bool DestIsTranposed, typename OtherDerived>
|
||||
struct ei_check_transpose_aliasing_selector
|
||||
{
|
||||
static bool run(const Scalar* dest, const OtherDerived& src)
|
||||
{
|
||||
return (ei_blas_traits<OtherDerived>::IsTransposed != DestIsTranposed) && (dest==(Scalar*)ei_extract_data(src));
|
||||
}
|
||||
};
|
||||
|
||||
template<typename Scalar, bool DestIsTranposed, typename BinOp, typename DerivedA, typename DerivedB>
|
||||
struct ei_check_transpose_aliasing_selector<Scalar,DestIsTranposed,CwiseBinaryOp<BinOp,DerivedA,DerivedB> >
|
||||
{
|
||||
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 OtherDerived>
|
||||
Derived& DenseBase<Derived>::lazyAssign(const Transpose<OtherDerived>& other)
|
||||
void DenseBase<Derived>::checkTransposeAliasing(const OtherDerived& other) const
|
||||
{
|
||||
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)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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));
|
||||
}
|
||||
|
||||
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)
|
||||
{
|
||||
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
|
||||
|
||||
|
||||
@@ -26,22 +26,11 @@
|
||||
#ifndef EIGEN_TRIANGULARMATRIX_H
|
||||
#define EIGEN_TRIANGULARMATRIX_H
|
||||
|
||||
/** \nonstableyet
|
||||
/** \internal
|
||||
*
|
||||
* \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.
|
||||
*
|
||||
* 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.
|
||||
*
|
||||
* \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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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); }
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -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()); }
|
||||
};
|
||||
|
||||
@@ -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;
|
||||
namespace Architecture
|
||||
{
|
||||
enum Type {
|
||||
Generic = 0x0,
|
||||
SSE = 0x1,
|
||||
AltiVec = 0x2,
|
||||
#if defined EIGEN_VECTORIZE_SSE
|
||||
Target = SSE
|
||||
#elif defined EIGEN_VECTORIZE_ALTIVEC
|
||||
Target = AltiVec
|
||||
#else
|
||||
Target = Generic
|
||||
#endif
|
||||
};
|
||||
}
|
||||
|
||||
enum DenseStorageMatrix {};
|
||||
enum DenseStorageArray {};
|
||||
|
||||
#if defined EIGEN_VECTORIZE_SSE
|
||||
const int EiArch = EiArch_SSE;
|
||||
#elif defined EIGEN_VECTORIZE_ALTIVEC
|
||||
const int EiArch = EiArch_AltiVec;
|
||||
#else
|
||||
const int EiArch = EiArch_Generic;
|
||||
#endif
|
||||
|
||||
#endif // EIGEN_CONSTANTS_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
|
||||
|
||||
@@ -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 && \
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user