mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Compare commits
13 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
1eec8488a2 | ||
|
|
9dcde48980 | ||
|
|
215ce5bdc1 | ||
|
|
10f9478f35 | ||
|
|
9c8a653c0b | ||
|
|
8551505436 | ||
|
|
1b88042880 | ||
|
|
7db3f2f72a | ||
|
|
dae7f065d4 | ||
|
|
ab660a4d29 | ||
|
|
986f301233 | ||
|
|
d316d4f393 | ||
|
|
e1ee876daa |
@@ -1,5 +1,5 @@
|
|||||||
project(Eigen)
|
project(Eigen)
|
||||||
set(EIGEN_VERSION_NUMBER "2.0-beta4")
|
set(EIGEN_VERSION_NUMBER "2.0-beta5")
|
||||||
|
|
||||||
#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.
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
set(Eigen_HEADERS Core LU Cholesky QR Geometry Sparse Array SVD Regression)
|
set(Eigen_HEADERS Core LU Cholesky QR Geometry Sparse Array SVD Regression LeastSquares)
|
||||||
|
|
||||||
if(EIGEN_BUILD_LIB)
|
if(EIGEN_BUILD_LIB)
|
||||||
set(Eigen_SRCS
|
set(Eigen_SRCS
|
||||||
|
|||||||
@@ -172,6 +172,8 @@ template<typename ExpressionType, int Direction> class PartialRedux
|
|||||||
> Type;
|
> Type;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef typename ExpressionType::PlainMatrixType CrossReturnType;
|
||||||
|
|
||||||
inline PartialRedux(const ExpressionType& matrix) : m_matrix(matrix) {}
|
inline PartialRedux(const ExpressionType& matrix) : m_matrix(matrix) {}
|
||||||
|
|
||||||
/** \internal */
|
/** \internal */
|
||||||
@@ -245,6 +247,32 @@ template<typename ExpressionType, int Direction> class PartialRedux
|
|||||||
const typename ReturnType<ei_member_any>::Type any() const
|
const typename ReturnType<ei_member_any>::Type any() const
|
||||||
{ return _expression(); }
|
{ return _expression(); }
|
||||||
|
|
||||||
|
/** \returns a 3x3 matrix expression of the cross product
|
||||||
|
* of each column or row of the referenced expression with the \a other vector.
|
||||||
|
*
|
||||||
|
* \geometry_module
|
||||||
|
*
|
||||||
|
* \sa MatrixBase::cross() */
|
||||||
|
template<typename OtherDerived>
|
||||||
|
const CrossReturnType cross(const MatrixBase<OtherDerived>& other) const
|
||||||
|
{
|
||||||
|
EIGEN_STATIC_ASSERT_MATRIX_SPECIFIC_SIZE(CrossReturnType,3,3)
|
||||||
|
EIGEN_STATIC_ASSERT_VECTOR_SPECIFIC_SIZE(OtherDerived,3)
|
||||||
|
EIGEN_STATIC_ASSERT((ei_is_same_type<Scalar, typename OtherDerived::Scalar>::ret),
|
||||||
|
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||||
|
|
||||||
|
if(Direction==Vertical)
|
||||||
|
return (CrossReturnType()
|
||||||
|
<< _expression().col(0).cross(other),
|
||||||
|
_expression().col(1).cross(other),
|
||||||
|
_expression().col(2).cross(other)).finished();
|
||||||
|
else
|
||||||
|
return (CrossReturnType()
|
||||||
|
<< _expression().row(0).cross(other),
|
||||||
|
_expression().row(1).cross(other),
|
||||||
|
_expression().row(2).cross(other)).finished();
|
||||||
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ExpressionTypeNested m_matrix;
|
ExpressionTypeNested m_matrix;
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -306,7 +306,7 @@ inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real MatrixBase<
|
|||||||
*
|
*
|
||||||
* \only_for_vectors
|
* \only_for_vectors
|
||||||
*
|
*
|
||||||
* \sa dot(), normSquared()
|
* \sa dot(), squaredNorm()
|
||||||
*/
|
*/
|
||||||
template<typename Derived>
|
template<typename Derived>
|
||||||
inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
|
inline typename NumTraits<typename ei_traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
|
||||||
|
|||||||
@@ -117,17 +117,9 @@ struct ei_traits<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
template<typename T, int Rows, int Cols, int Options,
|
|
||||||
bool NeedsToAlign = ((Options&Matrix_AutoAlign) == Matrix_AutoAlign) && Rows!=Dynamic && Cols!=Dynamic && ((sizeof(T)*Rows*Cols)%16==0)>
|
|
||||||
struct ei_matrix_with_aligned_operator_new : WithAlignedOperatorNew {};
|
|
||||||
|
|
||||||
template<typename T, int Rows, int Cols, int Options>
|
|
||||||
struct ei_matrix_with_aligned_operator_new<T, Rows, Cols, Options, false> {};
|
|
||||||
|
|
||||||
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
|
||||||
class Matrix
|
class Matrix
|
||||||
: public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
|
: public MatrixBase<Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols> >
|
||||||
, public ei_matrix_with_aligned_operator_new<_Scalar, _Rows, _Cols, _Options>
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix)
|
EIGEN_GENERIC_PUBLIC_INTERFACE(Matrix)
|
||||||
@@ -140,6 +132,33 @@ class Matrix
|
|||||||
protected:
|
protected:
|
||||||
ei_matrix_storage<Scalar, MaxSizeAtCompileTime, RowsAtCompileTime, ColsAtCompileTime, Options> m_storage;
|
ei_matrix_storage<Scalar, MaxSizeAtCompileTime, RowsAtCompileTime, ColsAtCompileTime, Options> m_storage;
|
||||||
|
|
||||||
|
public:
|
||||||
|
enum { NeedsToAlign = (Options&Matrix_AutoAlign) == Matrix_AutoAlign
|
||||||
|
&& SizeAtCompileTime!=Dynamic && ((sizeof(Scalar)*SizeAtCompileTime)%16)==0 };
|
||||||
|
typedef typename ei_meta_if<NeedsToAlign, ei_byte_forcing_aligned_malloc, char>::ret ByteAlignedAsNeeded;
|
||||||
|
void *operator new(size_t size) throw()
|
||||||
|
{
|
||||||
|
return ei_aligned_malloc<ByteAlignedAsNeeded>(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *operator new(size_t, void *ptr) throw()
|
||||||
|
{
|
||||||
|
return static_cast<void*>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *operator new[](size_t size) throw()
|
||||||
|
{
|
||||||
|
return ei_aligned_malloc<ByteAlignedAsNeeded>(size);
|
||||||
|
}
|
||||||
|
|
||||||
|
void *operator new[](size_t, void *ptr) throw()
|
||||||
|
{
|
||||||
|
return static_cast<void*>(ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
void operator delete(void * ptr) { ei_aligned_free(static_cast<ByteAlignedAsNeeded *>(ptr), 0); }
|
||||||
|
void operator delete[](void * ptr) { ei_aligned_free(static_cast<ByteAlignedAsNeeded *>(ptr), 0); }
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
EIGEN_STRONG_INLINE int rows() const { return m_storage.rows(); }
|
EIGEN_STRONG_INLINE int rows() const { return m_storage.rows(); }
|
||||||
|
|||||||
@@ -56,6 +56,8 @@ inline T* ei_aligned_malloc(size_t size)
|
|||||||
#else
|
#else
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
void_result = _aligned_malloc(size*sizeof(T), 16);
|
void_result = _aligned_malloc(size*sizeof(T), 16);
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
void_result = malloc(size*sizeof(T)); // Apple's malloc() already returns aligned ptrs
|
||||||
#else
|
#else
|
||||||
void_result = _mm_malloc(size*sizeof(T), 16);
|
void_result = _mm_malloc(size*sizeof(T), 16);
|
||||||
#endif
|
#endif
|
||||||
@@ -71,7 +73,7 @@ inline T* ei_aligned_malloc(size_t size)
|
|||||||
// and this type has a custom operator new, then we want to honor this operator new!
|
// and this type has a custom operator new, then we want to honor this operator new!
|
||||||
// so when we use C functions to allocate memory, we must be careful to call manually the constructor using
|
// so when we use C functions to allocate memory, we must be careful to call manually the constructor using
|
||||||
// the special placement-new syntax.
|
// the special placement-new syntax.
|
||||||
return new(void_result) T[size];
|
return new(void_result) T[size];
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
return new T[size]; // here we really want a new, not a malloc. Justification: if the user uses Eigen on
|
return new T[size]; // here we really want a new, not a malloc. Justification: if the user uses Eigen on
|
||||||
@@ -95,6 +97,8 @@ inline void ei_aligned_free(T* ptr, size_t size)
|
|||||||
while(size) ptr[--size].~T();
|
while(size) ptr[--size].~T();
|
||||||
#if defined(__linux)
|
#if defined(__linux)
|
||||||
free(ptr);
|
free(ptr);
|
||||||
|
#elif defined(__APPLE__)
|
||||||
|
free(ptr);
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
_aligned_free(ptr);
|
_aligned_free(ptr);
|
||||||
#else
|
#else
|
||||||
@@ -169,7 +173,7 @@ inline static int ei_alignmentOffset(const Scalar* ptr, int maxOffset)
|
|||||||
* overloading the operator new to return aligned data when the vectorization is enabled.
|
* overloading the operator new to return aligned data when the vectorization is enabled.
|
||||||
* Here is a similar safe example:
|
* Here is a similar safe example:
|
||||||
* \code
|
* \code
|
||||||
* struct Foo : WithAlignedOperatorNew {
|
* struct Foo : public WithAlignedOperatorNew {
|
||||||
* char dummy;
|
* char dummy;
|
||||||
* Vector4f some_vector;
|
* Vector4f some_vector;
|
||||||
* };
|
* };
|
||||||
@@ -197,7 +201,7 @@ struct WithAlignedOperatorNew
|
|||||||
|
|
||||||
template<typename T, int SizeAtCompileTime,
|
template<typename T, int SizeAtCompileTime,
|
||||||
bool NeedsToAlign = (SizeAtCompileTime!=Dynamic) && ((sizeof(T)*SizeAtCompileTime)%16==0)>
|
bool NeedsToAlign = (SizeAtCompileTime!=Dynamic) && ((sizeof(T)*SizeAtCompileTime)%16==0)>
|
||||||
struct ei_with_aligned_operator_new : WithAlignedOperatorNew {};
|
struct ei_with_aligned_operator_new : public WithAlignedOperatorNew {};
|
||||||
|
|
||||||
template<typename T, int SizeAtCompileTime>
|
template<typename T, int SizeAtCompileTime>
|
||||||
struct ei_with_aligned_operator_new<T,SizeAtCompileTime,false> {};
|
struct ei_with_aligned_operator_new<T,SizeAtCompileTime,false> {};
|
||||||
|
|||||||
@@ -39,9 +39,7 @@
|
|||||||
*/
|
*/
|
||||||
template <typename _Scalar, int _AmbientDim>
|
template <typename _Scalar, int _AmbientDim>
|
||||||
class AlignedBox
|
class AlignedBox
|
||||||
#ifdef EIGEN_VECTORIZE
|
|
||||||
: public ei_with_aligned_operator_new<_Scalar,_AmbientDim==Dynamic ? Dynamic : _AmbientDim+1>
|
: public ei_with_aligned_operator_new<_Scalar,_AmbientDim==Dynamic ? Dynamic : _AmbientDim+1>
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -59,7 +57,7 @@ public:
|
|||||||
{ setNull(); }
|
{ setNull(); }
|
||||||
|
|
||||||
/** Constructs a box with extremities \a _min and \a _max. */
|
/** Constructs a box with extremities \a _min and \a _max. */
|
||||||
inline AlignedBox(const VectorType& _min, const VectorType _max) : m_min(_min), m_max(_max) {}
|
inline AlignedBox(const VectorType& _min, const VectorType& _max) : m_min(_min), m_max(_max) {}
|
||||||
|
|
||||||
/** Constructs a box containing a single point \a p. */
|
/** Constructs a box containing a single point \a p. */
|
||||||
inline explicit AlignedBox(const VectorType& p) : m_min(p), m_max(p) {}
|
inline explicit AlignedBox(const VectorType& p) : m_min(p), m_max(p) {}
|
||||||
|
|||||||
@@ -45,9 +45,7 @@
|
|||||||
*/
|
*/
|
||||||
template <typename _Scalar, int _AmbientDim>
|
template <typename _Scalar, int _AmbientDim>
|
||||||
class Hyperplane
|
class Hyperplane
|
||||||
#ifdef EIGEN_VECTORIZE
|
|
||||||
: public ei_with_aligned_operator_new<_Scalar,_AmbientDim==Dynamic ? Dynamic : _AmbientDim+1>
|
: public ei_with_aligned_operator_new<_Scalar,_AmbientDim==Dynamic ? Dynamic : _AmbientDim+1>
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@@ -41,9 +41,7 @@
|
|||||||
*/
|
*/
|
||||||
template <typename _Scalar, int _AmbientDim>
|
template <typename _Scalar, int _AmbientDim>
|
||||||
class ParametrizedLine
|
class ParametrizedLine
|
||||||
#ifdef EIGEN_VECTORIZE
|
|
||||||
: public ei_with_aligned_operator_new<_Scalar,_AmbientDim>
|
: public ei_with_aligned_operator_new<_Scalar,_AmbientDim>
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
|
|||||||
@@ -59,9 +59,7 @@ template<typename _Scalar> struct ei_traits<Quaternion<_Scalar> >
|
|||||||
|
|
||||||
template<typename _Scalar>
|
template<typename _Scalar>
|
||||||
class Quaternion : public RotationBase<Quaternion<_Scalar>,3>
|
class Quaternion : public RotationBase<Quaternion<_Scalar>,3>
|
||||||
#ifdef EIGEN_VECTORIZE
|
|
||||||
, public ei_with_aligned_operator_new<_Scalar,4>
|
, public ei_with_aligned_operator_new<_Scalar,4>
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
typedef RotationBase<Quaternion<_Scalar>,3> Base;
|
typedef RotationBase<Quaternion<_Scalar>,3> Base;
|
||||||
typedef Matrix<_Scalar, 4, 1> Coefficients;
|
typedef Matrix<_Scalar, 4, 1> Coefficients;
|
||||||
|
|||||||
@@ -41,9 +41,7 @@
|
|||||||
*/
|
*/
|
||||||
template<typename _Scalar, int _Dim>
|
template<typename _Scalar, int _Dim>
|
||||||
class Scaling
|
class Scaling
|
||||||
#ifdef EIGEN_VECTORIZE
|
|
||||||
: public ei_with_aligned_operator_new<_Scalar,_Dim>
|
: public ei_with_aligned_operator_new<_Scalar,_Dim>
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** dimension of the space */
|
/** dimension of the space */
|
||||||
|
|||||||
@@ -61,9 +61,7 @@ struct ei_transform_product_impl;
|
|||||||
*/
|
*/
|
||||||
template<typename _Scalar, int _Dim>
|
template<typename _Scalar, int _Dim>
|
||||||
class Transform
|
class Transform
|
||||||
#ifdef EIGEN_VECTORIZE
|
|
||||||
: public ei_with_aligned_operator_new<_Scalar,_Dim==Dynamic ? Dynamic : (_Dim+1)*(_Dim+1)>
|
: public ei_with_aligned_operator_new<_Scalar,_Dim==Dynamic ? Dynamic : (_Dim+1)*(_Dim+1)>
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
||||||
@@ -108,7 +106,7 @@ public:
|
|||||||
inline Transform& operator=(const Transform& other)
|
inline Transform& operator=(const Transform& other)
|
||||||
{ m_matrix = other.m_matrix; return *this; }
|
{ m_matrix = other.m_matrix; return *this; }
|
||||||
|
|
||||||
template<typename OtherDerived, bool select = OtherDerived::RowsAtCompileTime == Dim>
|
template<typename OtherDerived, bool BigMatrix> // MSVC 2005 will commit suicide if BigMatrix has a default value
|
||||||
struct construct_from_matrix
|
struct construct_from_matrix
|
||||||
{
|
{
|
||||||
static inline void run(Transform *transform, const MatrixBase<OtherDerived>& other)
|
static inline void run(Transform *transform, const MatrixBase<OtherDerived>& other)
|
||||||
@@ -132,7 +130,7 @@ public:
|
|||||||
template<typename OtherDerived>
|
template<typename OtherDerived>
|
||||||
inline explicit Transform(const MatrixBase<OtherDerived>& other)
|
inline explicit Transform(const MatrixBase<OtherDerived>& other)
|
||||||
{
|
{
|
||||||
construct_from_matrix<OtherDerived>::run(this, other);
|
construct_from_matrix<OtherDerived, int(OtherDerived::RowsAtCompileTime) == Dim>::run(this, other);
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Set \c *this from a (Dim+1)^2 matrix. */
|
/** Set \c *this from a (Dim+1)^2 matrix. */
|
||||||
|
|||||||
@@ -41,9 +41,7 @@
|
|||||||
*/
|
*/
|
||||||
template<typename _Scalar, int _Dim>
|
template<typename _Scalar, int _Dim>
|
||||||
class Translation
|
class Translation
|
||||||
#ifdef EIGEN_VECTORIZE
|
|
||||||
: public ei_with_aligned_operator_new<_Scalar,_Dim>
|
: public ei_with_aligned_operator_new<_Scalar,_Dim>
|
||||||
#endif
|
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/** dimension of the space */
|
/** dimension of the space */
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ namespace Eigen {
|
|||||||
If you saw the assertion failure that links to this page, then you probably have done something like that in your code:
|
If you saw the assertion failure that links to this page, then you probably have done something like that in your code:
|
||||||
|
|
||||||
\code
|
\code
|
||||||
struct Foo
|
class Foo
|
||||||
{
|
{
|
||||||
...
|
...
|
||||||
Eigen::Vector2d v;
|
Eigen::Vector2d v;
|
||||||
@@ -28,7 +28,7 @@ struct Foo
|
|||||||
Foo *foo = new Foo;
|
Foo *foo = new Foo;
|
||||||
\endcode
|
\endcode
|
||||||
|
|
||||||
In other words: you have probably in your code a structure that has as a member a vectorizable fixed-size Eigen object, and you then dynamically allocated an object of that structure.
|
In other words: you have probably in your code a class that has as a member a vectorizable fixed-size Eigen object, and you then dynamically allocated an object of that class.
|
||||||
|
|
||||||
By "vectorizable fixed-size Eigen object" we mean an Eigen matrix or vector of fixed size, and whose size is a multiple of 128 bits. Examples include:
|
By "vectorizable fixed-size Eigen object" we mean an Eigen matrix or vector of fixed size, and whose size is a multiple of 128 bits. Examples include:
|
||||||
\li Eigen::Vector2d
|
\li Eigen::Vector2d
|
||||||
@@ -43,10 +43,10 @@ By "vectorizable fixed-size Eigen object" we mean an Eigen matrix or vector of f
|
|||||||
|
|
||||||
\section how How to fix this bug?
|
\section how How to fix this bug?
|
||||||
|
|
||||||
Very easy, you just need to let your struct Foo inherit Eigen::WithAlignedOperatorNew, like this:
|
Very easy, you just need to let your class Foo publicly inherit Eigen::WithAlignedOperatorNew, like this:
|
||||||
|
|
||||||
\code
|
\code
|
||||||
struct Foo : Eigen::WithAlignedOperatorNew
|
class Foo : public Eigen::WithAlignedOperatorNew
|
||||||
{
|
{
|
||||||
...
|
...
|
||||||
Eigen::Vector2d v;
|
Eigen::Vector2d v;
|
||||||
@@ -65,7 +65,7 @@ With this, you should be out of trouble.
|
|||||||
OK let's say that your code looks like this:
|
OK let's say that your code looks like this:
|
||||||
|
|
||||||
\code
|
\code
|
||||||
struct Foo
|
class Foo
|
||||||
{
|
{
|
||||||
...
|
...
|
||||||
Eigen::Vector2d v;
|
Eigen::Vector2d v;
|
||||||
@@ -85,18 +85,18 @@ For this reason, Eigen takes care by itself to require 128-bit alignment for Eig
|
|||||||
|
|
||||||
Thus, normally, you don't have to worry about anything, Eigen handles alignment for you...
|
Thus, normally, you don't have to worry about anything, Eigen handles alignment for you...
|
||||||
|
|
||||||
... except in one case. When you have a struct Foo like above, and you dynamically allocate a new Foo as above, then, since Foo doesn't have aligned "operator new", the returned pointer foo is not necessarily 128-bit aligned.
|
... except in one case. When you have a class Foo like above, and you dynamically allocate a new Foo as above, then, since Foo doesn't have aligned "operator new", the returned pointer foo is not necessarily 128-bit aligned.
|
||||||
|
|
||||||
The alignment attribute of the member v is then relative to the start of the struct, foo. If the foo pointer wasn't aligned, then foo->v won't be aligned either!
|
The alignment attribute of the member v is then relative to the start of the class, foo. If the foo pointer wasn't aligned, then foo->v won't be aligned either!
|
||||||
|
|
||||||
The solution is to let struct Foo have an aligned "operator new", as we showed in the previous section.
|
The solution is to let class Foo have an aligned "operator new", as we showed in the previous section.
|
||||||
|
|
||||||
\section movetotop Should I then put all the members of Eigen types at the beginning of my struct?
|
\section movetotop Should I then put all the members of Eigen types at the beginning of my class?
|
||||||
|
|
||||||
No, that's not needed. Since Eigen takes care of declaring 128-bit alignment, all members that need it are automatically 128-bit aligned relatively to the struct. So when you have code like
|
No, that's not needed. Since Eigen takes care of declaring 128-bit alignment, all members that need it are automatically 128-bit aligned relatively to the class. So when you have code like
|
||||||
|
|
||||||
\code
|
\code
|
||||||
struct Foo : Eigen::WithAlignedOperatorNew
|
class Foo : public Eigen::WithAlignedOperatorNew
|
||||||
{
|
{
|
||||||
double x;
|
double x;
|
||||||
Eigen::Vector2d v;
|
Eigen::Vector2d v;
|
||||||
@@ -106,7 +106,7 @@ struct Foo : Eigen::WithAlignedOperatorNew
|
|||||||
it will work just fine. You do \b not need to rewrite it as
|
it will work just fine. You do \b not need to rewrite it as
|
||||||
|
|
||||||
\code
|
\code
|
||||||
struct Foo : Eigen::WithAlignedOperatorNew
|
class Foo : public Eigen::WithAlignedOperatorNew
|
||||||
{
|
{
|
||||||
Eigen::Vector2d v;
|
Eigen::Vector2d v;
|
||||||
double x;
|
double x;
|
||||||
|
|||||||
@@ -59,7 +59,7 @@ template<typename Scalar> void geometry(void)
|
|||||||
Vector2 u0 = Vector2::Random();
|
Vector2 u0 = Vector2::Random();
|
||||||
Matrix3 matrot1;
|
Matrix3 matrot1;
|
||||||
|
|
||||||
Scalar a = ei_random<Scalar>(-M_PI, M_PI);
|
Scalar a = ei_random<Scalar>(-Scalar(M_PI), Scalar(M_PI));
|
||||||
|
|
||||||
// cross product
|
// cross product
|
||||||
VERIFY_IS_MUCH_SMALLER_THAN(v1.cross(v2).dot(v1), Scalar(1));
|
VERIFY_IS_MUCH_SMALLER_THAN(v1.cross(v2).dot(v1), Scalar(1));
|
||||||
@@ -77,7 +77,7 @@ template<typename Scalar> void geometry(void)
|
|||||||
|
|
||||||
|
|
||||||
VERIFY_IS_APPROX(v0, AngleAxisx(a, v0.normalized()) * v0);
|
VERIFY_IS_APPROX(v0, AngleAxisx(a, v0.normalized()) * v0);
|
||||||
VERIFY_IS_APPROX(-v0, AngleAxisx(M_PI, v0.unitOrthogonal()) * v0);
|
VERIFY_IS_APPROX(-v0, AngleAxisx(Scalar(M_PI), v0.unitOrthogonal()) * v0);
|
||||||
VERIFY_IS_APPROX(ei_cos(a)*v0.squaredNorm(), v0.dot(AngleAxisx(a, v0.unitOrthogonal()) * v0));
|
VERIFY_IS_APPROX(ei_cos(a)*v0.squaredNorm(), v0.dot(AngleAxisx(a, v0.unitOrthogonal()) * v0));
|
||||||
m = AngleAxisx(a, v0.normalized()).toRotationMatrix().adjoint();
|
m = AngleAxisx(a, v0.normalized()).toRotationMatrix().adjoint();
|
||||||
VERIFY_IS_APPROX(Matrix3::Identity(), m * AngleAxisx(a, v0.normalized()));
|
VERIFY_IS_APPROX(Matrix3::Identity(), m * AngleAxisx(a, v0.normalized()));
|
||||||
@@ -88,8 +88,8 @@ template<typename Scalar> void geometry(void)
|
|||||||
|
|
||||||
// angular distance
|
// angular distance
|
||||||
Scalar refangle = ei_abs(AngleAxisx(q1.inverse()*q2).angle());
|
Scalar refangle = ei_abs(AngleAxisx(q1.inverse()*q2).angle());
|
||||||
if (refangle>M_PI)
|
if (refangle>Scalar(M_PI))
|
||||||
refangle = 2.*M_PI - refangle;
|
refangle = 2.*Scalar(M_PI) - refangle;
|
||||||
VERIFY(ei_isApprox(q1.angularDistance(q2), refangle, largeEps));
|
VERIFY(ei_isApprox(q1.angularDistance(q2), refangle, largeEps));
|
||||||
|
|
||||||
// rotation matrix conversion
|
// rotation matrix conversion
|
||||||
@@ -138,7 +138,7 @@ template<typename Scalar> void geometry(void)
|
|||||||
// TODO complete the tests !
|
// TODO complete the tests !
|
||||||
a = 0;
|
a = 0;
|
||||||
while (ei_abs(a)<0.1)
|
while (ei_abs(a)<0.1)
|
||||||
a = ei_random<Scalar>(-0.4*M_PI, 0.4*M_PI);
|
a = ei_random<Scalar>(-0.4*Scalar(M_PI), 0.4*Scalar(M_PI));
|
||||||
q1 = AngleAxisx(a, v0.normalized());
|
q1 = AngleAxisx(a, v0.normalized());
|
||||||
Transform3 t0, t1, t2;
|
Transform3 t0, t1, t2;
|
||||||
t0.setIdentity();
|
t0.setIdentity();
|
||||||
@@ -181,7 +181,14 @@ template<typename Scalar> void geometry(void)
|
|||||||
|
|
||||||
// More transform constructors, operator=, operator*=
|
// More transform constructors, operator=, operator*=
|
||||||
|
|
||||||
Scalar a3 = ei_random<Scalar>(-M_PI, M_PI);
|
Matrix3 mat3 = Matrix3::Random();
|
||||||
|
Matrix4 mat4;
|
||||||
|
mat4 << mat3 , Vector3::Zero() , Vector4::Zero().transpose();
|
||||||
|
Transform3 tmat3(mat3), tmat4(mat4);
|
||||||
|
tmat4.matrix()(3,3) = Scalar(1);
|
||||||
|
VERIFY_IS_APPROX(tmat3.matrix(), tmat4.matrix());
|
||||||
|
|
||||||
|
Scalar a3 = ei_random<Scalar>(-Scalar(M_PI), Scalar(M_PI));
|
||||||
Vector3 v3 = Vector3::Random().normalized();
|
Vector3 v3 = Vector3::Random().normalized();
|
||||||
AngleAxisx aa3(a3, v3);
|
AngleAxisx aa3(a3, v3);
|
||||||
Transform3 t3(aa3);
|
Transform3 t3(aa3);
|
||||||
@@ -388,6 +395,18 @@ template<typename Scalar> void geometry(void)
|
|||||||
VERIFY_EULER(2,0,2, Z,X,Z);
|
VERIFY_EULER(2,0,2, Z,X,Z);
|
||||||
VERIFY_EULER(2,1,0, Z,Y,X);
|
VERIFY_EULER(2,1,0, Z,Y,X);
|
||||||
VERIFY_EULER(2,1,2, Z,Y,Z);
|
VERIFY_EULER(2,1,2, Z,Y,Z);
|
||||||
|
|
||||||
|
// colwise/rowwise cross product
|
||||||
|
mat3.setRandom();
|
||||||
|
Vector3 vec3 = Vector3::Random();
|
||||||
|
Matrix3 mcross;
|
||||||
|
int i = ei_random<int>(0,2);
|
||||||
|
mcross = mat3.colwise().cross(vec3);
|
||||||
|
VERIFY_IS_APPROX(mcross.col(i), mat3.col(i).cross(vec3));
|
||||||
|
mcross = mat3.rowwise().cross(vec3);
|
||||||
|
VERIFY_IS_APPROX(mcross.row(i), mat3.row(i).cross(vec3));
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_geometry()
|
void test_geometry()
|
||||||
|
|||||||
@@ -61,10 +61,10 @@ template<typename Scalar> void packetmath()
|
|||||||
const int PacketSize = ei_packet_traits<Scalar>::size;
|
const int PacketSize = ei_packet_traits<Scalar>::size;
|
||||||
|
|
||||||
const int size = PacketSize*4;
|
const int size = PacketSize*4;
|
||||||
Scalar data1[ei_packet_traits<Scalar>::size*4];
|
EIGEN_ALIGN_128 Scalar data1[ei_packet_traits<Scalar>::size*4];
|
||||||
Scalar data2[ei_packet_traits<Scalar>::size*4];
|
EIGEN_ALIGN_128 Scalar data2[ei_packet_traits<Scalar>::size*4];
|
||||||
Packet packets[PacketSize*2];
|
EIGEN_ALIGN_128 Packet packets[PacketSize*2];
|
||||||
Scalar ref[ei_packet_traits<Scalar>::size*4];
|
EIGEN_ALIGN_128 Scalar ref[ei_packet_traits<Scalar>::size*4];
|
||||||
for (int i=0; i<size; ++i)
|
for (int i=0; i<size; ++i)
|
||||||
{
|
{
|
||||||
data1[i] = ei_random<Scalar>();
|
data1[i] = ei_random<Scalar>();
|
||||||
|
|||||||
Reference in New Issue
Block a user