big addons:

* add Homogeneous expression for vector and set of vectors (aka matrix)
  => the next step will be to overload operator*
* add homogeneous normalization (again for vector and set of vectors)
* add a Replicate expression (with uni-directional replication
  facilities)
=> for all of them I'll add examples once we agree on the API
* fix gcc-4.4 warnings
* rename reverse.cpp array_reverse.cpp
This commit is contained in:
Gael Guennebaud
2009-03-05 10:25:22 +00:00
parent d710ccd41e
commit 0be89a4796
20 changed files with 623 additions and 75 deletions

View File

@@ -299,7 +299,7 @@ struct ei_functor_traits<ei_scalar_imag_op<Scalar> >
* indeed it seems better to declare m_other as a PacketScalar and do the ei_pset1() once
* in the constructor. However, in practice:
* - GCC does not like m_other as a PacketScalar and generate a load every time it needs it
* - one the other hand GCC is able to moves the ei_pset1() away the loop :)
* - on the other hand GCC is able to moves the ei_pset1() away the loop :)
* - simpler code ;)
* (ICC and gcc 4.4 seems to perform well in both cases, the issue is visible with y = a*x + b*y)
*/

View File

@@ -360,10 +360,6 @@ template<typename Derived> class MatrixBase
void transposeInPlace();
const AdjointReturnType adjoint() const;
Eigen::Reverse<Derived, BothDirections> reverse();
const Eigen::Reverse<Derived, BothDirections> reverse() const;
void reverseInPlace();
RowXpr row(int i);
const RowXpr row(int i) const;
@@ -589,6 +585,14 @@ template<typename Derived> class MatrixBase
select(typename ElseDerived::Scalar thenScalar, const MatrixBase<ElseDerived>& elseMatrix) const;
template<int p> RealScalar lpNorm() const;
template<int RowFactor, int ColFactor>
const Replicate<Derived,RowFactor,ColFactor> replicate() const;
const Replicate<Derived,Dynamic,Dynamic> replicate(int rowFacor,int colFactor) const;
Eigen::Reverse<Derived, BothDirections> reverse();
const Eigen::Reverse<Derived, BothDirections> reverse() const;
void reverseInPlace();
/////////// LU module ///////////
@@ -620,6 +624,17 @@ template<typename Derived> class MatrixBase
PlainMatrixType unitOrthogonal(void) const;
Matrix<Scalar,3,1> eulerAngles(int a0, int a1, int a2) const;
const ScalarMultipleReturnType operator*(const UniformScaling<Scalar>& s) const;
enum {
SizeMinusOne = SizeAtCompileTime==Dynamic ? Dynamic : SizeAtCompileTime-1
};
typedef Block<Derived,
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;
const HNormalizedReturnType hnormalized() const;
const Homogeneous<Derived,MatrixBase<Derived>::ColsAtCompileTime==1?Vertical:Horizontal> homogeneous() const;
/////////// Sparse module ///////////

View File

@@ -28,28 +28,38 @@
/** \class ReturnByValue
*
*/
template<typename Functor,typename EvalType>
struct ei_traits<ReturnByValue<Functor,EvalType> > : public ei_traits<EvalType>
template<typename Functor, typename _Scalar,int _Rows,int _Cols,int _Options,int _MaxRows,int _MaxCols>
struct ei_traits<ReturnByValue<Functor,Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> > >
: public ei_traits<Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> >
{
enum {
Flags = ei_traits<EvalType>::Flags | EvalBeforeNestingBit
Flags = ei_traits<Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> >::Flags | EvalBeforeNestingBit
};
};
template<typename Functor,typename EvalType,int n>
struct ei_nested<ReturnByValue<Functor,EvalType>, n, EvalType>
template<typename Functor,typename EvalTypeDerived,int n>
struct ei_nested<ReturnByValue<Functor,MatrixBase<EvalTypeDerived> >, n, EvalTypeDerived>
{
typedef EvalType type;
typedef EvalTypeDerived type;
};
template<typename Functor, typename EvalType> class ReturnByValue
: public MatrixBase<ReturnByValue<Functor,EvalType> >
{
public:
template<typename Dest>
inline void evalTo(Dest& dst) const
{ static_cast<const Functor*>(this)->evalTo(dst); }
};
template<typename Functor, typename _Scalar,int _Rows,int _Cols,int _Options,int _MaxRows,int _MaxCols>
class ReturnByValue<Functor,Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> >
: public MatrixBase<ReturnByValue<Functor,Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> > >
{
public:
EIGEN_GENERIC_PUBLIC_INTERFACE(ReturnByValue)
template<typename Dest>
inline void evalTo(Dest& dst) const
{ static_cast<const Functor*>(this)->evalTo(dst); }
{ static_cast<const Functor* const>(this)->evalTo(dst); }
};
template<typename Derived>

