Compare commits

...

18 Commits
5.0.1 ... 2.0.1

Author SHA1 Message Date
Benoit Jacob
a16d18a632 update version number to 2.0.1 2009-04-14 14:32:00 +00:00
Benoit Jacob
3c3653b9de merge 953719: fix 4x4 inverse 2009-04-14 13:43:21 +00:00
Gael Guennebaud
c15842c374 backporting rev 951682 (compilation fix in aligned allocator) 2009-04-09 21:23:25 +00:00
Benoit Jacob
3c90fc2e64 patch by Hauke Heibel: compilation fix with VS 9 2009-04-09 12:05:36 +00:00
Benoit Jacob
d9c9508a12 backport 947492 -- fix static assertion / patch by Markus Moll 2009-03-31 16:08:06 +00:00
Gael Guennebaud
d6bb34fa5a backporting various bug fixes related to MapBase/Map/Block and new
StdVector workaround because the previous was really too limited. I hope
it is not a too big change for a "stable" branch.
2009-03-24 08:20:43 +00:00
Gael Guennebaud
e5b5ab53b8 backporting bugfix in SliceVectorization 2009-03-07 15:12:42 +00:00
Gael Guennebaud
f2829c1358 backporting rev 918446: fix MSVC internal compilation error 2009-03-06 22:18:26 +00:00
Benoit Jacob
d38504a4c8 backport 921254-921261 to the branch: disable alignment altogether on exotic platforms 2009-02-16 16:29:33 +00:00
Gael Guennebaud
95e4508b04 backporting rev925153 (bugfix in MapBase::coeffRef(int) ) 2009-02-12 15:32:32 +00:00
Benoit Jacob
b064b5e68e forgot to update version number 2009-02-02 16:18:42 +00:00
Benoit Jacob
f7df9f92ff backport 919961 and 920175 2009-02-02 14:26:40 +00:00
Benoit Jacob
d2dcca52a3 backport 920106: BSD's don't have aligned malloc 2009-02-02 13:24:17 +00:00
Gael Guennebaud
7408e923a7 backporting commit 918468 (fix MSVC internal error) 2009-01-29 23:14:51 +00:00
Gael Guennebaud
18ca438a62 backport r917694 (Patch from Frank fixing stupid MSVC internal crash) 2009-01-28 15:18:28 +00:00
Benoit Jacob
d286300362 backport unit-tests fixes 2009-01-27 20:56:47 +00:00
Benoit Jacob
02ba4e2f54 backport compilation fix 2009-01-27 17:46:02 +00:00
Benoit Jacob
2eef21a8d5 branch eigen 2.0 2009-01-27 17:26:44 +00:00
39 changed files with 380 additions and 369 deletions

View File

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

View File

