a couple of fixes, now Array passes the linearstructure test

This commit is contained in:
Gael Guennebaud 2009-12-17 19:28:54 +01:00
parent 4b70b47998
commit af4d8c5cec
14 changed files with 146 additions and 44 deletions

View File

@ -25,6 +25,12 @@
#ifndef EIGEN_ARRAY_H
#define EIGEN_ARRAY_H
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
struct ei_traits<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> > : ei_traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
{
typedef DenseStorageArray DenseStorageType;
};
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
class Array
: public DenseStorageBase<Array<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>, ArrayBase, _Options>
@ -183,6 +189,11 @@ class Array
other.evalTo(*this);
}
// template<typename OtherDerived>
// Array& lazyAssign(const ArrayBase<OtherDerived>& other);
// template<typename OtherDerived>
// Array& lazyAssign(const MatrixBase<OtherDerived>& other);
/** \sa MatrixBase::operator=(const AnyMatrixBase<OtherDerived>&) */
template<typename OtherDerived>
EIGEN_STRONG_INLINE Array(const AnyMatrixBase<OtherDerived> &other)

View File

@ -84,7 +84,12 @@ template<typename Derived> class ArrayBase
using Base::size;
using Base::coeff;
using Base::coeffRef;
using Base::lazyAssign;
using Base::operator=;
using Base::operator+=;
using Base::operator-=;
using Base::operator*=;
using Base::operator/=;
typedef typename Base::RealScalar RealScalar;
typedef typename Base::CoeffReturnType CoeffReturnType;
@ -114,6 +119,7 @@ template<typename Derived> class ArrayBase
# include "../plugins/MatrixCwiseUnaryOps.h"
# include "../plugins/ArrayCwiseUnaryOps.h"
# include "../plugins/CommonCwiseBinaryOps.h"
# include "../plugins/MatrixCwiseBinaryOps.h"
# include "../plugins/ArrayCwiseBinaryOps.h"
# ifdef EIGEN_ARRAYBASE_PLUGIN
# include EIGEN_ARRAYBASE_PLUGIN
@ -137,6 +143,8 @@ template<typename Derived> class ArrayBase
/** Copies \a other into *this without evaluating other. \returns a reference to *this. */
// template<typename OtherDerived>
// Derived& lazyAssign(const ArrayBase<OtherDerived>& other);
// template<typename OtherDerived>
// Derived& lazyAssign(const MatrixBase<OtherDerived>& other);
#endif // not EIGEN_PARSED_BY_DOXYGEN
Derived& operator+=(const Scalar& scalar)
@ -206,4 +214,32 @@ template<typename Derived> class ArrayBase
template<typename OtherDerived> explicit ArrayBase(const ArrayBase<OtherDerived>&);
};
/** replaces \c *this by \c *this - \a other.
*
* \returns a reference to \c *this
*/
template<typename Derived>
template<typename OtherDerived>
EIGEN_STRONG_INLINE Derived &
ArrayBase<Derived>::operator-=(const ArrayBase<OtherDerived> &other)
{
SelfCwiseBinaryOp<ei_scalar_difference_op<Scalar>, Derived> tmp(derived());
tmp = other;
return derived();
}
/** replaces \c *this by \c *this + \a other.
*
* \returns a reference to \c *this
*/
template<typename Derived>
template<typename OtherDerived>
EIGEN_STRONG_INLINE Derived &
ArrayBase<Derived>::operator+=(const ArrayBase<OtherDerived>& other)
{
SelfCwiseBinaryOp<ei_scalar_sum_op<Scalar>, Derived> tmp(derived());
tmp = other.derived();
return derived();
}
#endif // EIGEN_ARRAYBASE_H

View File

