* remove set(), revert to old behavior where = resizes

* try to be clever in matrix ctors and operator=: be lazy when we can, always allow
  to copy rowvector into columnvector, check the template parameters,
  try to factor the code better
* add missing copy ctor in UnalignedType
* fix bug in the traits of DiagonalProduct
* renaming: EIGEN_TUNE_FOR_CPU_CACHE_SIZE
* update the dox a little
This commit is contained in:
Benoit Jacob 2009-01-21 17:10:23 +00:00
parent a5fbf27843
commit 5f43a42ee7
17 changed files with 170 additions and 114 deletions

View File

@ -1,5 +1,5 @@
project(Eigen) project(Eigen)
set(EIGEN_VERSION_NUMBER "2.0-beta6") set(EIGEN_VERSION_NUMBER "2.0-rc1")
#if the svnversion program is absent, this will leave the SVN_REVISION string empty, #if the svnversion program is absent, this will leave the SVN_REVISION string empty,
#but won't stop CMake. #but won't stop CMake.

View File

@ -81,7 +81,7 @@ static void ei_cache_friendly_product(
MaxBlockRows_ClampingMask = 0xFFFFF8, MaxBlockRows_ClampingMask = 0xFFFFF8,
#endif #endif
// maximal size of the blocks fitted in L2 cache // maximal size of the blocks fitted in L2 cache
MaxL2BlockSize = ei_L2_block_traits<EIGEN_TUNE_FOR_L2_CACHE_SIZE,Scalar>::width MaxL2BlockSize = ei_L2_block_traits<EIGEN_TUNE_FOR_CPU_CACHE_SIZE,Scalar>::width
}; };
const bool resIsAligned = (PacketSize==1) || (((resStride%PacketSize) == 0) && (size_t(res)%16==0)); const bool resIsAligned = (PacketSize==1) || (((resStride%PacketSize) == 0) && (size_t(res)%16==0));

View File

@ -73,7 +73,7 @@ struct ei_traits<Product<LhsNested, RhsNested, DiagonalProduct> >
RemovedBits = ~((RhsFlags & RowMajorBit) && (!CanVectorizeLhs) ? 0 : RowMajorBit), RemovedBits = ~((RhsFlags & RowMajorBit) && (!CanVectorizeLhs) ? 0 : RowMajorBit),
Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits) Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits)
| (CanVectorizeLhs || CanVectorizeRhs ? PacketAccessBit : 0), | (((CanVectorizeLhs&&RhsIsDiagonal) || (CanVectorizeRhs&&LhsIsDiagonal)) ? PacketAccessBit : 0),
CoeffReadCost = NumTraits<Scalar>::MulCost + _LhsNested::CoeffReadCost + _RhsNested::CoeffReadCost CoeffReadCost = NumTraits<Scalar>::MulCost + _LhsNested::CoeffReadCost + _RhsNested::CoeffReadCost
}; };
@ -114,12 +114,10 @@ template<typename LhsNested, typename RhsNested> class Product<LhsNested, RhsNes
{ {
if (RhsIsDiagonal) if (RhsIsDiagonal)
{ {
ei_assert((_LhsNested::Flags&RowMajorBit)==0);
return ei_pmul(m_lhs.template packet<LoadMode>(row, col), ei_pset1(m_rhs.coeff(col, col))); return ei_pmul(m_lhs.template packet<LoadMode>(row, col), ei_pset1(m_rhs.coeff(col, col)));
} }
else else
{ {
ei_assert(_RhsNested::Flags&RowMajorBit);
return ei_pmul(ei_pset1(m_lhs.coeff(row, row)), m_rhs.template packet<LoadMode>(row, col)); return ei_pmul(ei_pset1(m_lhs.coeff(row, row)), m_rhs.template packet<LoadMode>(row, col));
} }
} }

View File

@ -102,17 +102,13 @@ template<typename MatrixType, int PacketAccess> class Map
* Only for fixed-size matrices and vectors. * Only for fixed-size matrices and vectors.
* \param data The array of data to copy * \param data The array of data to copy
* *
* For dynamic-size matrices and vectors, see the variants taking additional int parameters * \sa Matrix::Map(const Scalar *)
* for the dimensions.
*
* \sa Matrix(const Scalar *, int), Matrix(const Scalar *, int, int),
* Matrix::Map(const Scalar *)
*/ */
template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols> template<typename _Scalar, int _Rows, int _Cols, int _StorageOrder, int _MaxRows, int _MaxCols>
inline Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols> inline Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols>
::Matrix(const Scalar *data) ::Matrix(const Scalar *data)
{ {
*this = Eigen::Map<Matrix>(data); _set_noalias(Eigen::Map<Matrix>(data));
} }
#endif // EIGEN_MAP_H #endif // EIGEN_MAP_H