@@ -17,6 +17,9 @@
namespace Eigen {
/** \defgroup Cholesky_Module Cholesky module
*
* \nonstableyet
*
* This module provides two variants of the Cholesky decomposition for selfadjoint (hermitian) matrices.
* Those decompositions are accessible via the following MatrixBase methods:
* - MatrixBase::llt(),

View File

@@ -1,15 +1,133 @@
#ifndef EIGEN_STDVECTOR_MODULE_H
#define EIGEN_STDVECTOR_MODULE_H
#include "Core"
#include <vector>
#if defined(_GLIBCXX_VECTOR) || defined(_VECTOR_)
#error you must include Eigen/StdVector before std::vector
#endif
#ifndef EIGEN_GNUC_AT_LEAST
#ifdef __GNUC__
#define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__>=x && __GNUC_MINOR__>=y) || __GNUC__>x)
#else
#define EIGEN_GNUC_AT_LEAST(x,y) 0
#endif
#endif
#define vector std_vector
#include <vector>
#undef vector
namespace Eigen {
#include "src/StdVector/UnalignedType.h"
} // namespace Eigen
template<typename T> class aligned_allocator;
// meta programming to determine if a class has a given member
struct ei_does_not_have_aligned_operator_new_marker_sizeof {int a[1];};
struct ei_has_aligned_operator_new_marker_sizeof {int a[2];};
template<typename ClassType>
struct ei_has_aligned_operator_new {
template<typename T>
static ei_has_aligned_operator_new_marker_sizeof
test(T const *, typename T::ei_operator_new_marker_type const * = 0);
static ei_does_not_have_aligned_operator_new_marker_sizeof
test(...);
// note that the following indirection is needed for gcc-3.3
enum {ret = sizeof(test(static_cast<ClassType*>(0)))
== sizeof(ei_has_aligned_operator_new_marker_sizeof) };
};
#ifdef _MSC_VER
// sometimes, MSVC detects, at compile time, that the argument x
// in std::vector::resize(size_t s,T x) won't be aligned and generate an error
// even if this function is never called. Whence this little wrapper.
#define _EIGEN_WORKAROUND_MSVC_STD_VECTOR(T) Eigen::ei_workaround_msvc_std_vector<T>
template<typename T> struct ei_workaround_msvc_std_vector : public T
{
inline ei_workaround_msvc_std_vector() : T() {}
inline ei_workaround_msvc_std_vector(const T& other) : T(other) {}
inline operator T& () { return *static_cast<T*>(this); }
inline operator const T& () const { return *static_cast<const T*>(this); }
template<typename OtherT>
inline T& operator=(const OtherT& other)
{ T::operator=(other); return *this; }
inline ei_workaround_msvc_std_vector& operator=(const ei_workaround_msvc_std_vector& other)
{ T::operator=(other); return *this; }
};
#else
#define _EIGEN_WORKAROUND_MSVC_STD_VECTOR(T) T
#endif
}
namespace std {
#include "src/StdVector/StdVector.h"
} // namespace std
#define EIGEN_STD_VECTOR_SPECIALIZATION_BODY \
public: \
typedef T value_type; \
typedef typename vector_base::allocator_type allocator_type; \
typedef typename vector_base::size_type size_type; \
typedef typename vector_base::iterator iterator; \
explicit vector(const allocator_type& __a = allocator_type()) : vector_base(__a) {} \
vector(const vector& c) : vector_base(c) {} \
vector(size_type num, const value_type& val = value_type()) : vector_base(num, val) {} \
vector(iterator start, iterator end) : vector_base(start, end) {} \
vector& operator=(const vector& __x) { \
vector_base::operator=(__x); \
return *this; \
}
template<typename T,
typename AllocT = std::allocator<T>,
bool HasAlignedNew = Eigen::ei_has_aligned_operator_new<T>::ret>
class vector : public std::std_vector<T,AllocT>
{
typedef std_vector<T, AllocT> vector_base;
EIGEN_STD_VECTOR_SPECIALIZATION_BODY
};
template<typename T,typename DummyAlloc>
class vector<T,DummyAlloc,true>
: public std::std_vector<_EIGEN_WORKAROUND_MSVC_STD_VECTOR(T),
Eigen::aligned_allocator<_EIGEN_WORKAROUND_MSVC_STD_VECTOR(T)> >
{
typedef std_vector<_EIGEN_WORKAROUND_MSVC_STD_VECTOR(T),
Eigen::aligned_allocator<_EIGEN_WORKAROUND_MSVC_STD_VECTOR(T)> > vector_base;
EIGEN_STD_VECTOR_SPECIALIZATION_BODY
void resize(size_type __new_size)
{ resize(__new_size, T()); }
#if defined(_VECTOR_)
// workaround MSVC std::vector implementation
void resize(size_type __new_size, const value_type& __x)
{
if (vector_base::size() < __new_size)
vector_base::_Insert_n(vector_base::end(), __new_size - vector_base::size(), __x);
else if (__new_size < vector_base::size())
vector_base::erase(vector_base::begin() + __new_size, vector_base::end());
}
#elif defined(_GLIBCXX_VECTOR) && EIGEN_GNUC_AT_LEAST(4,1)
// workaround GCC std::vector implementation
// Note that before gcc-4.1 we already have: std::vector::resize(size_type,const T&),
// no no need to workaround !
void resize(size_type __new_size, const value_type& __x)
{
if (__new_size < vector_base::size())
vector_base::_M_erase_at_end(this->_M_impl._M_start + __new_size);
else
vector_base::insert(vector_base::end(), __new_size - vector_base::size(), __x);
}
#else
using vector_base::resize;
#endif
};
}
#endif // EIGEN_STDVECTOR_MODULE_H

View File

@@ -7,4 +7,3 @@ ADD_SUBDIRECTORY(Array)
ADD_SUBDIRECTORY(Geometry)
ADD_SUBDIRECTORY(LeastSquares)
ADD_SUBDIRECTORY(Sparse)
ADD_SUBDIRECTORY(StdVector)

View File

@@ -353,7 +353,7 @@ struct ei_assign_impl<Derived1, Derived2, SliceVectorization, NoUnrolling>
const int outerSize = dst.outerSize();
const int alignedStep = (packetSize - dst.stride() % packetSize) & packetAlignedMask;
int alignedStart = ei_assign_traits<Derived1,Derived2>::DstIsAligned ? 0
: ei_alignmentOffset(&dst.coeffRef(0), innerSize);
: ei_alignmentOffset(&dst.coeffRef(0,0), innerSize);
for(int i = 0; i < outerSize; ++i)
{

View File

@@ -61,27 +61,28 @@
*
* \sa MatrixBase::block(int,int,int,int), MatrixBase::block(int,int), class VectorBlock
*/
template<typename MatrixType, int BlockRows, int BlockCols, int _PacketAccess, int _DirectAccessStatus>
struct ei_traits<Block<MatrixType, BlockRows, BlockCols, _PacketAccess, _DirectAccessStatus> >
{
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::Nested MatrixTypeNested;
typedef typename ei_traits<MatrixType>::Scalar Scalar;
typedef typename ei_nested<MatrixType>::type MatrixTypeNested;
typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
enum{
RowsAtCompileTime = MatrixType::RowsAtCompileTime == 1 ? 1 : BlockRows,
ColsAtCompileTime = MatrixType::ColsAtCompileTime == 1 ? 1 : BlockCols,
RowsAtCompileTime = ei_traits<MatrixType>::RowsAtCompileTime == 1 ? 1 : BlockRows,
ColsAtCompileTime = ei_traits<MatrixType>::ColsAtCompileTime == 1 ? 1 : BlockCols,
MaxRowsAtCompileTime = RowsAtCompileTime == 1 ? 1
: (BlockRows==Dynamic ? MatrixType::MaxRowsAtCompileTime : BlockRows),
: (BlockRows==Dynamic ? ei_traits<MatrixType>::MaxRowsAtCompileTime : BlockRows),
MaxColsAtCompileTime = ColsAtCompileTime == 1 ? 1
: (BlockCols==Dynamic ? MatrixType::MaxColsAtCompileTime : BlockCols),
RowMajor = int(MatrixType::Flags)&RowMajorBit,
: (BlockCols==Dynamic ? ei_traits<MatrixType>::MaxColsAtCompileTime : BlockCols),
RowMajor = int(ei_traits<MatrixType>::Flags)&RowMajorBit,
InnerSize = RowMajor ? ColsAtCompileTime : RowsAtCompileTime,
InnerMaxSize = RowMajor ? MaxColsAtCompileTime : MaxRowsAtCompileTime,
MaskPacketAccessBit = (InnerMaxSize == Dynamic || (InnerSize >= ei_packet_traits<Scalar>::size))
? PacketAccessBit : 0,
FlagsLinearAccessBit = (RowsAtCompileTime == 1 || ColsAtCompileTime == 1) ? LinearAccessBit : 0,
Flags = (MatrixType::Flags & (HereditaryBits | MaskPacketAccessBit | DirectAccessBit)) | FlagsLinearAccessBit,
CoeffReadCost = MatrixType::CoeffReadCost,
Flags = (ei_traits<MatrixType>::Flags & (HereditaryBits | MaskPacketAccessBit | DirectAccessBit)) | FlagsLinearAccessBit,
CoeffReadCost = ei_traits<MatrixType>::CoeffReadCost,
PacketAccess = _PacketAccess
};
typedef typename ei_meta_if<int(PacketAccess)==ForceAligned,
@@ -122,7 +123,7 @@ template<typename MatrixType, int BlockRows, int BlockCols, int PacketAccess, in
: m_matrix(matrix), m_startRow(startRow), m_startCol(startCol),
m_blockRows(matrix.rows()), m_blockCols(matrix.cols())
{
EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && RowsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
EIGEN_STATIC_ASSERT(RowsAtCompileTime!=Dynamic && ColsAtCompileTime!=Dynamic,THIS_METHOD_IS_ONLY_FOR_FIXED_SIZE)
ei_assert(startRow >= 0 && BlockRows >= 1 && startRow + BlockRows <= matrix.rows()
&& startCol >= 0 && BlockCols >= 1 && startCol + BlockCols <= matrix.cols());
}
@@ -221,15 +222,13 @@ class Block<MatrixType,BlockRows,BlockCols,PacketAccess,HasDirectAccess>
class InnerIterator;
typedef typename ei_traits<Block>::AlignedDerivedType AlignedDerivedType;
friend class Block<MatrixType,BlockRows,BlockCols,AsRequested,HasDirectAccess>;
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Block)
AlignedDerivedType forceAligned()
AlignedDerivedType _convertToForceAligned()
{
if (PacketAccess==ForceAligned)
return *this;
else
return Block<MatrixType,BlockRows,BlockCols,ForceAligned,HasDirectAccess>
return Block<MatrixType,BlockRows,BlockCols,ForceAligned,HasDirectAccess>
(m_matrix, Base::m_data, Base::m_rows.value(), Base::m_cols.value());
}
@@ -454,7 +453,7 @@ MatrixBase<Derived>::end(int size) const
* \only_for_vectors
*
* The template parameter \a Size is the number of coefficients in the block
*
*
* \param start the index of the first element of the sub-vector
*
* Example: \include MatrixBase_template_int_segment.cpp

View File

@@ -433,8 +433,13 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
{
/* explicit vectorization */
// process initial unaligned coeffs
for (int j=0; j<alignedStart; ++j)
res[j] += ei_pfirst(ptmp0)*lhs0[j] + ei_pfirst(ptmp1)*lhs1[j] + ei_pfirst(ptmp2)*lhs2[j] + ei_pfirst(ptmp3)*lhs3[j];
for (int j=0; j<alignedStart; ++j) {
Scalar s = ei_pfirst(ptmp0)*lhs0[j];
s += ei_pfirst(ptmp1)*lhs1[j];
s += ei_pfirst(ptmp2)*lhs2[j];
s += ei_pfirst(ptmp3)*lhs3[j];
res[j] += s;
}
if (alignedSize>alignedStart)
{

View File

@@ -66,12 +66,9 @@ template<typename MatrixType, int PacketAccess> class Map
inline int stride() const { return this->innerSize(); }
AlignedDerivedType forceAligned()
AlignedDerivedType _convertToForceAligned()
{
if (PacketAccess==ForceAligned)
return *this;
else
return Map<MatrixType,ForceAligned>(Base::m_data, Base::m_rows.value(), Base::m_cols.value());
return Map<MatrixType,ForceAligned>(Base::m_data, Base::m_rows.value(), Base::m_cols.value());
}
inline Map(const Scalar* data) : Base(data) {}

View File

@@ -65,9 +65,20 @@ template<typename Derived> class MapBase
inline int stride() const { return derived().stride(); }
inline const Scalar* data() const { return m_data; }
template<bool IsForceAligned,typename Dummy> struct force_aligned_impl {
AlignedDerivedType static run(MapBase& a) { return a.derived(); }
};
template<typename Dummy> struct force_aligned_impl<false,Dummy> {
AlignedDerivedType static run(MapBase& a) { return a.derived()._convertToForceAligned(); }
};
/** \returns an expression equivalent to \c *this but having the \c PacketAccess constant
* set to \c ForceAligned. Must be reimplemented by the derived class. */
AlignedDerivedType forceAligned() { return derived().forceAligned(); }
AlignedDerivedType forceAligned()
{
return force_aligned_impl<int(PacketAccess)==int(ForceAligned),Derived>::run(*this);
}
inline const Scalar& coeff(int row, int col) const
{
@@ -96,7 +107,11 @@ template<typename Derived> class MapBase
inline Scalar& coeffRef(int index)
{
return *const_cast<Scalar*>(m_data + index);
ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit));
if ( ((RowsAtCompileTime == 1) == IsRowMajor) )
return const_cast<Scalar*>(m_data)[index];
else
return const_cast<Scalar*>(m_data)[index*stride()];
}
template<int LoadMode>
@@ -150,7 +165,20 @@ template<typename Derived> class MapBase
|| ( rows > 0 && (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
&& cols > 0 && (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols)));
}
Derived& operator=(const MapBase& other)
{
return Base::operator=(other);
}
template<typename OtherDerived>
Derived& operator=(const MatrixBase<OtherDerived>& other)
{
return Base::operator=(other);
}
using Base::operator*=;
template<typename OtherDerived>
Derived& operator+=(const MatrixBase<OtherDerived>& other)
{ return derived() = forceAligned() + other; }

View File

@@ -226,7 +226,6 @@ class Matrix
*/
inline void resize(int rows, int cols)
{
ei_assert(rows > 0 && cols > 0 && "a matrix cannot be resized to 0 size");
ei_assert((MaxRowsAtCompileTime == Dynamic || MaxRowsAtCompileTime >= rows)
&& (RowsAtCompileTime == Dynamic || RowsAtCompileTime == rows)
&& (MaxColsAtCompileTime == Dynamic || MaxColsAtCompileTime >= cols)
@@ -240,7 +239,6 @@ class Matrix
*/
inline void resize(int size)
{
ei_assert(size>0 && "a vector cannot be resized to 0 length");
EIGEN_STATIC_ASSERT_VECTOR_ONLY(Matrix)
if(RowsAtCompileTime == 1)
m_storage.resize(size, 1, size);
@@ -508,15 +506,15 @@ class Matrix
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)
}
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

View File

@@ -2,7 +2,7 @@
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// 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
@@ -41,7 +41,7 @@ template <typename T, int Size, int MatrixOptions,
{
#ifndef EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
ei_assert((reinterpret_cast<size_t>(array) & 0xf) == 0
&& "this assertion is explained here: http://eigen.tuxfamily.org/api/UnalignedArrayAssert.html **** READ THIS WEB PAGE !!! ****");
&& "this assertion is explained here: http://eigen.tuxfamily.org/dox/UnalignedArrayAssert.html **** READ THIS WEB PAGE !!! ****");
#endif
}
@@ -176,7 +176,10 @@ template<typename T, int _Options> class ei_matrix_storage<T, Dynamic, Dynamic,
if(size != m_rows*m_cols)
{
ei_aligned_delete(m_data, m_rows*m_cols);
m_data = ei_aligned_new<T>(size);
if (size)
m_data = ei_aligned_new<T>(size);
else
m_data = 0;
}
m_rows = rows;
m_cols = cols;
@@ -203,7 +206,10 @@ template<typename T, int _Rows, int _Options> class ei_matrix_storage<T, Dynamic
if(size != _Rows*m_cols)
{
ei_aligned_delete(m_data, _Rows*m_cols);
m_data = ei_aligned_new<T>(size);
if (size)
m_data = ei_aligned_new<T>(size);
else
m_data = 0;
}
m_cols = cols;
}
@@ -229,7 +235,10 @@ template<typename T, int _Cols, int _Options> class ei_matrix_storage<T, Dynamic
if(size != m_rows*_Cols)
{
ei_aligned_delete(m_data, _Cols*m_rows);
m_data = ei_aligned_new<T>(size);
if (size)
m_data = ei_aligned_new<T>(size);
else
m_data = 0;
}
m_rows = rows;
}