View File

@@ -262,6 +262,7 @@ static void ei_cache_friendly_product(
blB += 4*nr*PacketSize;
blA += 4*mr;
}
// process remaining peeled loop
for(int k=peeled_kc; k<actual_kc; k++)
{
PacketType B0, B1, B2, B3, A0, A1;

View File

@@ -38,19 +38,18 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
const Scalar* lhs, int lhsStride,
const RhsType& rhs,
Scalar* res)
{
{asm("#ei_cache_friendly_product_colmajor_times_vector");
#ifdef _EIGEN_ACCUMULATE_PACKETS
#error _EIGEN_ACCUMULATE_PACKETS has already been defined
#endif
#define _EIGEN_ACCUMULATE_PACKETS(A0,A13,A2,OFFSET) \
ei_pstore(&res[j OFFSET], \
ei_padd(ei_pload(&res[j OFFSET]), \
#define _EIGEN_ACCUMULATE_PACKETS(A0,A13,A2) \
ei_pstore(&res[j], \
ei_padd(ei_pload(&res[j]), \
ei_padd( \
ei_padd(ei_pmul(ptmp0,EIGEN_CAT(ei_pload , A0)(&lhs0[j OFFSET])), \
ei_pmul(ptmp1,EIGEN_CAT(ei_pload , A13)(&lhs1[j OFFSET]))), \
ei_padd(ei_pmul(ptmp2,EIGEN_CAT(ei_pload , A2)(&lhs2[j OFFSET])), \
ei_pmul(ptmp3,EIGEN_CAT(ei_pload , A13)(&lhs3[j OFFSET]))) )))
ei_padd(ei_pmul(ptmp0,EIGEN_CAT(ei_ploa , A0)(&lhs0[j])), \
ei_pmul(ptmp1,EIGEN_CAT(ei_ploa , A13)(&lhs1[j]))), \
ei_padd(ei_pmul(ptmp2,EIGEN_CAT(ei_ploa , A2)(&lhs2[j])), \
ei_pmul(ptmp3,EIGEN_CAT(ei_ploa , A13)(&lhs3[j]))) )))
typedef typename ei_packet_traits<Scalar>::type Packet;
const int PacketSize = sizeof(Packet)/sizeof(Scalar);
@@ -125,11 +124,11 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
{
case AllAligned:
for (int j = alignedStart; j<alignedSize; j+=PacketSize)
_EIGEN_ACCUMULATE_PACKETS(EIGEN_EMPTY,EIGEN_EMPTY,EIGEN_EMPTY,EIGEN_EMPTY);
_EIGEN_ACCUMULATE_PACKETS(d,d,d);
break;
case EvenAligned:
for (int j = alignedStart; j<alignedSize; j+=PacketSize)
_EIGEN_ACCUMULATE_PACKETS(EIGEN_EMPTY,u,EIGEN_EMPTY,EIGEN_EMPTY);
_EIGEN_ACCUMULATE_PACKETS(d,du,d);
break;
case FirstAligned:
if(peels>1)
@@ -165,11 +164,11 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
}
}
for (int j = peeledSize; j<alignedSize; j+=PacketSize)
_EIGEN_ACCUMULATE_PACKETS(EIGEN_EMPTY,u,u,EIGEN_EMPTY);
_EIGEN_ACCUMULATE_PACKETS(d,du,du);
break;
default:
for (int j = alignedStart; j<alignedSize; j+=PacketSize)
_EIGEN_ACCUMULATE_PACKETS(u,u,u,EIGEN_EMPTY);
_EIGEN_ACCUMULATE_PACKETS(du,du,du);
break;
}
}
@@ -233,12 +232,12 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
#error _EIGEN_ACCUMULATE_PACKETS has already been defined
#endif
#define _EIGEN_ACCUMULATE_PACKETS(A0,A13,A2,OFFSET) {\
#define _EIGEN_ACCUMULATE_PACKETS(A0,A13,A2) {\
Packet b = ei_pload(&rhs[j]); \
ptmp0 = ei_pmadd(b, EIGEN_CAT(ei_pload,A0) (&lhs0[j]), ptmp0); \
ptmp1 = ei_pmadd(b, EIGEN_CAT(ei_pload,A13)(&lhs1[j]), ptmp1); \
ptmp2 = ei_pmadd(b, EIGEN_CAT(ei_pload,A2) (&lhs2[j]), ptmp2); \
ptmp3 = ei_pmadd(b, EIGEN_CAT(ei_pload,A13)(&lhs3[j]), ptmp3); }
ptmp0 = ei_pmadd(b, EIGEN_CAT(ei_ploa,A0) (&lhs0[j]), ptmp0); \
ptmp1 = ei_pmadd(b, EIGEN_CAT(ei_ploa,A13)(&lhs1[j]), ptmp1); \
ptmp2 = ei_pmadd(b, EIGEN_CAT(ei_ploa,A2) (&lhs2[j]), ptmp2); \
ptmp3 = ei_pmadd(b, EIGEN_CAT(ei_ploa,A13)(&lhs3[j]), ptmp3); }
typedef typename ei_packet_traits<Scalar>::type Packet;
const int PacketSize = sizeof(Packet)/sizeof(Scalar);
@@ -319,11 +318,11 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
{
case AllAligned:
for (int j = alignedStart; j<alignedSize; j+=PacketSize)
_EIGEN_ACCUMULATE_PACKETS(EIGEN_EMPTY,EIGEN_EMPTY,EIGEN_EMPTY,EIGEN_EMPTY);
_EIGEN_ACCUMULATE_PACKETS(d,d,d);
break;
case EvenAligned:
for (int j = alignedStart; j<alignedSize; j+=PacketSize)
_EIGEN_ACCUMULATE_PACKETS(EIGEN_EMPTY,u,EIGEN_EMPTY,EIGEN_EMPTY);
_EIGEN_ACCUMULATE_PACKETS(d,du,d);
break;
case FirstAligned:
if (peels>1)
@@ -362,11 +361,11 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
}
}
for (int j = peeledSize; j<alignedSize; j+=PacketSize)
_EIGEN_ACCUMULATE_PACKETS(EIGEN_EMPTY,u,u,EIGEN_EMPTY);
_EIGEN_ACCUMULATE_PACKETS(d,du,du);
break;
default:
for (int j = alignedStart; j<alignedSize; j+=PacketSize)
_EIGEN_ACCUMULATE_PACKETS(u,u,u,EIGEN_EMPTY);
_EIGEN_ACCUMULATE_PACKETS(du,du,du);
break;
}
tmp0 += ei_predux(ptmp0);