View File

@ -226,12 +226,11 @@ class Matrix
*/ */
inline void resize(int rows, int cols) inline void resize(int rows, int cols)
{ {
ei_assert(rows > 0 ei_assert(rows > 0 && cols > 0 && "a matrix cannot be resized to 0 size");
&& (MaxRowsAtCompileTime == Dynamic || MaxRowsAtCompileTime >= rows) ei_assert((MaxRowsAtCompileTime == Dynamic || MaxRowsAtCompileTime >= rows)
&& (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows) && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
&& cols > 0 && (MaxColsAtCompileTime == Dynamic || MaxColsAtCompileTime >= cols)
&& (MaxColsAtCompileTime == Dynamic || MaxColsAtCompileTime >= cols) && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
&& (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
m_storage.resize(rows * cols, rows, cols); m_storage.resize(rows * cols, rows, cols);
} }
@ -249,49 +248,19 @@ class Matrix
m_storage.resize(size, size, 1); m_storage.resize(size, size, 1);
} }
/** Copies the value of the expression \a other into \c *this.
*
* \warning Note that the sizes of \c *this and \a other must match.
* If you want automatic resizing, then you must use the function set().
*
* As a special exception, copying a row-vector into a vector (and conversely)
* is allowed.
*
* \sa set()
*/
template<typename OtherDerived>
EIGEN_STRONG_INLINE Matrix& operator=(const MatrixBase<OtherDerived>& other)
{
ei_assert(m_storage.data()!=0 && "you cannot use operator= with a non initialized matrix (instead use set()");
return Base::operator=(other.derived());
}
/** Copies the value of the expression \a other into \c *this with automatic resizing. /** Copies the value of the expression \a other into \c *this with automatic resizing.
* *
* This function is the same than the assignment operator = excepted that \c *this might * *this might be resized to match the dimensions of \a other. If *this was a null matrix (not already initialized),
* be resized to match the dimensions of \a other. * it will be initialized.
* *
* Note that copying a row-vector into a vector (and conversely) is allowed. * Note that copying a row-vector into a vector (and conversely) is allowed.
* The resizing, if any, is then done in the appropriate way so that row-vectors * The resizing, if any, is then done in the appropriate way so that row-vectors
* remain row-vectors and vectors remain vectors. * remain row-vectors and vectors remain vectors.
*
* \sa operator=()
*/ */
template<typename OtherDerived> template<typename OtherDerived>
inline Matrix& set(const MatrixBase<OtherDerived>& other) EIGEN_STRONG_INLINE Matrix& operator=(const MatrixBase<OtherDerived>& other)
{ {
if(RowsAtCompileTime == 1) return _set(other);
{
ei_assert(other.isVector());
resize(1, other.size());
}
else if(ColsAtCompileTime == 1)
{
ei_assert(other.isVector());
resize(other.size(), 1);
}
else resize(other.rows(), other.cols());
return Base::operator=(other.derived());
} }
/** This is a special case of the templated operator=. Its purpose is to /** This is a special case of the templated operator=. Its purpose is to
@ -299,7 +268,7 @@ class Matrix
*/ */
EIGEN_STRONG_INLINE Matrix& operator=(const Matrix& other) EIGEN_STRONG_INLINE Matrix& operator=(const Matrix& other)
{ {
return operator=<Matrix>(other); return _set(other);
} }
EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Matrix, +=) EIGEN_INHERIT_ASSIGNMENT_OPERATOR(Matrix, +=)
@ -311,34 +280,23 @@ class Matrix
* *
* For fixed-size matrices, does nothing. * For fixed-size matrices, does nothing.
* *
* For dynamic-size matrices, creates an empty matrix of size null. * For dynamic-size matrices, creates an empty matrix of size 0. Does not allocate any array. Such a matrix
* \warning while creating such an \em null matrix is allowed, it \b cannot * is called a null matrix. This constructor is the unique way to create null matrices: resizing
* \b be \b used before having being resized or initialized with the function set().
* In particular, initializing a null matrix with operator = is not supported.
* Finally, this constructor is the unique way to create null matrices: resizing
* a matrix to 0 is not supported. * a matrix to 0 is not supported.
* Here are some examples:
* \code
* MatrixXf r = MatrixXf::Random(3,4); // create a random matrix of floats
* MatrixXf m1, m2; // creates two null matrices of float
* *
* m1 = r; // illegal (raise an assertion) * \sa resize(int,int)
* r = m1; // illegal (raise an assertion)
* m1 = m2; // illegal (raise an assertion)
* m1.set(r); // OK
* m2.resize(3,4);
* m2 = r; // OK
* \endcode
*
* \sa resize(int,int), set()
*/ */
EIGEN_STRONG_INLINE explicit Matrix() : m_storage() EIGEN_STRONG_INLINE explicit Matrix() : m_storage()
{ {
ei_assert(RowsAtCompileTime > 0 && ColsAtCompileTime > 0); _check_template_params();
} }
#ifndef EIGEN_PARSED_BY_DOXYGEN
/** \internal */
Matrix(ei_constructor_without_unaligned_array_assert) Matrix(ei_constructor_without_unaligned_array_assert)
: m_storage(ei_constructor_without_unaligned_array_assert()) {} : m_storage(ei_constructor_without_unaligned_array_assert())
{}
#endif
/** Constructs a vector or row-vector with given dimension. \only_for_vectors /** Constructs a vector or row-vector with given dimension. \only_for_vectors
* *
@ -349,6 +307,7 @@ class Matrix
EIGEN_STRONG_INLINE explicit Matrix(int dim) EIGEN_STRONG_INLINE explicit Matrix(int dim)
: m_storage(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim) : m_storage(dim, RowsAtCompileTime == 1 ? 1 : dim, ColsAtCompileTime == 1 ? 1 : dim)
{ {
_check_template_params();
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix) EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix)
ei_assert(dim > 0); ei_assert(dim > 0);
ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim); ei_assert(SizeAtCompileTime == Dynamic || SizeAtCompileTime == dim);
@ -366,6 +325,7 @@ class Matrix
*/ */
EIGEN_STRONG_INLINE Matrix(int x, int y) : m_storage(x*y, x, y) EIGEN_STRONG_INLINE Matrix(int x, int y) : m_storage(x*y, x, y)
{ {
_check_template_params();
if((RowsAtCompileTime == 1 && ColsAtCompileTime == 2) if((RowsAtCompileTime == 1 && ColsAtCompileTime == 2)
|| (RowsAtCompileTime == 2 && ColsAtCompileTime == 1)) || (RowsAtCompileTime == 2 && ColsAtCompileTime == 1))
{ {
@ -381,6 +341,7 @@ class Matrix
/** constructs an initialized 2D vector with given coefficients */ /** constructs an initialized 2D vector with given coefficients */
EIGEN_STRONG_INLINE Matrix(const float& x, const float& y) EIGEN_STRONG_INLINE Matrix(const float& x, const float& y)
{ {
_check_template_params();
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 2) EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 2)
m_storage.data()[0] = x; m_storage.data()[0] = x;
m_storage.data()[1] = y; m_storage.data()[1] = y;
@ -388,6 +349,7 @@ class Matrix
/** constructs an initialized 2D vector with given coefficients */ /** constructs an initialized 2D vector with given coefficients */
EIGEN_STRONG_INLINE Matrix(const double& x, const double& y) EIGEN_STRONG_INLINE Matrix(const double& x, const double& y)
{ {
_check_template_params();
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 2) EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 2)
m_storage.data()[0] = x; m_storage.data()[0] = x;
m_storage.data()[1] = y; m_storage.data()[1] = y;
@ -395,6 +357,7 @@ class Matrix
/** constructs an initialized 3D vector with given coefficients */ /** constructs an initialized 3D vector with given coefficients */
EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z) EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z)
{ {
_check_template_params();
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 3) EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 3)
m_storage.data()[0] = x; m_storage.data()[0] = x;
m_storage.data()[1] = y; m_storage.data()[1] = y;
@ -403,6 +366,7 @@ class Matrix
/** constructs an initialized 4D vector with given coefficients */ /** constructs an initialized 4D vector with given coefficients */
EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w) EIGEN_STRONG_INLINE Matrix(const Scalar& x, const Scalar& y, const Scalar& z, const Scalar& w)
{ {
_check_template_params();
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 4) EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(Matrix, 4)
m_storage.data()[0] = x; m_storage.data()[0] = x;
m_storage.data()[1] = y; m_storage.data()[1] = y;
@ -417,14 +381,15 @@ class Matrix
EIGEN_STRONG_INLINE Matrix(const MatrixBase<OtherDerived>& other) EIGEN_STRONG_INLINE Matrix(const MatrixBase<OtherDerived>& other)
: m_storage(other.rows() * other.cols(), other.rows(), other.cols()) : m_storage(other.rows() * other.cols(), other.rows(), other.cols())
{ {
ei_assign_selector<Matrix,OtherDerived,false>::run(*this, other.derived()); _check_template_params();
//Base::operator=(other.derived()); _set_noalias(other);
} }
/** Copy constructor */ /** Copy constructor */
EIGEN_STRONG_INLINE Matrix(const Matrix& other) EIGEN_STRONG_INLINE Matrix(const Matrix& other)
: Base(), m_storage(other.rows() * other.cols(), other.rows(), other.cols()) : Base(), m_storage(other.rows() * other.cols(), other.rows(), other.cols())
{ {
Base::lazyAssign(other); _check_template_params();
_set_noalias(other);
} }
/** Destructor */ /** Destructor */
inline ~Matrix() {} inline ~Matrix() {}
@ -486,6 +451,72 @@ class Matrix
#ifdef EIGEN_MATRIX_PLUGIN #ifdef EIGEN_MATRIX_PLUGIN
#include EIGEN_MATRIX_PLUGIN #include EIGEN_MATRIX_PLUGIN
#endif #endif
private:
/** \internal Resizes *this in preparation for assigning \a other to it.
* Takes care of doing all the checking that's needed.
*
* Note that copying a row-vector into a vector (and conversely) is allowed.
* The resizing, if any, is then done in the appropriate way so that row-vectors
* remain row-vectors and vectors remain vectors.
*/
template<typename OtherDerived>
EIGEN_STRONG_INLINE void _resize_to_match(const MatrixBase<OtherDerived>& other)
{
if(RowsAtCompileTime == 1)
{
ei_assert(other.isVector());
resize(1, other.size());
}
else if(ColsAtCompileTime == 1)
{
ei_assert(other.isVector());
resize(other.size(), 1);
}
else resize(other.rows(), other.cols());
}
/** \internal 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),
* it will be initialized.
*
* Note that copying a row-vector into a vector (and conversely) is allowed.
* The resizing, if any, is then done in the appropriate way so that row-vectors
* remain row-vectors and vectors remain vectors.
*
* \sa operator=(const MatrixBase<OtherDerived>&), _set_noalias()
*/
template<typename OtherDerived>
EIGEN_STRONG_INLINE Matrix& _set(const MatrixBase<OtherDerived>& other)
{
_resize_to_match(other);
return Base::operator=(other);
}
/** \internal Like _set() but additionally makes the assumption that no aliasing effect can happen (which
* is the case when creating a new matrix) so one can enforce lazy evaluation.
*
* \sa operator=(const MatrixBase<OtherDerived>&), _set()
*/
template<typename OtherDerived>
EIGEN_STRONG_INLINE Matrix& _set_noalias(const MatrixBase<OtherDerived>& other)
{
_resize_to_match(other);
// the 'false' below means to enforce lazy evaluation. We don't use lazyAssign() because
// it wouldn't allow to copy a row-vector into a column-vector.
return ei_assign_selector<Matrix,OtherDerived,false>::run(*this, other.derived());
}
static EIGEN_STRONG_INLINE void _check_template_params()
{
EIGEN_STATIC_ASSERT((_Rows > 0
&& _Cols > 0
&& _MaxRows <= _Rows
&& _MaxCols <= _Cols
&& (_Options & (AutoAlign|RowMajor)) == _Options),
INVALID_MATRIX_TEMPLATE_PARAMETERS)
}
}; };
/** \defgroup matrixtypedefs Global matrix typedefs /** \defgroup matrixtypedefs Global matrix typedefs

View File

@ -175,7 +175,7 @@ struct ei_inplace_transpose_selector<MatrixType,false> { // non square matrix
if (m.rows()==m.cols()) if (m.rows()==m.cols())
m.template part<StrictlyUpperTriangular>().swap(m.transpose()); m.template part<StrictlyUpperTriangular>().swap(m.transpose());
else else
m.set(m.transpose().eval()); m = m.transpose().eval();
} }
}; };
@ -186,7 +186,7 @@ struct ei_inplace_transpose_selector<MatrixType,false> { // non square matrix
* then this "in-place" version is probably the right choice because it provides * then this "in-place" version is probably the right choice because it provides
* the following additional features: * the following additional features:
* - less error prone: doing the same operation with .transpose() requires special care: * - less error prone: doing the same operation with .transpose() requires special care:
* \code m.set(m.transpose().eval()); \endcode * \code m = m.transpose().eval(); \endcode
* - no temporary object is created (currently only for squared matrices) * - no temporary object is created (currently only for squared matrices)
* - it allows future optimizations (cache friendliness, etc.) * - it allows future optimizations (cache friendliness, etc.)
* *

View File

@ -50,10 +50,18 @@
#define EIGEN_UNROLLING_LIMIT 100 #define EIGEN_UNROLLING_LIMIT 100
#endif #endif
/** \internal Define the maximal size in Bytes of L2 blocks. /** \internal Define the maximal size in Bytes of blocks fitting in CPU cache.
* The current value is set to generate blocks of 256x256 for float */ * The current value is set to generate blocks of 256x256 for float
#ifndef EIGEN_TUNE_FOR_L2_CACHE_SIZE *
#define EIGEN_TUNE_FOR_L2_CACHE_SIZE (sizeof(float)*256*256) * Typically for a single-threaded application you would set that to 25% of the size of your CPU caches in bytes
*/
#ifndef EIGEN_TUNE_FOR_CPU_CACHE_SIZE
#define EIGEN_TUNE_FOR_CPU_CACHE_SIZE (sizeof(float)*256*256)
#endif
// FIXME this should go away quickly
#ifdef EIGEN_TUNE_FOR_L2_CACHE_SIZE
#error EIGEN_TUNE_FOR_L2_CACHE_SIZE is now called EIGEN_TUNE_FOR_CPU_CACHE_SIZE.
#endif #endif
#define USING_PART_OF_NAMESPACE_EIGEN \ #define USING_PART_OF_NAMESPACE_EIGEN \