View File

@@ -221,6 +221,8 @@ struct ei_solve_triangular_selector<Lhs,Rhs,UpLo,ColMajor|IsDense>
};
/** "in-place" version of MatrixBase::solveTriangular() where the result is written in \a other
*
* \nonstableyet
*
* The parameter is only marked 'const' to make the C++ compiler accept a temporary expression here.
* This function will const_cast it, so constness isn't honored here.
@@ -250,6 +252,8 @@ void MatrixBase<Derived>::solveTriangularInPlace(const MatrixBase<OtherDerived>&
}
/** \returns the product of the inverse of \c *this with \a other, \a *this being triangular.
*
* \nonstableyet
*
* This function computes the inverse-matrix matrix product inverse(\c *this) * \a other.
* The matrix \c *this must be triangular and invertible (i.e., all the coefficients of the

View File

@@ -114,9 +114,16 @@ template<> EIGEN_STRONG_INLINE void ei_pstoreu<float>(float* to, const __m128&
template<> EIGEN_STRONG_INLINE void ei_pstoreu<double>(double* to, const __m128d& from) { _mm_storeu_pd(to, from); }
template<> EIGEN_STRONG_INLINE void ei_pstoreu<int>(int* to, const __m128i& from) { _mm_storeu_si128(reinterpret_cast<__m128i*>(to), from); }
#ifdef _MSC_VER
// this fix internal compilation error
template<> EIGEN_STRONG_INLINE float ei_pfirst<__m128>(const __m128& a) { float x = _mm_cvtss_f32(a); return x; }
template<> EIGEN_STRONG_INLINE double ei_pfirst<__m128d>(const __m128d& a) { double x = _mm_cvtsd_f64(a); return x; }
template<> EIGEN_STRONG_INLINE int ei_pfirst<__m128i>(const __m128i& a) { int x = _mm_cvtsi128_si32(a); return x; }
#else
template<> EIGEN_STRONG_INLINE float ei_pfirst<__m128>(const __m128& a) { return _mm_cvtss_f32(a); }
template<> EIGEN_STRONG_INLINE double ei_pfirst<__m128d>(const __m128d& a) { return _mm_cvtsd_f64(a); }
template<> EIGEN_STRONG_INLINE int ei_pfirst<__m128i>(const __m128i& a) { return _mm_cvtsi128_si32(a); }
#endif
#ifdef __SSE3__
// TODO implement SSE2 versions as well as integer versions

View File

@@ -30,12 +30,30 @@
#define EIGEN_WORLD_VERSION 2
#define EIGEN_MAJOR_VERSION 0
#define EIGEN_MINOR_VERSION 0
#define EIGEN_MINOR_VERSION 1
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \
(EIGEN_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
EIGEN_MINOR_VERSION>=z))))
// if the compiler is GNUC, disable 16 byte alignment on exotic archs that probably don't need it, and on which
// it may be extra trouble to get aligned memory allocation to work (example: on ARM, overloading new[] is a PITA
// because extra memory must be allocated for bookkeeping).
// if the compiler is not GNUC, just cross fingers that the architecture isn't too exotic, because we don't want
// to keep track of all the different preprocessor symbols for all compilers.
#if !defined(__GNUC__) || defined(__i386__) || defined(__x86_64__) || defined(__ppc__) || defined(__ia64__)
#define EIGEN_ARCH_WANTS_ALIGNMENT 1
#else
#ifdef EIGEN_VECTORIZE
#error Vectorization enabled, but the architecture is not listed among those for which we require 16 byte alignment. If you added vectorization for another architecture, you also need to edit this list.
#endif
#define EIGEN_ARCH_WANTS_ALIGNMENT 0
#ifndef EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
#define EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
#endif
#endif
#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
#define EIGEN_DEFAULT_MATRIX_STORAGE_ORDER_OPTION RowMajor
#else
@@ -147,12 +165,14 @@ using Eigen::ei_cos;
* If we made alignment depend on whether or not EIGEN_VECTORIZE is defined, it would be impossible to link
* vectorized and non-vectorized code.
*/
#if (defined __GNUC__)
#if !EIGEN_ARCH_WANTS_ALIGNMENT
#define EIGEN_ALIGN_128
#elif (defined __GNUC__)
#define EIGEN_ALIGN_128 __attribute__((aligned(16)))
#elif (defined _MSC_VER)
#define EIGEN_ALIGN_128 __declspec(align(16))
#else
#define EIGEN_ALIGN_128
#error Please tell me what is the equivalent of __attribute__((aligned(16))) for your compiler
#endif
#define EIGEN_RESTRICT __restrict
@@ -173,18 +193,18 @@ using Eigen::ei_cos;
template<typename OtherDerived> \
EIGEN_STRONG_INLINE Derived& operator Op(const Eigen::MatrixBase<OtherDerived>& other) \
{ \
return Eigen::MatrixBase<Derived>::operator Op(other.derived()); \
return Base::operator Op(other.derived()); \
} \
EIGEN_STRONG_INLINE Derived& operator Op(const Derived& other) \
{ \
return Eigen::MatrixBase<Derived>::operator Op(other); \
return Base::operator Op(other); \
}
#define EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, Op) \
template<typename Other> \
EIGEN_STRONG_INLINE Derived& operator Op(const Other& scalar) \
{ \
return Eigen::MatrixBase<Derived>::operator Op(scalar); \
return Base::operator Op(scalar); \
}
#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) \