@ -28,7 +28,9 @@
template<typename ExpressionType>
struct ei_traits<ArrayWrapper<ExpressionType> >
: public ei_traits<ExpressionType>
{};
{
typedef DenseStorageArray DenseStorageType;
};
template<typename ExpressionType>
class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
@ -98,13 +100,16 @@ class ArrayWrapper : public ArrayBase<ArrayWrapper<ExpressionType> >
template<typename ExpressionType>
struct ei_traits<MatrixWrapper<ExpressionType> >
: public ei_traits<ExpressionType>
{};
{
typedef DenseStorageMatrix DenseStorageType;
};
template<typename ExpressionType>
class MatrixWrapper : public MatrixBase<MatrixWrapper<ExpressionType> >
{
public:
EIGEN_GENERIC_PUBLIC_INTERFACE(MatrixWrapper)
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(MatrixWrapper);
inline MatrixWrapper(const ExpressionType& matrix) : m_expression(matrix) {}

View File

@ -37,7 +37,7 @@
*/
template<typename Derived> struct AnyMatrixBase
{
typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType;
// typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType;
/** \returns a reference to the derived object */
Derived& derived() { return *static_cast<Derived*>(this); }

View File

@ -58,12 +58,11 @@
* \sa DenseBase::block(int,int,int,int), DenseBase::block(int,int), class VectorBlock
*/
template<typename MatrixType, int BlockRows, int BlockCols, int _DirectAccessStatus>
struct ei_traits<Block<MatrixType, BlockRows, BlockCols, _DirectAccessStatus> >
struct ei_traits<Block<MatrixType, BlockRows, BlockCols, _DirectAccessStatus> > : ei_traits<MatrixType>
{
typedef typename ei_traits<MatrixType>::Scalar Scalar;
typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
typedef typename ei_traits<MatrixType>::StorageType StorageType;
enum{
RowsAtCompileTime = BlockRows,
ColsAtCompileTime = BlockCols,
@ -77,8 +76,7 @@ struct ei_traits<Block<MatrixType, BlockRows, BlockCols, _DirectAccessStatus> >
MaskPacketAccessBit = (InnerMaxSize == Dynamic || (InnerSize >= ei_packet_traits<Scalar>::size))
? PacketAccessBit : 0,
FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
Flags = (ei_traits<MatrixType>::Flags & (HereditaryBits | MaskPacketAccessBit | DirectAccessBit)) | FlagsLinearAccessBit,
CoeffReadCost = ei_traits<MatrixType>::CoeffReadCost
Flags = (ei_traits<MatrixType>::Flags & (HereditaryBits | MaskPacketAccessBit | DirectAccessBit)) | FlagsLinearAccessBit
};
};

View File

@ -44,7 +44,7 @@
* \sa MatrixBase::binaryExpr(const MatrixBase<OtherDerived> &,const CustomBinaryOp &) const, class CwiseUnaryOp, class CwiseNullaryOp
*/
template<typename BinaryOp, typename Lhs, typename Rhs>
struct ei_traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
struct ei_traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> > : ei_traits<Lhs>
{
// even though we require Lhs and Rhs to have the same scalar type (see CwiseBinaryOp constructor),
// we still want to handle the case when the result type is different.
@ -65,10 +65,6 @@ struct ei_traits<CwiseBinaryOp<BinaryOp, Lhs, Rhs> >
RhsCoeffReadCost = _RhsNested::CoeffReadCost,
LhsFlags = _LhsNested::Flags,
RhsFlags = _RhsNested::Flags,
RowsAtCompileTime = Lhs::RowsAtCompileTime,
ColsAtCompileTime = Lhs::ColsAtCompileTime,
MaxRowsAtCompileTime = Lhs::MaxRowsAtCompileTime,
MaxColsAtCompileTime = Lhs::MaxColsAtCompileTime,
Flags = (int(LhsFlags) | int(RhsFlags)) & (
HereditaryBits
| (int(LhsFlags) & int(RhsFlags) & (LinearAccessBit | AlignedBit))

View File

@ -307,7 +307,7 @@ class DenseStorageBase : public _Base<Derived>
/** \sa MatrixBase::lazyAssign() */
template<typename OtherDerived>
EIGEN_STRONG_INLINE Derived& lazyAssign(const MatrixBase<OtherDerived>& other)
EIGEN_STRONG_INLINE Derived& lazyAssign(const DenseBase<OtherDerived>& other)
{
_resize_to_match(other);
return Base::lazyAssign(other.derived());

View File

@ -54,6 +54,9 @@ bool DenseBase<Derived>::isApprox(
{
const typename ei_nested<Derived,2>::type nested(derived());
const typename ei_nested<OtherDerived,2>::type otherNested(other.derived());
// std::cerr << typeid(Derived).name() << " => " << typeid(typename ei_nested<Derived,2>::type).name() << "\n";
// std::cerr << typeid(OtherDerived).name() << " => " << typeid(typename ei_nested<OtherDerived,2>::type).name() << "\n";
// return false;
return (nested - otherNested).cwiseAbs2().sum() <= prec * prec * std::min(nested.cwiseAbs2().sum(), otherNested.cwiseAbs2().sum());
}

View File

@ -112,6 +112,7 @@ struct ei_traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
{
typedef _Scalar Scalar;
typedef Dense StorageType;
typedef DenseStorageMatrix DenseStorageType;
enum {
RowsAtCompileTime = _Rows,
ColsAtCompileTime = _Cols,

View File

@ -124,14 +124,14 @@ template<typename Derived> class MatrixBase
* reference to a matrix, not a matrix! It is however guaranteed that the return type of eval() is either
* PlainMatrixType or const PlainMatrixType&.
*/
typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType;
// typedef Matrix<typename ei_traits<Derived>::Scalar,
// ei_traits<Derived>::RowsAtCompileTime,
// ei_traits<Derived>::ColsAtCompileTime,
// AutoAlign | (ei_traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor),
// ei_traits<Derived>::MaxRowsAtCompileTime,
// ei_traits<Derived>::MaxColsAtCompileTime
// > PlainMatrixType;
// typedef typename ei_plain_matrix_type<Derived>::type PlainMatrixType;
typedef Matrix<typename ei_traits<Derived>::Scalar,
ei_traits<Derived>::RowsAtCompileTime,
ei_traits<Derived>::ColsAtCompileTime,
AutoAlign | (ei_traits<Derived>::Flags&RowMajorBit ? RowMajor : ColMajor),
ei_traits<Derived>::MaxRowsAtCompileTime,
ei_traits<Derived>::MaxColsAtCompileTime
> PlainMatrixType;
/** \internal the column-major plain matrix type corresponding to this expression. Note that is not necessarily
* exactly the return type of eval(): in the case of plain matrices, the return type of eval() is a const
* reference to a matrix, not a matrix!

View File

@ -35,11 +35,15 @@ template<typename BinaryOp, typename MatrixType>
struct ei_traits<SelfCwiseBinaryOp<BinaryOp,MatrixType> > : ei_traits<MatrixType> {};
template<typename BinaryOp, typename MatrixType> class SelfCwiseBinaryOp
: public MatrixBase<SelfCwiseBinaryOp<BinaryOp,MatrixType> >
//: public MatrixBase<SelfCwiseBinaryOp<BinaryOp,MatrixType> >
: public MatrixType::template MakeBase< SelfCwiseBinaryOp<BinaryOp, MatrixType> >::Type
{
public:
EIGEN_GENERIC_PUBLIC_INTERFACE(SelfCwiseBinaryOp)
typedef typename MatrixType::template MakeBase< SelfCwiseBinaryOp<BinaryOp, MatrixType> >::Type Base;
_EIGEN_DENSE_PUBLIC_INTERFACE(SelfCwiseBinaryOp)
// EIGEN_GENERIC_PUBLIC_INTERFACE(SelfCwiseBinaryOp)
typedef typename ei_packet_traits<Scalar>::type Packet;
using Base::operator=;
@ -65,7 +69,7 @@ template<typename BinaryOp, typename MatrixType> class SelfCwiseBinaryOp
}
template<typename OtherDerived>
void copyCoeff(int row, int col, const MatrixBase<OtherDerived>& other)
void copyCoeff(int row, int col, const DenseBase<OtherDerived>& other)
{
OtherDerived& _other = other.const_cast_derived();
ei_internal_assert(row >= 0 && row < rows()
@ -75,7 +79,7 @@ template<typename BinaryOp, typename MatrixType> class SelfCwiseBinaryOp
}
template<typename OtherDerived>
void copyCoeff(int index, const MatrixBase<OtherDerived>& other)
void copyCoeff(int index, const DenseBase<OtherDerived>& other)
{
OtherDerived& _other = other.const_cast_derived();
ei_internal_assert(index >= 0 && index < m_matrix.size());
@ -84,7 +88,7 @@ template<typename BinaryOp, typename MatrixType> class SelfCwiseBinaryOp
}
template<typename OtherDerived, int StoreMode, int LoadMode>
void copyPacket(int row, int col, const MatrixBase<OtherDerived>& other)
void copyPacket(int row, int col, const DenseBase<OtherDerived>& other)
{
OtherDerived& _other = other.const_cast_derived();
ei_internal_assert(row >= 0 && row < rows()
@ -94,7 +98,7 @@ template<typename BinaryOp, typename MatrixType> class SelfCwiseBinaryOp
}
template<typename OtherDerived, int StoreMode, int LoadMode>
void copyPacket(int index, const MatrixBase<OtherDerived>& other)
void copyPacket(int index, const DenseBase<OtherDerived>& other)
{
OtherDerived& _other = other.const_cast_derived();
ei_internal_assert(index >= 0 && index < m_matrix.size());

View File

@ -271,6 +271,9 @@ const int EiArch_Generic = 0x0;
const int EiArch_SSE = 0x1;
const int EiArch_AltiVec = 0x2;
enum DenseStorageMatrix {};
enum DenseStorageArray {};
#if defined EIGEN_VECTORIZE_SSE
const int EiArch = EiArch_SSE;
#elif defined EIGEN_VECTORIZE_ALTIVEC

View File

@ -104,13 +104,35 @@ template<int _Rows, int _Cols> struct ei_size_at_compile_time
enum { ret = (_Rows==Dynamic || _Cols==Dynamic) ? Dynamic : _Rows * _Cols };
};
/* ei_eval : the return type of eval(). For matrices, this is just a const reference
* in order to avoid a useless copy
/* ei_plain_matrix_type : the difference from ei_eval is that ei_plain_matrix_type is always a plain matrix type,
* whereas ei_eval is a const reference in the case of a matrix
*/
template<typename T, typename StorageType = typename ei_traits<T>::StorageType> class ei_eval;
// template<typename Derived> class MatrixBase;
// template<typename Derived> class ArrayBase;
// template<typename Object> struct ei_is_matrix_or_array
// {
// struct is_matrix {int a[1];};
// struct is_array {int a[2];};
// struct is_none {int a[3];};
//
// template<typename T>
// static is_matrix testBaseClass(const MatrixBase<T>*);
// template<typename T>
// static is_array testBaseClass(const ArrayBase<T>*);
// // static is_none testBaseClass(...);
//
// enum {BaseClassType = sizeof(testBaseClass(static_cast<const Object*>(0)))};
// };
template<typename T> struct ei_eval<T,Dense>
template<typename T, typename StorageType = typename ei_traits<T>::StorageType> class ei_plain_matrix_type;
template<typename T, typename BaseClassType> struct ei_plain_matrix_type_dense;
template<typename T> struct ei_plain_matrix_type<T,Dense>
{
typedef typename ei_plain_matrix_type_dense<T,typename ei_traits<T>::DenseStorageType>::type type;
};
template<typename T> struct ei_plain_matrix_type_dense<T,DenseStorageMatrix>
{
typedef Matrix<typename ei_traits<T>::Scalar,
ei_traits<T>::RowsAtCompileTime,
@ -121,6 +143,36 @@ template<typename T> struct ei_eval<T,Dense>
> type;
};
template<typename T> struct ei_plain_matrix_type_dense<T,DenseStorageArray>
{
typedef Array<typename ei_traits<T>::Scalar,
ei_traits<T>::RowsAtCompileTime,
ei_traits<T>::ColsAtCompileTime,
AutoAlign | (ei_traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
ei_traits<T>::MaxRowsAtCompileTime,
ei_traits<T>::MaxColsAtCompileTime
> type;
};
/* ei_eval : the return type of eval(). For matrices, this is just a const reference
* in order to avoid a useless copy
*/
template<typename T, typename StorageType = typename ei_traits<T>::StorageType> class ei_eval;
template<typename T> struct ei_eval<T,Dense>
{
typedef typename ei_plain_matrix_type<T>::type type;
// typedef typename T::PlainMatrixType type;
// typedef T::Matrix<typename ei_traits<T>::Scalar,
// ei_traits<T>::RowsAtCompileTime,
// ei_traits<T>::ColsAtCompileTime,
// AutoAlign | (ei_traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
// ei_traits<T>::MaxRowsAtCompileTime,
// ei_traits<T>::MaxColsAtCompileTime
// > type;
};
// for matrices, no need to evaluate, just use a const reference to avoid a useless copy
template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols>
struct ei_eval<Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>, Dense>
@ -128,21 +180,14 @@ struct ei_eval<Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>,
typedef const Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>& type;
};
/* ei_plain_matrix_type : the difference from ei_eval is that ei_plain_matrix_type is always a plain matrix type,
* whereas ei_eval is a const reference in the case of a matrix
*/
template<typename T> struct ei_plain_matrix_type
template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols>
struct ei_eval<Array<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>, Dense>
{
// typedef typename T::PlainMatrixType type;
typedef Matrix<typename ei_traits<T>::Scalar,
ei_traits<T>::RowsAtCompileTime,
ei_traits<T>::ColsAtCompileTime,
AutoAlign | (ei_traits<T>::Flags&RowMajorBit ? RowMajor : ColMajor),
ei_traits<T>::MaxRowsAtCompileTime,
ei_traits<T>::MaxColsAtCompileTime
> type;
typedef const Array<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>& type;
};
/* ei_plain_matrix_type_column_major : same as ei_plain_matrix_type but guaranteed to be column-major
*/
template<typename T> struct ei_plain_matrix_type_column_major

View File

@ -31,7 +31,6 @@ template<typename MatrixType> void linearStructure(const MatrixType& m)
*/
typedef typename MatrixType::Scalar Scalar;
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> VectorType;
int rows = m.rows();
int cols = m.cols();
@ -95,5 +94,6 @@ void test_linearstructure()
CALL_SUBTEST_6( linearStructure(MatrixXf(8, 12)) );
CALL_SUBTEST_7( linearStructure(MatrixXi(8, 12)) );
CALL_SUBTEST_8( linearStructure(MatrixXcd(20, 20)) );
CALL_SUBTEST_9( linearStructure(ArrayXXf(12, 8)) );
}
}