View File

@ -115,11 +115,11 @@ template<> inline void* ei_conditional_aligned_malloc<false>(size_t size)
ei_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)"); ei_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)");
#endif #endif
void *void_result = malloc(size); void *result = malloc(size);
#ifdef EIGEN_EXCEPTIONS #ifdef EIGEN_EXCEPTIONS
if(!void_result) throw std::bad_alloc(); if(!result) throw std::bad_alloc();
#endif #endif
return void_result; return result;
} }
/** allocates \a size objects of type T. The returned pointer is guaranteed to have 16 bytes alignment. /** allocates \a size objects of type T. The returned pointer is guaranteed to have 16 bytes alignment.

View File

@ -71,7 +71,8 @@
INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS, INVALID_VECTOR_VECTOR_PRODUCT__IF_YOU_WANTED_A_DOT_OR_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTIONS,
INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION, INVALID_MATRIX_PRODUCT__IF_YOU_WANTED_A_COEFF_WISE_PRODUCT_YOU_MUST_USE_THE_EXPLICIT_FUNCTION,
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY, YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY,
THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES THIS_METHOD_IS_ONLY_FOR_COLUMN_MAJOR_MATRICES,
INVALID_MATRIX_TEMPLATE_PARAMETERS
}; };
}; };

View File

@ -32,13 +32,24 @@ template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int
class ei_unaligned_type<Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> > class ei_unaligned_type<Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> >
: public Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> : public Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols>
{ {
private:
template<typename Other> void _unaligned_copy(const Other& other)
{
if(other.size() == 0) return;
resize(other.rows(), other.cols());
ei_assign_impl<ei_unaligned_type,aligned_base,NoVectorization>::run(*this, other);
}
public: public:
typedef Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> aligned_base; typedef Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> aligned_base;
ei_unaligned_type() : aligned_base(ei_constructor_without_unaligned_array_assert()) {} ei_unaligned_type() : aligned_base(ei_constructor_without_unaligned_array_assert()) {}
ei_unaligned_type(const aligned_base& other) : aligned_base(ei_constructor_without_unaligned_array_assert()) ei_unaligned_type(const aligned_base& other) : aligned_base(ei_constructor_without_unaligned_array_assert())
{ {
resize(other.rows(), other.cols()); _unaligned_copy(other);
ei_assign_impl<ei_unaligned_type,aligned_base,NoVectorization>::run(*this, other); }
ei_unaligned_type(const ei_unaligned_type& other) : aligned_base(ei_constructor_without_unaligned_array_assert())
{
_unaligned_copy(other);
} }
}; };
@ -46,14 +57,23 @@ template<typename _Scalar, int _Dim>
class ei_unaligned_type<Transform<_Scalar,_Dim> > class ei_unaligned_type<Transform<_Scalar,_Dim> >
: public Transform<_Scalar,_Dim> : public Transform<_Scalar,_Dim>
{ {
private:
template<typename Other> void _unaligned_copy(const Other& other)
{
// no resizing here, it's fixed-size anyway
ei_assign_impl<MatrixType,MatrixType,NoVectorization>::run(this->matrix(), other.matrix());
}
public: public:
typedef Transform<_Scalar,_Dim> aligned_base; typedef Transform<_Scalar,_Dim> aligned_base;
typedef typename aligned_base::MatrixType MatrixType; typedef typename aligned_base::MatrixType MatrixType;
ei_unaligned_type() : aligned_base(ei_constructor_without_unaligned_array_assert()) {} ei_unaligned_type() : aligned_base(ei_constructor_without_unaligned_array_assert()) {}
ei_unaligned_type(const aligned_base& other) : aligned_base(ei_constructor_without_unaligned_array_assert()) ei_unaligned_type(const aligned_base& other) : aligned_base(ei_constructor_without_unaligned_array_assert())
{ {
// no resizing here, it's fixed-size anyway _unaligned_copy(other);
ei_assign_impl<MatrixType,MatrixType,NoVectorization>::run(this->matrix(), other.matrix()); }
ei_unaligned_type(const ei_unaligned_type& other) : aligned_base(ei_constructor_without_unaligned_array_assert())
{
_unaligned_copy(other);
} }
}; };
@ -61,14 +81,23 @@ template<typename _Scalar>
class ei_unaligned_type<Quaternion<_Scalar> > class ei_unaligned_type<Quaternion<_Scalar> >
: public Quaternion<_Scalar> : public Quaternion<_Scalar>
{ {
private:
template<typename Other> void _unaligned_copy(const Other& other)
{
// no resizing here, it's fixed-size anyway
ei_assign_impl<Coefficients,Coefficients,NoVectorization>::run(this->coeffs(), other.coeffs());
}
public: public:
typedef Quaternion<_Scalar> aligned_base; typedef Quaternion<_Scalar> aligned_base;
typedef typename aligned_base::Coefficients Coefficients; typedef typename aligned_base::Coefficients Coefficients;
ei_unaligned_type() : aligned_base(ei_constructor_without_unaligned_array_assert()) {} ei_unaligned_type() : aligned_base(ei_constructor_without_unaligned_array_assert()) {}
ei_unaligned_type(const aligned_base& other) : aligned_base(ei_constructor_without_unaligned_array_assert()) ei_unaligned_type(const aligned_base& other) : aligned_base(ei_constructor_without_unaligned_array_assert())
{ {
// no resizing here, it's fixed-size anyway _unaligned_copy(other);
ei_assign_impl<Coefficients,Coefficients,NoVectorization>::run(this->coeffs(), other.coeffs()); }
ei_unaligned_type(const ei_unaligned_type& other) : aligned_base(ei_constructor_without_unaligned_array_assert())
{
_unaligned_copy(other);
} }
}; };

View File

@ -18,7 +18,7 @@
// DOXYGEN_SET_MULTILINE_CPP_IS_BRIEF = NO // DOXYGEN_SET_MULTILINE_CPP_IS_BRIEF = NO
// DOXYGEN_SET_DETAILS_AT_TOP = YES // DOXYGEN_SET_DETAILS_AT_TOP = YES
// DOXYGEN_SET_INHERIT_DOCS = YES // DOXYGEN_SET_INHERIT_DOCS = YES
// DOXYGEN_SET_ALIASES = "only_for_vectors=This is only for vectors (either row-vectors or column-vectors), i.e. matrices which are known at compile-time to have either one row or one column." "array_module=This is defined in the %Array module. \code #include <Eigen/Array> \endcode" "lu_module=This is defined in the %LU module. \code #include <Eigen/LU> \endcode" "cholesky_module=This is defined in the %Cholesky module. \code #include <Eigen/Cholesky> \endcode" "qr_module=This is defined in the %QR module. \code #include <Eigen/QR> \endcode" "svd_module=This is defined in the %SVD module. \code #include <Eigen/SVD> \endcode" "geometry_module=This is defined in the %Geometry module. \code #include <Eigen/Geometry> \endcode" "regression_module=This is defined in the %Regression module. \code #include <Eigen/Regression> \endcode" "addexample=\anchor" "label=\bug" "redstar=<a href='#warningarraymodule' style='color:red;text-decoration: none;'>*</a>" // DOXYGEN_SET_ALIASES = "only_for_vectors=This is only for vectors (either row-vectors or column-vectors), i.e. matrices which are known at compile-time to have either one row or one column." "array_module=This is defined in the %Array module. \code #include <Eigen/Array> \endcode" "lu_module=This is defined in the %LU module. \code #include <Eigen/LU> \endcode" "cholesky_module=This is defined in the %Cholesky module. \code #include <Eigen/Cholesky> \endcode" "qr_module=This is defined in the %QR module. \code #include <Eigen/QR> \endcode" "svd_module=This is defined in the %SVD module. \code #include <Eigen/SVD> \endcode" "geometry_module=This is defined in the %Geometry module. \code #include <Eigen/Geometry> \endcode" "regression_module=This is defined in the %Regression module. \code #include <Eigen/Regression> \endcode" "addexample=\anchor" "label=\bug" "redstar=<a href='#warningarraymodule' style='color:red;text-decoration: none;'>*</a>" "nonstableyet=\warning This class/function is not considered to be part of the stable public API yet. Changes may happen in future releases. See \ref Experimental \"Experimental parts of Eigen\""
// DOXYGEN_SET_DISTRIBUTE_GROUP_DOC = NO // DOXYGEN_SET_DISTRIBUTE_GROUP_DOC = NO
// DOXYGEN_SET_SUBGROUPING = YES // DOXYGEN_SET_SUBGROUPING = YES
// DOXYGEN_SET_TYPEDEF_HIDES_STRUCT = NO // DOXYGEN_SET_TYPEDEF_HIDES_STRUCT = NO

View File

@ -134,10 +134,12 @@ namespace adtl {
\section PreprocessorDirectives Preprocessor directives \section PreprocessorDirectives Preprocessor directives
The value of the following preprocessor tokens can be overwritten by defining them before including any Eigen's headers. You can control some aspects of Eigen by defining the following preprocessor tokens them before including any of Eigen's headers.
- \b EIGEN_NO_DEBUG disables Eigen assertions. Like NDEBUG but only affects Eigen's assertions.
- \b EIGEN_DONT_VECTORIZE disables explicit vectorization when defined. - \b EIGEN_DONT_VECTORIZE disables explicit vectorization when defined.
- \b EIGEN_UNROLLING_LIMIT defines the maximal instruction counts to enable meta unrolling of loops. Set it to zero to disable unrolling. The default is 100. - \b EIGEN_UNROLLING_LIMIT defines the maximal instruction counts to enable meta unrolling of loops. Set it to zero to disable unrolling. The default is 100.
- \b EIGEN_TUNE_FOR_L2_CACHE_SIZE represents the maximal size in Bytes of L2 blocks. Since several blocks have to stay concurently in L2 cache, this value should correspond to at most 1/4 of the size of L2 cache. - \b EIGEN_DEFAULT_TO_ROW_MAJOR the default storage order for matrices becomes row-major instead of column-major.
- \b EIGEN_TUNE_FOR_CPU_CACHE_SIZE represents the maximal size in Bytes of L2 blocks. Since several blocks have to stay concurently in L2 cache, this value should correspond to at most 1/4 of the size of L2 cache.
- \b EIGEN_NO_STATIC_ASSERT replaces compile time static assertions by runtime assertions - \b EIGEN_NO_STATIC_ASSERT replaces compile time static assertions by runtime assertions
- \b EIGEN_MATRIXBASE_PLUGIN see \ref ExtendingMatrixBase - \b EIGEN_MATRIXBASE_PLUGIN see \ref ExtendingMatrixBase

View File

@ -214,13 +214,13 @@ Matrix3f mf = md.cast<float>();
\endcode \endcode
Note that casting to the same scalar type in an expression is free. Note that casting to the same scalar type in an expression is free.
The sizes of a resizable destination matrix can be changed automatically using the Matrix::set() function: The destination matrix is automatically resized in any assignment:
\code \code
MatrixXf res(10,10); MatrixXf res(10,10);
Matrix3f a, b; Matrix3f a, b;
res = a + b; // does not work (no automatic resizing) res = a+b; // OK: res is resized to size 3x3
res.set(a+b); // OK
\endcode \endcode
Of course, fixed-size matrices can't be resized.
\subsection TutorialMap Map \subsection TutorialMap Map

View File

@ -95,19 +95,9 @@ template<typename MatrixType> void basicStuff(const MatrixType& m)
VERIFY_RAISES_ASSERT(m1 = (m2.block(0,0, rows-1, cols-1))); VERIFY_RAISES_ASSERT(m1 = (m2.block(0,0, rows-1, cols-1)));
} }
// test set VERIFY_IS_APPROX(m3 = m1,m1);
{ MatrixType m4;
VERIFY_IS_APPROX(m3.set(m1),m1); VERIFY_IS_APPROX(m4 = m1,m1);
MatrixType m4, m5;
VERIFY_IS_APPROX(m4.set(m1),m1);
if (MatrixType::RowsAtCompileTime==Dynamic && MatrixType::ColsAtCompileTime==Dynamic)
{
MatrixType m6(rows+1,cols);
VERIFY_RAISES_ASSERT(m5 = m1);
VERIFY_RAISES_ASSERT(m3 = m5);
VERIFY_RAISES_ASSERT(m3 = m6);
}
}
// test swap // test swap
m3 = m1; m3 = m1;

View File

@ -22,6 +22,7 @@
// License and a copy of the GNU General Public License along with // License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>. // Eigen. If not, see <http://www.gnu.org/licenses/>.
#define EIGEN_NO_ASSERTION_CHECKING
#include "main.h" #include "main.h"
#include <Eigen/Cholesky> #include <Eigen/Cholesky>
#include <Eigen/LU> #include <Eigen/LU>

View File

@ -47,7 +47,7 @@ void check_qtvector_matrix(const MatrixType& m)
} }
v.resize(21); v.resize(21);
v[20].set(x); v[20] = x;
VERIFY_IS_APPROX(v[20], x); VERIFY_IS_APPROX(v[20], x);
v.fill(y,22); v.fill(y,22);
//v.resize(22); //v.resize(22);
@ -97,7 +97,7 @@ void check_qtvector_transform(const TransformType&)
TransformType* ref = &w[0]; TransformType* ref = &w[0];
for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i) for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)
v.push_back(w[i%w.size()]); v.push_back(w[i%w.size()]);
for(unsigned int i=23; i<v.size(); ++i) for(unsigned int i=23; int(i)<v.size(); ++i)
{ {
VERIFY(v[i].matrix()==w[(i-23)%w.size()].matrix()); VERIFY(v[i].matrix()==w[(i-23)%w.size()].matrix());
} }
@ -133,7 +133,7 @@ void check_qtvector_quaternion(const QuaternionType&)
QuaternionType* ref = &w[0]; QuaternionType* ref = &w[0];
for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i) for(int i=0; i<30 || ((ref==&w[0]) && i<300); ++i)
v.push_back(w[i%w.size()]); v.push_back(w[i%w.size()]);
for(unsigned int i=23; i<v.size(); ++i) for(unsigned int i=23; int(i)<v.size(); ++i)
{ {
VERIFY(v[i].coeffs()==w[(i-23)%w.size()].coeffs()); VERIFY(v[i].coeffs()==w[(i-23)%w.size()].coeffs());
} }

View File

@ -43,7 +43,7 @@ void check_stdvector_matrix(const MatrixType& m)
} }
v.resize(21); v.resize(21);
v[20].set(x); v[20] = x;
VERIFY_IS_APPROX(v[20], x); VERIFY_IS_APPROX(v[20], x);
v.resize(22,y); v.resize(22,y);
VERIFY_IS_APPROX(v[21], y); VERIFY_IS_APPROX(v[21], y);