View File

@@ -2,7 +2,7 @@
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2008-2009 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2009 Kenneth Riddile <kfriddile@yahoo.com>
//
// Eigen is free software; you can redistribute it and/or
@@ -27,8 +27,7 @@
#ifndef EIGEN_MEMORY_H
#define EIGEN_MEMORY_H
// for NetBSD I didn't see any clear statement in the docs, but Mark Davies is confident about this.
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(_WIN64)
#if defined(__APPLE__) || defined(_WIN64)
#define EIGEN_MALLOC_ALREADY_ALIGNED 1
#else
#define EIGEN_MALLOC_ALREADY_ALIGNED 0
@@ -75,13 +74,15 @@ inline void* ei_aligned_malloc(size_t size)
#endif
void *result;
#if EIGEN_HAS_POSIX_MEMALIGN && !EIGEN_MALLOC_ALREADY_ALIGNED
#if EIGEN_HAS_POSIX_MEMALIGN && EIGEN_ARCH_WANTS_ALIGNMENT && !EIGEN_MALLOC_ALREADY_ALIGNED
#ifdef EIGEN_EXCEPTIONS
const int failed =
#endif
posix_memalign(&result, 16, size);
#else
#if EIGEN_MALLOC_ALREADY_ALIGNED
#if !EIGEN_ARCH_WANTS_ALIGNMENT
result = malloc(size);
#elif EIGEN_MALLOC_ALREADY_ALIGNED
result = malloc(size);
#elif EIGEN_HAS_MM_MALLOC
result = _mm_malloc(size, 16);
@@ -142,7 +143,9 @@ template<typename T, bool Align> inline T* ei_conditional_aligned_new(size_t siz
*/
inline void ei_aligned_free(void *ptr)
{
#if EIGEN_MALLOC_ALREADY_ALIGNED
#if !EIGEN_ARCH_WANTS_ALIGNMENT
free(ptr);
#elif EIGEN_MALLOC_ALREADY_ALIGNED
free(ptr);
#elif EIGEN_HAS_POSIX_MEMALIGN
free(ptr);
@@ -233,60 +236,28 @@ inline static int ei_alignmentOffset(const Scalar* ptr, int maxOffset)
#define ei_aligned_stack_delete(TYPE,PTR,SIZE) do {ei_delete_elements_of_array<TYPE>(PTR, SIZE); \
ei_aligned_stack_free(PTR,sizeof(TYPE)*SIZE);} while(0)
/** \brief Overloads the operator new and delete of the class Type with operators that are aligned if NeedsToAlign is true
*
* When Eigen's explicit vectorization is enabled, Eigen assumes that some fixed sizes types are aligned
* on a 16 bytes boundary. Those include all Matrix types having a sizeof multiple of 16 bytes, e.g.:
* - Vector2d, Vector4f, Vector4i, Vector4d,
* - Matrix2d, Matrix4f, Matrix4i, Matrix4d,
* - etc.
* When an object is statically allocated, the compiler will automatically and always enforces 16 bytes
* alignment of the data when needed. However some troubles might appear when data are dynamically allocated.
* Let's pick an example:
* \code
* struct Foo {
* char dummy;
* Vector4f some_vector;
* };
* Foo obj1; // static allocation
* obj1.some_vector = Vector4f(..); // => OK
*
* Foo *pObj2 = new Foo; // dynamic allocation
* pObj2->some_vector = Vector4f(..); // => !! might segfault !!
* \endcode
* Here, the problem is that operator new is not aware of the compile time alignment requirement of the
* type Vector4f (and hence of the type Foo). Therefore "new Foo" does not necessarily returns a 16 bytes
* aligned pointer. The purpose of the class WithAlignedOperatorNew is exactly to overcome this issue by
* overloading the operator new to return aligned data when the vectorization is enabled.
* Here is a similar safe example:
* \code
* struct Foo {
* EIGEN_MAKE_ALIGNED_OPERATOR_NEW
* char dummy;
* Vector4f some_vector;
* };
* Foo *pObj2 = new Foo; // dynamic allocation
* pObj2->some_vector = Vector4f(..); // => SAFE !
* \endcode
*
* \sa class ei_new_allocator
*/
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) \
void *operator new(size_t size) throw() { \
return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); \
} \
void *operator new[](size_t size) throw() { \
return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); \
} \
void operator delete(void * ptr) { Eigen::ei_conditional_aligned_free<NeedsToAlign>(ptr); } \
void operator delete[](void * ptr) { Eigen::ei_conditional_aligned_free<NeedsToAlign>(ptr); } \
void *operator new(size_t, void *ptr) throw() { return ptr; }
#if EIGEN_ARCH_WANTS_ALIGNMENT
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) \
void *operator new(size_t size) throw() { \
return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); \
} \
void *operator new[](size_t size) throw() { \
return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); \
} \
void operator delete(void * ptr) { Eigen::ei_conditional_aligned_free<NeedsToAlign>(ptr); } \
void operator delete[](void * ptr) { Eigen::ei_conditional_aligned_free<NeedsToAlign>(ptr); } \
void *operator new(size_t, void *ptr) throw() { return ptr; } \
typedef void ei_operator_new_marker_type;
#else
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign)
#endif
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(true)
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(Scalar,Size) \
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(((Size)!=Eigen::Dynamic) && ((sizeof(Scalar)*(Size))%16==0))
/** \class aligned_allocator
*
* \brief stl compatible allocator to use with with 16 byte aligned types
@@ -318,34 +289,34 @@ public:
typedef aligned_allocator<U> other;
};
pointer address( reference value ) const
pointer address( reference value ) const
{
return &value;
}
const_pointer address( const_reference value ) const
const_pointer address( const_reference value ) const
{
return &value;
}
aligned_allocator() throw()
aligned_allocator() throw()
{
}
aligned_allocator( const aligned_allocator& ) throw()
aligned_allocator( const aligned_allocator& ) throw()
{
}
template<class U>
aligned_allocator( const aligned_allocator<U>& ) throw()
aligned_allocator( const aligned_allocator<U>& ) throw()
{
}
~aligned_allocator() throw()
~aligned_allocator() throw()
{
}
size_type max_size() const throw()
size_type max_size() const throw()
{
return std::numeric_limits<size_type>::max();
}
@@ -356,20 +327,26 @@ public:
return static_cast<pointer>( ei_aligned_malloc( num * sizeof(T) ) );
}
void construct( pointer p, const T& value )
void construct( pointer p, const T& value )
{
::new( p ) T( value );
}
void destroy( pointer p )
void destroy( pointer p )
{
p->~T();
}
void deallocate( pointer p, size_type /*num*/ )
void deallocate( pointer p, size_type /*num*/ )
{
ei_aligned_free( p );
}
bool operator!=(const aligned_allocator<T>& other) const
{ return false; }
bool operator==(const aligned_allocator<T>& other) const
{ return true; }
};
#endif // EIGEN_MEMORY_H