View File

@@ -140,37 +140,6 @@ static EIGEN_DONT_INLINE void ei_product_selfadjoint_vector(
}
res[j] += t2;
}
/*
// colmajor - upper
for (int j=0;j<size;j++)
{
register const Scalar* __restrict__ A0 = lhs + j*lhsStride;
Scalar t1 = rhs[j];
Scalar t2 = 0;
for (int i=0; i<j; i+=PacketSize) {
res[i] += t1 * A0[i];
t2 += A0[i] * rhs[i];
}
res[j] += t1 * A0[j];
res[j] += t2;
}
// rowmajor - lower
for (int j=0;j<size;j++)
{
register const Scalar* __restrict__ A0 = lhs + j*lhsStride;
Scalar t1 = rhs[j];
Scalar t2 = 0;
for (int i=0; i<j; i+=PacketSize) {
res[i] += t1 * A0[i];
t2 += A0[i] * rhs[i];
}
res[j] += t1 * A0[j];
res[j] += t2;
}
*/
}

View File

@@ -239,4 +239,12 @@ enum {
HasDirectAccess = DirectAccessBit
};
enum TransformTraits {
Affine = 0x1,
Isometry = 0x2,
AffineSquare = Affine|0x10,
AffineCompact = Affine|0x20,
Projective = 0x30
};
#endif // EIGEN_CONSTANTS_H