View File

@@ -25,7 +25,7 @@
#ifndef EIGEN_ALIGNEDBOX_H
#define EIGEN_ALIGNEDBOX_H
/** \geometry_module \ingroup GeometryModule
/** \geometry_module \ingroup Geometry_Module
* \nonstableyet
*
* \class AlignedBox

View File

@@ -25,7 +25,7 @@
#ifndef EIGEN_ANGLEAXIS_H
#define EIGEN_ANGLEAXIS_H
/** \geometry_module \ingroup GeometryModule
/** \geometry_module \ingroup Geometry_Module
*
* \class AngleAxis
*
@@ -158,10 +158,10 @@ public:
{ return m_axis.isApprox(other.m_axis, prec) && ei_isApprox(m_angle,other.m_angle, prec); }
};
/** \ingroup GeometryModule
/** \ingroup Geometry_Module
* single precision angle-axis type */
typedef AngleAxis<float> AngleAxisf;
/** \ingroup GeometryModule
/** \ingroup Geometry_Module
* double precision angle-axis type */
typedef AngleAxis<double> AngleAxisd;

View File

@@ -25,7 +25,7 @@
#ifndef EIGEN_EULERANGLES_H
#define EIGEN_EULERANGLES_H
/** \geometry_module \ingroup GeometryModule
/** \geometry_module \ingroup Geometry_Module
* \nonstableyet
*
* \returns the Euler-angles of the rotation matrix \c *this using the convention defined by the triplet (\a a0,\a a1,\a a2)

View File

@@ -26,7 +26,7 @@
#ifndef EIGEN_HYPERPLANE_H
#define EIGEN_HYPERPLANE_H
/** \geometry_module \ingroup GeometryModule
/** \geometry_module \ingroup Geometry_Module
*
* \class Hyperplane
*

View File

@@ -26,7 +26,7 @@
#ifndef EIGEN_PARAMETRIZEDLINE_H
#define EIGEN_PARAMETRIZEDLINE_H
/** \geometry_module \ingroup GeometryModule
/** \geometry_module \ingroup Geometry_Module
*
* \class ParametrizedLine
*

View File

@@ -30,7 +30,7 @@ template<typename Other,
int OtherCols=Other::ColsAtCompileTime>
struct ei_quaternion_assign_impl;
/** \geometry_module \ingroup GeometryModule
/** \geometry_module \ingroup Geometry_Module
*
* \class Quaternion
*
@@ -61,12 +61,12 @@ template<typename _Scalar>
class Quaternion : public RotationBase<Quaternion<_Scalar>,3>
{
typedef RotationBase<Quaternion<_Scalar>,3> Base;
public:
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF_VECTORIZABLE_FIXED_SIZE(_Scalar,4)
using Base::operator*;
/** the scalar type of the coefficients */
typedef _Scalar Scalar;
@@ -112,10 +112,6 @@ public:
/** Default constructor leaving the quaternion uninitialized. */
inline Quaternion() {}
inline Quaternion(ei_constructor_without_unaligned_array_assert)
: m_coeffs(ei_constructor_without_unaligned_array_assert()) {}
/** Constructs and initializes the quaternion \f$ w+xi+yj+zk \f$ from
* its four coefficients \a w, \a x, \a y and \a z.
*
@@ -217,14 +213,14 @@ public:
bool isApprox(const Quaternion& other, typename NumTraits<Scalar>::Real prec = precision<Scalar>()) const
{ return m_coeffs.isApprox(other.m_coeffs, prec); }
protected:
protected:
Coefficients m_coeffs;
};
/** \ingroup GeometryModule
/** \ingroup Geometry_Module
* single precision quaternion type */
typedef Quaternion<float> Quaternionf;
/** \ingroup GeometryModule
/** \ingroup Geometry_Module
* double precision quaternion type */
typedef Quaternion<double> Quaterniond;

View File

@@ -25,7 +25,7 @@
#ifndef EIGEN_ROTATION2D_H
#define EIGEN_ROTATION2D_H
/** \geometry_module \ingroup GeometryModule
/** \geometry_module \ingroup Geometry_Module
*
* \class Rotation2D
*
@@ -125,10 +125,10 @@ public:
{ return ei_isApprox(m_angle,other.m_angle, prec); }
};
/** \ingroup GeometryModule
/** \ingroup Geometry_Module
* single precision 2D rotation type */
typedef Rotation2D<float> Rotation2Df;
/** \ingroup GeometryModule
/** \ingroup Geometry_Module
* double precision 2D rotation type */
typedef Rotation2D<double> Rotation2Dd;

View File

@@ -25,7 +25,7 @@
#ifndef EIGEN_SCALING_H
#define EIGEN_SCALING_H
/** \geometry_module \ingroup GeometryModule
/** \geometry_module \ingroup Geometry_Module
*
* \class Scaling
*
@@ -149,7 +149,7 @@ public:
};
/** \addtogroup GeometryModule */
/** \addtogroup Geometry_Module */
//@{
typedef Scaling<float, 2> Scaling2f;
typedef Scaling<double,2> Scaling2d;

View File

@@ -43,7 +43,7 @@ template< typename Other,
int OtherCols=Other::ColsAtCompileTime>
struct ei_transform_product_impl;
/** \geometry_module \ingroup GeometryModule
/** \geometry_module \ingroup Geometry_Module
*
* \class Transform
*
@@ -95,11 +95,8 @@ public:
/** Default constructor without initialization of the coefficients. */
inline Transform() { }
inline Transform(ei_constructor_without_unaligned_array_assert)
: m_matrix(ei_constructor_without_unaligned_array_assert()) {}
inline Transform(const Transform& other)
{
{
m_matrix = other.m_matrix;
}
@@ -290,13 +287,13 @@ protected:
};
/** \ingroup GeometryModule */
/** \ingroup Geometry_Module */
typedef Transform<float,2> Transform2f;
/** \ingroup GeometryModule */
/** \ingroup Geometry_Module */
typedef Transform<float,3> Transform3f;
/** \ingroup GeometryModule */
/** \ingroup Geometry_Module */
typedef Transform<double,2> Transform2d;
/** \ingroup GeometryModule */
/** \ingroup Geometry_Module */
typedef Transform<double,3> Transform3d;
/**************************
@@ -648,7 +645,7 @@ template<typename Scalar, int Dim>
template<typename ScalingMatrixType, typename RotationMatrixType>
void Transform<Scalar,Dim>::computeScalingRotation(ScalingMatrixType *scaling, RotationMatrixType *rotation) const
{
linear().svd().computeScalingRotation(scaling, rotation);
linear().svd().computeScalingRotation(scaling, rotation);
}
/** Convenient method to set \c *this from a position, orientation and scale

View File

@@ -25,7 +25,7 @@
#ifndef EIGEN_TRANSLATION_H
#define EIGEN_TRANSLATION_H
/** \geometry_module \ingroup GeometryModule
/** \geometry_module \ingroup Geometry_Module
*
* \class Translation
*
@@ -152,7 +152,7 @@ public:
};
/** \addtogroup GeometryModule */
/** \addtogroup Geometry_Module */
//@{
typedef Translation<float, 2> Translation2f;
typedef Translation<double,2> Translation2d;

View File

@@ -132,21 +132,31 @@ void ei_compute_inverse_in_size4_case(const MatrixType& matrix, MatrixType* resu
// since this is a rare case, we don't need to optimize it. We just want to handle it with little
// additional code.
MatrixType m(matrix);
m.row(1).swap(m.row(2));
m.row(0).swap(m.row(2));
m.row(1).swap(m.row(3));
if(ei_compute_inverse_in_size4_case_helper(m, result))
{
// good, the topleft 2x2 block of m is invertible. Since m is different from matrix in that two
// good, the topleft 2x2 block of m is invertible. Since m is different from matrix in that some
// rows were permuted, the actual inverse of matrix is derived from the inverse of m by permuting
// the corresponding columns.
result->col(1).swap(result->col(2));
result->col(0).swap(result->col(2));
result->col(1).swap(result->col(3));
}
else
{
// last possible case. Since matrix is assumed to be invertible, this last case has to work.
m.row(1).swap(m.row(2));
// first, undo the swaps previously made
m.row(0).swap(m.row(2));
m.row(1).swap(m.row(3));
// swap row 0 with the the row among 0 and 1 that has the biggest 2 first coeffs
int swap0with = ei_abs(m.coeff(0,0))+ei_abs(m.coeff(0,1))>ei_abs(m.coeff(1,0))+ei_abs(m.coeff(1,1)) ? 0 : 1;
m.row(0).swap(m.row(swap0with));
// swap row 1 with the the row among 2 and 3 that has the biggest 2 first coeffs
int swap1with = ei_abs(m.coeff(2,0))+ei_abs(m.coeff(2,1))>ei_abs(m.coeff(3,0))+ei_abs(m.coeff(3,1)) ? 2 : 3;
m.row(1).swap(m.row(swap1with));
ei_compute_inverse_in_size4_case_helper(m, result);
result->col(1).swap(result->col(3));
result->col(1).swap(result->col(swap1with));
result->col(0).swap(result->col(swap0with));
}
}
}

View File

@@ -1,6 +0,0 @@
FILE(GLOB Eigen_StdVector_SRCS "*.h")
INSTALL(FILES
${Eigen_StdVector_SRCS}
DESTINATION ${INCLUDE_INSTALL_DIR}/Eigen/src/StdVector
)

View File