View File

@@ -40,7 +40,6 @@ template<typename MatrixType, int BlockRows=Dynamic, int BlockCols=Dynamic, int
int _DirectAccessStatus = ei_traits<MatrixType>::Flags&DirectAccessBit ? DirectAccessBit
: ei_traits<MatrixType>::Flags&SparseBit> class Block;
template<typename MatrixType> class Transpose;
template<typename MatrixType, int Direction = BothDirections> class Reverse;
template<typename MatrixType> class Conjugate;
template<typename NullaryOp, typename MatrixType> class CwiseNullaryOp;
template<typename UnaryOp, typename MatrixType> class CwiseUnaryOp;
@@ -104,6 +103,8 @@ void ei_cache_friendly_product(
template<typename ConditionMatrixType, typename ThenMatrixType, typename ElseMatrixType> class Select;
template<typename MatrixType, typename BinaryOp, int Direction> class PartialReduxExpr;
template<typename ExpressionType, int Direction> class PartialRedux;
template<typename MatrixType,int RowFactor,int ColFactor> class Replicate;
template<typename MatrixType, int Direction = BothDirections> class Reverse;
template<typename MatrixType> class LU;
template<typename MatrixType> class QR;
@@ -117,11 +118,12 @@ template<typename Lhs, typename Rhs> class Cross;
template<typename Scalar> class Quaternion;
template<typename Scalar> class Rotation2D;
template<typename Scalar> class AngleAxis;
template<typename Scalar,int Dim> class Transform;
template<typename Scalar,int Dim/*,int Mode=AffineSquare*/> class Transform;
template <typename _Scalar, int _AmbientDim> class ParametrizedLine;
template <typename _Scalar, int _AmbientDim> class Hyperplane;
template<typename Scalar,int Dim> class Translation;
template<typename Scalar> class UniformScaling;
template<typename MatrixType,int Direction> class Homogeneous;
// Sparse module:
template<typename Lhs, typename Rhs, int ProductMode> class SparseProduct;

View File

@@ -211,6 +211,19 @@ template<typename ExpressionType, int RowsOrSize=Dynamic, int Cols=Dynamic> stru
typedef Block<ExpressionType, RowsOrSize, Cols> Type;
};
template<typename ExpressionType> struct HNormalizedReturnType {
enum {
SizeAtCompileTime = ExpressionType::SizeAtCompileTime,
SizeMinusOne = SizeAtCompileTime==Dynamic ? Dynamic : SizeAtCompileTime-1
};
typedef Block<ExpressionType,
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;
};
template<typename CurrentType, typename NewType> struct ei_cast_return_type
{
typedef typename ei_meta_if<ei_is_same_type<CurrentType,NewType>::ret,const CurrentType&,NewType>::ret type;