@@ -1,73 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2009 Alex Stapleton <alex.stapleton@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_STDVECTOR_H
#define EIGEN_STDVECTOR_H
#define EIGEN_STD_VECTOR_SPECIALIZATION_BODY \
typedef Eigen::aligned_allocator<value_type> allocator_type; \
typedef vector<value_type, allocator_type > unaligned_base; \
typedef typename unaligned_base::size_type size_type; \
typedef typename unaligned_base::iterator iterator; \
explicit vector(const allocator_type& __a = allocator_type()) : unaligned_base(__a) {} \
vector(const vector& c) : unaligned_base(c) {} \
vector(size_type num, const value_type& val = value_type()) : unaligned_base(num, val) {}\
vector(iterator start, iterator end) : unaligned_base(start, end) {} \
vector& operator=(const vector& __x) { \
unaligned_base::operator=(__x); \
return *this; \
}
template <typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols, typename _Alloc>
class vector<Eigen::Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols>, _Alloc>
: public vector<Eigen::ei_unaligned_type<Eigen::Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> >,
Eigen::aligned_allocator<Eigen::ei_unaligned_type<Eigen::Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> > > >
{
public:
typedef Eigen::ei_unaligned_type<Eigen::Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> > value_type;
EIGEN_STD_VECTOR_SPECIALIZATION_BODY
};
template <typename _Scalar, int _Dim, typename _Alloc>
class vector<Eigen::Transform<_Scalar,_Dim>, _Alloc>
: public vector<Eigen::ei_unaligned_type<Eigen::Transform<_Scalar,_Dim> >,
Eigen::aligned_allocator<Eigen::ei_unaligned_type<Eigen::Transform<_Scalar,_Dim> > > >
{
public:
typedef Eigen::ei_unaligned_type<Eigen::Transform<_Scalar,_Dim> > value_type;
EIGEN_STD_VECTOR_SPECIALIZATION_BODY
};
template <typename _Scalar, typename _Alloc>
class vector<Eigen::Quaternion<_Scalar>, _Alloc>
: public vector<Eigen::ei_unaligned_type<Eigen::Quaternion<_Scalar> >,
Eigen::aligned_allocator<Eigen::ei_unaligned_type<Eigen::Quaternion<_Scalar> > > >
{
public:
typedef Eigen::ei_unaligned_type<Eigen::Quaternion<_Scalar> > value_type;
EIGEN_STD_VECTOR_SPECIALIZATION_BODY
};
#endif // EIGEN_STDVECTOR_H

View File

@@ -1,105 +0,0 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
// Copyright (C) 2009 Alex Stapleton <alex.stapleton@gmail.com>
//
// Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public
// License as published by the Free Software Foundation; either
// version 3 of the License, or (at your option) any later version.
//
// Alternatively, you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of
// the License, or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#ifndef EIGEN_UNALIGNEDTYPE_H
#define EIGEN_UNALIGNEDTYPE_H
template<typename aligned_type> class ei_unaligned_type;
template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int _MaxCols>
class ei_unaligned_type<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:
typedef Matrix<_Scalar,_Rows,_Cols,_Options,_MaxRows,_MaxCols> aligned_base;
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())
{
_unaligned_copy(other);
}
ei_unaligned_type(const ei_unaligned_type& other) : aligned_base(ei_constructor_without_unaligned_array_assert())
{
_unaligned_copy(other);
}
};
template<typename _Scalar, int _Dim>
class ei_unaligned_type<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:
typedef Transform<_Scalar,_Dim> aligned_base;
typedef typename aligned_base::MatrixType MatrixType;
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())
{
_unaligned_copy(other);
}
ei_unaligned_type(const ei_unaligned_type& other) : aligned_base(ei_constructor_without_unaligned_array_assert())
{
_unaligned_copy(other);
}
};
template<typename _Scalar>
class ei_unaligned_type<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:
typedef Quaternion<_Scalar> aligned_base;
typedef typename aligned_base::Coefficients Coefficients;
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())
{
_unaligned_copy(other);
}
ei_unaligned_type(const ei_unaligned_type& other) : aligned_base(ei_constructor_without_unaligned_array_assert())
{
_unaligned_copy(other);
}
};
#endif // EIGEN_UNALIGNEDTYPE_H

View File

@@ -120,6 +120,6 @@ In order to generate the documentation of Eigen, please follow these steps:
After doing that, you will find the HTML documentation in the doc/html/ subdirectory of the build directory.
<h2>Note however that the documentation is available online here:
<a href="http://eigen.tuxfamily.org/api/">http://eigen.tuxfamily.org/api</a></h2>
<a href="http://eigen.tuxfamily.org/dox/">http://eigen.tuxfamily.org/dox</a></h2>
*/

View File

@@ -9,6 +9,12 @@ namespace Eigen {
\section summary Summary
With the 2.0 release, Eigen's API is, to a large extent, stable. However, we wish to retain the freedom to make API incompatible changes. To that effect, we call many parts of Eigen "experimental" which means that they are not subject to API stability guarantee.
Our goal is that for the 2.1 release (expected in July 2009) most of these parts become API-stable too.
We are aware that API stability is a major concern for our users. That's why it's a priority for us to reach it, but at the same time we're being serious about not calling Eigen API-stable too early.
Experimental features may at any time:
\li be removed;
\li be subject to an API incompatible change;
@@ -16,11 +22,12 @@ Experimental features may at any time:
\section modules Experimental modules
The following modules are considered entirely experimental:
The following modules are considered entirely experimental, and we make no firm API stability guarantee about them for the time being:
\li SVD
\li QR
\li Cholesky
\li Sparse
\li Geometry
\li Geometry (this one should be mostly stable, but it's a little too early to make a formal guarantee)
\section core Experimental parts of the Core module
@@ -37,7 +44,7 @@ The only classes subject to (even partial) API stability guarantee (meaning that
All other classes offer no direct API guarantee, e.g. their methods can be changed; however notice that most classes inherit MatrixBase and that this is where most of their API comes from -- so in practice most of the API is stable.
Here are the MatrixBase methods that are considered experimental, hence not part of any API stability guarantee:
A few MatrixBase methods are considered experimental, hence not part of any API stability guarantee:
\li all methods documented as internal
\li all methods hidden in the Doxygen documentation
\li all methods marked as experimental

View File

@@ -357,8 +357,8 @@ absolute value (\link Cwise::abs() abs \endlink, \link Cwise::abs2() abs2 \endli
</td><td>\code
mat3 = mat1.cwise().min(mat2);
mat3 = mat1.cwise().max(mat2);
mat3 = mat1.cwise().abs(mat2);
mat3 = mat1.cwise().abs2(mat2);
mat3 = mat1.cwise().abs();
mat3 = mat1.cwise().abs2();
\endcode</td></tr>
</table>
</td></tr></table>

View File

@@ -8,7 +8,7 @@ my_program: path/to/eigen2/Eigen/src/Core/MatrixStorage.h:44:
Eigen::ei_matrix_array<T, Size, MatrixOptions, Align>::ei_matrix_array()
[with T = double, int Size = 2, int MatrixOptions = 2, bool Align = true]:
Assertion `(reinterpret_cast<size_t>(array) & 0xf) == 0 && "this assertion
is explained here: http://eigen.tuxfamily.org/api/UnalignedArrayAssert.html
is explained here: http://eigen.tuxfamily.org/dox/UnalignedArrayAssert.html
**** READ THIS WEB PAGE !!! ****"' failed.
</pre>

View File

@@ -1,4 +1,4 @@
Matrix3d m = Matrix3i::Zero();
Matrix3d m = Matrix3d::Zero();
m.part<Eigen::StrictlyUpperTriangular>().setOnes();
cout << "Here is the matrix m:" << endl << m << endl;
cout << "And let us now compute m*m.adjoint() in a very optimized way" << endl

View File

@@ -103,7 +103,10 @@ template<typename MatrixType> void basicStuff(const MatrixType& m)
m3 = m1;
m1.swap(m2);
VERIFY_IS_APPROX(m3, m2);
VERIFY_IS_NOT_APPROX(m3, m1);
if(rows*cols>=3)
{
VERIFY_IS_NOT_APPROX(m3, m1);
}
}
void test_basicstuff()

View File

@@ -24,12 +24,18 @@
#include "main.h"
#if EIGEN_ARCH_WANTS_ALIGNMENT
#define ALIGNMENT 16
#else
#define ALIGNMENT 1
#endif
void check_handmade_aligned_malloc()
{
for(int i = 1; i < 1000; i++)
{
char *p = (char*)ei_handmade_aligned_malloc(i);
VERIFY(size_t(p)%16==0);
VERIFY(size_t(p)%ALIGNMENT==0);
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
for(int j = 0; j < i; j++) p[j]=0;
ei_handmade_aligned_free(p);
@@ -41,7 +47,7 @@ void check_aligned_malloc()
for(int i = 1; i < 1000; i++)
{
char *p = (char*)ei_aligned_malloc(i);
VERIFY(size_t(p)%16==0);
VERIFY(size_t(p)%ALIGNMENT==0);
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
for(int j = 0; j < i; j++) p[j]=0;
ei_aligned_free(p);
@@ -53,7 +59,7 @@ void check_aligned_new()
for(int i = 1; i < 1000; i++)
{
float *p = ei_aligned_new<float>(i);
VERIFY(size_t(p)%16==0);
VERIFY(size_t(p)%ALIGNMENT==0);
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
for(int j = 0; j < i; j++) p[j]=0;
ei_aligned_delete(p,i);
@@ -65,7 +71,7 @@ void check_aligned_stack_alloc()
for(int i = 1; i < 1000; i++)
{
float *p = ei_aligned_stack_new(float,i);
VERIFY(size_t(p)%16==0);
VERIFY(size_t(p)%ALIGNMENT==0);
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
for(int j = 0; j < i; j++) p[j]=0;
ei_aligned_stack_delete(float,p,i);
@@ -92,7 +98,7 @@ class MyClassA
template<typename T> void check_dynaligned()
{
T* obj = new T;
VERIFY(size_t(obj)%16==0);
VERIFY(size_t(obj)%ALIGNMENT==0);
delete obj;
}
@@ -115,15 +121,15 @@ void test_dynalloc()
// check static allocation, who knows ?
{
MyStruct foo0; VERIFY(size_t(foo0.avec.data())%16==0);
MyClassA fooA; VERIFY(size_t(fooA.avec.data())%16==0);
MyStruct foo0; VERIFY(size_t(foo0.avec.data())%ALIGNMENT==0);
MyClassA fooA; VERIFY(size_t(fooA.avec.data())%ALIGNMENT==0);
}
// dynamic allocation, single object
for (int i=0; i<g_repeat*100; ++i)
{
MyStruct *foo0 = new MyStruct(); VERIFY(size_t(foo0->avec.data())%16==0);
MyClassA *fooA = new MyClassA(); VERIFY(size_t(fooA->avec.data())%16==0);
MyStruct *foo0 = new MyStruct(); VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0);
MyClassA *fooA = new MyClassA(); VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0);
delete foo0;
delete fooA;
}
@@ -132,8 +138,8 @@ void test_dynalloc()
const int N = 10;
for (int i=0; i<g_repeat*100; ++i)
{
MyStruct *foo0 = new MyStruct[N]; VERIFY(size_t(foo0->avec.data())%16==0);
MyClassA *fooA = new MyClassA[N]; VERIFY(size_t(fooA->avec.data())%16==0);
MyStruct *foo0 = new MyStruct[N]; VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0);
MyClassA *fooA = new MyClassA[N]; VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0);
delete[] foo0;
delete[] fooA;
}

View File

@@ -50,7 +50,7 @@ template<typename Scalar> void geometry(void)
Scalar largeEps = test_precision<Scalar>();
if (ei_is_same_type<Scalar,float>::ret)
largeEps = 1e-3f;
largeEps = 1e-2f;
Vector3 v0 = Vector3::Random(),
v1 = Vector3::Random(),
@@ -96,14 +96,18 @@ template<typename Scalar> void geometry(void)
Scalar refangle = ei_abs(AngleAxisx(q1.inverse()*q2).angle());
if (refangle>Scalar(M_PI))
refangle = Scalar(2)*Scalar(M_PI) - refangle;
VERIFY(ei_isApprox(q1.angularDistance(q2), refangle, largeEps));
if((q1.coeffs()-q2.coeffs()).norm() > 10*largeEps)
{
VERIFY(ei_isApprox(q1.angularDistance(q2), refangle, largeEps));
}
// rotation matrix conversion
VERIFY_IS_APPROX(q1 * v2, q1.toRotationMatrix() * v2);
VERIFY_IS_APPROX(q1 * q2 * v2,
q1.toRotationMatrix() * q2.toRotationMatrix() * v2);
VERIFY( (q2*q1).isApprox(q1*q2) || !(q2 * q1 * v2).isApprox(
VERIFY( (q2*q1).isApprox(q1*q2, largeEps) || !(q2 * q1 * v2).isApprox(
q1.toRotationMatrix() * q2.toRotationMatrix() * v2));
q2 = q1.toRotationMatrix();
@@ -157,7 +161,7 @@ template<typename Scalar> void geometry(void)
t1.prescale(v0);
VERIFY_IS_APPROX( (t0 * Vector3(1,0,0)).norm(), v0.x());
VERIFY(!ei_isApprox((t1 * Vector3(1,0,0)).norm(), v0.x()));
//VERIFY(!ei_isApprox((t1 * Vector3(1,0,0)).norm(), v0.x()));
t0.setIdentity();
t1.setIdentity();

View File

@@ -22,8 +22,8 @@
// License and a copy of the GNU General Public License along with
// Eigen. If not, see <http://www.gnu.org/licenses/>.
#include "main.h"
#include <Eigen/StdVector>
#include "main.h"
#include <Eigen/Geometry>
template<typename MatrixType>

View File

@@ -92,6 +92,7 @@ void check_unalignedassert_good()
delete[] y;
}
#if EIGEN_ARCH_WANTS_ALIGNMENT
template<typename T>
void check_unalignedassert_bad()
{
@@ -101,20 +102,27 @@ void check_unalignedassert_bad()
T *x = ::new(static_cast<void*>(unaligned)) T;
x->~T();
}
#endif
void unalignedassert()
{
check_unalignedassert_good<Good1>();
check_unalignedassert_good<Good2>();
check_unalignedassert_good<Good3>();
#if EIGEN_ARCH_WANTS_ALIGNMENT
VERIFY_RAISES_ASSERT(check_unalignedassert_bad<Bad4>());
VERIFY_RAISES_ASSERT(check_unalignedassert_bad<Bad5>());
VERIFY_RAISES_ASSERT(check_unalignedassert_bad<Bad6>());
#endif
check_unalignedassert_good<Good7>();
check_unalignedassert_good<Good8>();
check_unalignedassert_good<Good9>();
check_unalignedassert_good<Depends<true> >();
#if EIGEN_ARCH_WANTS_ALIGNMENT
VERIFY_RAISES_ASSERT(check_unalignedassert_bad<Depends<false> >());
#endif
}
void test_unalignedassert()