Compare commits

..

16 Commits

Author SHA1 Message Date
Benoit Jacob
ed6eb5a625 bump 2010-02-11 21:39:41 -05:00
Benoit Jacob
9488a12125 work around brain dead ICC 2010-02-11 19:32:56 -05:00
Piotr Trojanek
7b44957c4b std:: namespace fixup for more restricive compilers such as QNX's QCC 2010-02-10 22:27:35 +01:00
Hauke Heibel
743ad75595 BenchTimer backport (clock_gettime & QueryPerformanceCounter). 2010-02-03 21:55:01 +01:00
Benoit Jacob
a9eabed421 Patch by 'Wolf' from the issue tracker:
Fix bug #90, missing type cast in LU, allow to use LU with MPFR.
2010-02-02 07:06:15 -05:00
Benoit Jacob
cd34a1d351 backport bug fix by Jitse. 2010-01-28 14:00:09 -05:00
Benoit Jacob
3e963ee69d EIGEN_ENUM_MIN ---> EIGEN_SIZE_MIN 2010-01-26 20:37:57 -05:00
Benoit Jacob
6cc9dc17f2 In LU / Inverse, decouple the output type from the input type.
This has long been done in the default branch
2010-01-26 18:45:23 -05:00
Gael Guennebaud
7852a48a2f fix matrix product with EIGEN_DEFAULT_TO_ROW_MAJOR 2010-01-25 21:56:01 +01:00
Benoit Jacob
d209120180 * Introduce EIGEN_DEFAULT_TO_ROW_MAJOR tests option
---> Now only product_large fails with EIGEN_DEFAULT_TO_ROW_MAJOR.
* Fix EIGEN_NO_ASSERTION_CHECKING tests option
* Fix a crash in Tridiagonalization on row-major matrices + SSE
* Fix inverse test (numeric stability noise)
* Extend map test (see previous fixes in MapBase)
* Fix vectorization_logic test for row-major
* Disable sparse tests with EIGEN_DEFAULT_TO_ROW_MAJOR
2010-01-25 14:00:02 -05:00
Thomas Capricelli
55c0707b1d fix the script again (definitely?) + cleaning 2010-01-22 19:28:33 +01:00
Benoit Jacob
72044ca925 fix a super nasty bug: on row-major expressions that are NOT vectors but that
do have LinearAccess, the MapBase::coeff(int) and MapBase::coeffRef(int)
methods were broken.
2010-01-21 23:33:20 -05:00
Benoit Jacob
c2b8ca7493 if EIGEN_DONT_ALIGN then don't try to vectorize (was giving a #error later on). 2010-01-21 22:32:16 -05:00
Gael Guennebaud
018cb8975a fix plugin doc 2010-01-17 19:55:08 +01:00
Benoit Jacob
3ab280ce4e add missing semicolon in the example 2010-01-17 12:40:19 -05:00
Benoit Jacob
b40030753b Added tag 2.0.11 for changeset 5f73a8df20 2010-01-10 11:30:40 -05:00
26 changed files with 279 additions and 138 deletions

View File

@@ -7,7 +7,7 @@ set(INCLUDE_INSTALL_DIR
"The directory where we install the header files" "The directory where we install the header files"
FORCE) FORCE)
set(EIGEN_VERSION_NUMBER "2.0.11") set(EIGEN_VERSION_NUMBER "2.0.12")
set(EIGEN_VERSION "${EIGEN_VERSION_NUMBER}") set(EIGEN_VERSION "${EIGEN_VERSION_NUMBER}")
set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake) set(CMAKE_MODULE_PATH ${PROJECT_SOURCE_DIR}/cmake)

View File

@@ -26,7 +26,7 @@
#define EIGEN_SSE2_BUT_NOT_OLD_GCC #define EIGEN_SSE2_BUT_NOT_OLD_GCC
#endif #endif
#ifndef EIGEN_DONT_VECTORIZE #if !defined(EIGEN_DONT_VECTORIZE) && !defined(EIGEN_DONT_ALIGN)
#if defined (EIGEN_SSE2_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER) #if defined (EIGEN_SSE2_BUT_NOT_OLD_GCC) || defined(EIGEN_SSE2_ON_MSVC_2008_OR_LATER)
#define EIGEN_VECTORIZE #define EIGEN_VECTORIZE
#define EIGEN_VECTORIZE_SSE #define EIGEN_VECTORIZE_SSE

View File

@@ -47,11 +47,11 @@ struct ei_traits<DiagonalCoeffs<MatrixType> >
typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested; typedef typename ei_unref<MatrixTypeNested>::type _MatrixTypeNested;
enum { enum {
RowsAtCompileTime = int(MatrixType::SizeAtCompileTime) == Dynamic ? Dynamic RowsAtCompileTime = int(MatrixType::SizeAtCompileTime) == Dynamic ? Dynamic
: EIGEN_ENUM_MIN(MatrixType::RowsAtCompileTime, : EIGEN_SIZE_MIN(MatrixType::RowsAtCompileTime,
MatrixType::ColsAtCompileTime), MatrixType::ColsAtCompileTime),
ColsAtCompileTime = 1, ColsAtCompileTime = 1,
MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic MaxRowsAtCompileTime = int(MatrixType::MaxSizeAtCompileTime) == Dynamic ? Dynamic
: EIGEN_ENUM_MIN(MatrixType::MaxRowsAtCompileTime, : EIGEN_SIZE_MIN(MatrixType::MaxRowsAtCompileTime,
MatrixType::MaxColsAtCompileTime), MatrixType::MaxColsAtCompileTime),
MaxColsAtCompileTime = 1, MaxColsAtCompileTime = 1,
Flags = (unsigned int)_MatrixTypeNested::Flags & (HereditaryBits | LinearAccessBit), Flags = (unsigned int)_MatrixTypeNested::Flags & (HereditaryBits | LinearAccessBit),

View File

@@ -99,7 +99,7 @@ template<typename Derived> class MapBase
inline const Scalar coeff(int index) const inline const Scalar coeff(int index) const
{ {
ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit)); ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit));
if ( ((RowsAtCompileTime == 1) == IsRowMajor) ) if ( ((RowsAtCompileTime == 1) == IsRowMajor) || !int(Derived::IsVectorAtCompileTime) )
return m_data[index]; return m_data[index];
else else
return m_data[index*stride()]; return m_data[index*stride()];
@@ -108,7 +108,7 @@ template<typename Derived> class MapBase
inline Scalar& coeffRef(int index) inline Scalar& coeffRef(int index)
{ {
ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit)); ei_assert(Derived::IsVectorAtCompileTime || (ei_traits<Derived>::Flags & LinearAccessBit));
if ( ((RowsAtCompileTime == 1) == IsRowMajor) ) if ( ((RowsAtCompileTime == 1) == IsRowMajor) || !int(Derived::IsVectorAtCompileTime) )
return const_cast<Scalar*>(m_data)[index]; return const_cast<Scalar*>(m_data)[index];
else else
return const_cast<Scalar*>(m_data)[index*stride()]; return const_cast<Scalar*>(m_data)[index*stride()];

View File

@@ -54,7 +54,7 @@ template<> inline int machine_epsilon<int>() { return 0; }
inline int ei_real(int x) { return x; } inline int ei_real(int x) { return x; }
inline int ei_imag(int) { return 0; } inline int ei_imag(int) { return 0; }
inline int ei_conj(int x) { return x; } inline int ei_conj(int x) { return x; }
inline int ei_abs(int x) { return abs(x); } inline int ei_abs(int x) { return std::abs(x); }
inline int ei_abs2(int x) { return x*x; } inline int ei_abs2(int x) { return x*x; }
inline int ei_sqrt(int) { ei_assert(false); return 0; } inline int ei_sqrt(int) { ei_assert(false); return 0; }
inline int ei_exp(int) { ei_assert(false); return 0; } inline int ei_exp(int) { ei_assert(false); return 0; }
@@ -67,7 +67,7 @@ inline int ei_pow(int x, int y) { return int(std::pow(double(x), y)); }
template<> inline int ei_random(int a, int b) template<> inline int ei_random(int a, int b)
{ {
// We can't just do rand()%n as only the high-order bits are really random // We can't just do rand()%n as only the high-order bits are really random
return a + static_cast<int>((b-a+1) * (rand() / (RAND_MAX + 1.0))); return a + static_cast<int>((b-a+1) * (std::rand() / (RAND_MAX + 1.0)));
} }
template<> inline int ei_random() template<> inline int ei_random()
{ {

View File

@@ -592,7 +592,8 @@ template<typename _Scalar, int _Rows, int _Cols, int _Options, int _MaxRows, int
template<typename OtherDerived> template<typename OtherDerived>
inline void Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::swap(const MatrixBase<OtherDerived>& other) inline void Matrix<_Scalar, _Rows, _Cols, _Options, _MaxRows, _MaxCols>::swap(const MatrixBase<OtherDerived>& other)
{ {
ei_matrix_swap_impl<Matrix, OtherDerived>::run(*this, *const_cast<MatrixBase<OtherDerived>*>(&other)); // the Eigen:: here is to work around a stupid ICC 11.1 bug.
Eigen::ei_matrix_swap_impl<Matrix, OtherDerived>::run(*this, *const_cast<MatrixBase<OtherDerived>*>(&other));
} }

View File

@@ -583,7 +583,8 @@ template<typename Derived> class MatrixBase
const LU<PlainMatrixType> lu() const; const LU<PlainMatrixType> lu() const;
const PlainMatrixType inverse() const; const PlainMatrixType inverse() const;
void computeInverse(PlainMatrixType *result) const; template<typename ResultType>
void computeInverse(MatrixBase<ResultType> *result) const;
Scalar determinant() const; Scalar determinant() const;
/////////// Cholesky module /////////// /////////// Cholesky module ///////////

View File

@@ -40,7 +40,7 @@ template <typename T, int Size, int MatrixOptions,
ei_matrix_array() ei_matrix_array()
{ {
#ifndef EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT #ifndef EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT
ei_assert((reinterpret_cast<size_t>(array) & 0xf) == 0 ei_assert((reinterpret_cast<std::size_t>(array) & 0xf) == 0
&& "this assertion is explained here: http://eigen.tuxfamily.org/dox/UnalignedArrayAssert.html **** READ THIS WEB PAGE !!! ****"); && "this assertion is explained here: http://eigen.tuxfamily.org/dox/UnalignedArrayAssert.html **** READ THIS WEB PAGE !!! ****");
#endif #endif
} }

View File

@@ -66,11 +66,8 @@ struct ProductReturnType
template<typename Lhs, typename Rhs> template<typename Lhs, typename Rhs>
struct ProductReturnType<Lhs,Rhs,CacheFriendlyProduct> struct ProductReturnType<Lhs,Rhs,CacheFriendlyProduct>
{ {
typedef typename ei_nested<Lhs,Rhs::ColsAtCompileTime>::type LhsNested; typedef const Lhs& LhsNested;
typedef const Rhs& RhsNested;
typedef typename ei_nested<Rhs,Lhs::RowsAtCompileTime,
typename ei_plain_matrix_type_column_major<Rhs>::type
>::type RhsNested;
typedef Product<LhsNested, RhsNested, CacheFriendlyProduct> Type; typedef Product<LhsNested, RhsNested, CacheFriendlyProduct> Type;
}; };
@@ -128,7 +125,7 @@ struct ei_traits<Product<LhsNested, RhsNested, ProductMode> >
RowsAtCompileTime = _LhsNested::RowsAtCompileTime, RowsAtCompileTime = _LhsNested::RowsAtCompileTime,
ColsAtCompileTime = _RhsNested::ColsAtCompileTime, ColsAtCompileTime = _RhsNested::ColsAtCompileTime,
InnerSize = EIGEN_ENUM_MIN(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime), InnerSize = EIGEN_SIZE_MIN(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime),
MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime, MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime,
MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime, MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime,
@@ -144,7 +141,7 @@ struct ei_traits<Product<LhsNested, RhsNested, ProductMode> >
EvalToRowMajor = RhsRowMajor && (ProductMode==(int)CacheFriendlyProduct ? LhsRowMajor : (!CanVectorizeLhs)), EvalToRowMajor = RhsRowMajor && (ProductMode==(int)CacheFriendlyProduct ? LhsRowMajor : (!CanVectorizeLhs)),
RemovedBits = ~(EvalToRowMajor ? 0 : RowMajorBit), RemovedBits = ~((EvalToRowMajor ? 0 : RowMajorBit)|DirectAccessBit),
Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits) Flags = ((unsigned int)(LhsFlags | RhsFlags) & HereditaryBits & RemovedBits)
| EvalBeforeAssigningBit | EvalBeforeAssigningBit
@@ -571,7 +568,7 @@ struct ei_cache_friendly_product_selector<ProductType,LhsRows,ColMajor,HasDirect
else else
{ {
_res = ei_aligned_stack_new(Scalar,res.size()); _res = ei_aligned_stack_new(Scalar,res.size());
Map<Matrix<Scalar,DestDerived::RowsAtCompileTime,1> >(_res, res.size()) = res; Map<Matrix<Scalar,DestDerived::RowsAtCompileTime,1,ColMajor> >(_res, res.size()) = res;
} }
ei_cache_friendly_product_colmajor_times_vector(res.size(), ei_cache_friendly_product_colmajor_times_vector(res.size(),
&product.lhs().const_cast_derived().coeffRef(0,0), product.lhs().stride(), &product.lhs().const_cast_derived().coeffRef(0,0), product.lhs().stride(),
@@ -579,7 +576,7 @@ struct ei_cache_friendly_product_selector<ProductType,LhsRows,ColMajor,HasDirect
if (!EvalToRes) if (!EvalToRes)
{ {
res = Map<Matrix<Scalar,DestDerived::SizeAtCompileTime,1> >(_res, res.size()); res = Map<Matrix<Scalar,DestDerived::SizeAtCompileTime,1,ColMajor> >(_res, res.size());
ei_aligned_stack_delete(Scalar, _res, res.size()); ei_aligned_stack_delete(Scalar, _res, res.size());
} }
} }
@@ -617,7 +614,7 @@ struct ei_cache_friendly_product_selector<ProductType,1,LhsOrder,LhsAccess,RhsCo
else else
{ {
_res = ei_aligned_stack_new(Scalar, res.size()); _res = ei_aligned_stack_new(Scalar, res.size());
Map<Matrix<Scalar,DestDerived::SizeAtCompileTime,1> >(_res, res.size()) = res; Map<Matrix<Scalar,DestDerived::SizeAtCompileTime,1,ColMajor> >(_res, res.size()) = res;
} }
ei_cache_friendly_product_colmajor_times_vector(res.size(), ei_cache_friendly_product_colmajor_times_vector(res.size(),
&product.rhs().const_cast_derived().coeffRef(0,0), product.rhs().stride(), &product.rhs().const_cast_derived().coeffRef(0,0), product.rhs().stride(),
@@ -625,7 +622,7 @@ struct ei_cache_friendly_product_selector<ProductType,1,LhsOrder,LhsAccess,RhsCo
if (!EvalToRes) if (!EvalToRes)
{ {
res = Map<Matrix<Scalar,DestDerived::SizeAtCompileTime,1> >(_res, res.size()); res = Map<Matrix<Scalar,DestDerived::SizeAtCompileTime,1,ColMajor> >(_res, res.size());
ei_aligned_stack_delete(Scalar, _res, res.size()); ei_aligned_stack_delete(Scalar, _res, res.size());
} }
} }
@@ -650,7 +647,7 @@ struct ei_cache_friendly_product_selector<ProductType,LhsRows,RowMajor,HasDirect
else else
{ {
_rhs = ei_aligned_stack_new(Scalar, product.rhs().size()); _rhs = ei_aligned_stack_new(Scalar, product.rhs().size());
Map<Matrix<Scalar,Rhs::SizeAtCompileTime,1> >(_rhs, product.rhs().size()) = product.rhs(); Map<Matrix<Scalar,Rhs::SizeAtCompileTime,1,ColMajor> >(_rhs, product.rhs().size()) = product.rhs();
} }
ei_cache_friendly_product_rowmajor_times_vector(&product.lhs().const_cast_derived().coeffRef(0,0), product.lhs().stride(), ei_cache_friendly_product_rowmajor_times_vector(&product.lhs().const_cast_derived().coeffRef(0,0), product.lhs().stride(),
_rhs, product.rhs().size(), res); _rhs, product.rhs().size(), res);
@@ -678,7 +675,7 @@ struct ei_cache_friendly_product_selector<ProductType,1,LhsOrder,LhsAccess,RhsCo
else else
{ {
_lhs = ei_aligned_stack_new(Scalar, product.lhs().size()); _lhs = ei_aligned_stack_new(Scalar, product.lhs().size());
Map<Matrix<Scalar,Lhs::SizeAtCompileTime,1> >(_lhs, product.lhs().size()) = product.lhs(); Map<Matrix<Scalar,Lhs::SizeAtCompileTime,1,ColMajor> >(_lhs, product.lhs().size()) = product.lhs();
} }
ei_cache_friendly_product_rowmajor_times_vector(&product.rhs().const_cast_derived().coeffRef(0,0), product.rhs().stride(), ei_cache_friendly_product_rowmajor_times_vector(&product.rhs().const_cast_derived().coeffRef(0,0), product.rhs().stride(),
_lhs, product.lhs().size(), res); _lhs, product.lhs().size(), res);
@@ -709,7 +706,17 @@ MatrixBase<Derived>::operator+=(const Flagged<Product<Lhs,Rhs,CacheFriendlyProdu
if (other._expression()._useCacheFriendlyProduct()) if (other._expression()._useCacheFriendlyProduct())
ei_cache_friendly_product_selector<Product<Lhs,Rhs,CacheFriendlyProduct> >::run(const_cast_derived(), other._expression()); ei_cache_friendly_product_selector<Product<Lhs,Rhs,CacheFriendlyProduct> >::run(const_cast_derived(), other._expression());
else else
lazyAssign(derived() + other._expression()); {
typedef typename ei_cleantype<Lhs>::type _Lhs;
typedef typename ei_cleantype<Rhs>::type _Rhs;
typedef typename ei_nested<_Lhs,_Rhs::ColsAtCompileTime>::type LhsNested;
typedef typename ei_nested<_Rhs,_Lhs::RowsAtCompileTime>::type RhsNested;
Product<LhsNested,RhsNested,NormalProduct> prod(other._expression().lhs(),other._expression().rhs());
lazyAssign(derived() + prod);
}
return derived(); return derived();
} }
@@ -724,12 +731,21 @@ inline Derived& MatrixBase<Derived>::lazyAssign(const Product<Lhs,Rhs,CacheFrien
} }
else else
{ {
lazyAssign<Product<Lhs,Rhs,CacheFriendlyProduct> >(product); typedef typename ei_cleantype<Lhs>::type _Lhs;
typedef typename ei_cleantype<Rhs>::type _Rhs;
typedef typename ei_nested<_Lhs,_Rhs::ColsAtCompileTime>::type LhsNested;
typedef typename ei_nested<_Rhs,_Lhs::RowsAtCompileTime>::type RhsNested;
typedef Product<LhsNested,RhsNested,NormalProduct> NormalProduct;
NormalProduct normal_prod(product.lhs(),product.rhs());
lazyAssign<NormalProduct>(normal_prod);
} }
return derived(); return derived();
} }
template<typename T> struct ei_product_copy_rhs template<typename T,int StorageOrder> struct ei_product_copy_rhs
{ {
typedef typename ei_meta_if< typedef typename ei_meta_if<
(ei_traits<T>::Flags & RowMajorBit) (ei_traits<T>::Flags & RowMajorBit)
@@ -739,11 +755,30 @@ template<typename T> struct ei_product_copy_rhs
>::ret type; >::ret type;
}; };
template<typename T> struct ei_product_copy_lhs template<typename T> struct ei_product_copy_rhs<T,RowMajorBit>
{
typedef typename ei_meta_if<
(!(ei_traits<T>::Flags & DirectAccessBit)),
typename ei_plain_matrix_type<T>::type,
const T&
>::ret type;
};
template<typename T,int StorageOrder> struct ei_product_copy_lhs
{ {
typedef typename ei_meta_if< typedef typename ei_meta_if<
(!(int(ei_traits<T>::Flags) & DirectAccessBit)), (!(int(ei_traits<T>::Flags) & DirectAccessBit)),
typename ei_plain_matrix_type<T>::type, typename ei_plain_matrix_type_row_major<T>::type,
const T&
>::ret type;
};
template<typename T> struct ei_product_copy_lhs<T,RowMajorBit>
{
typedef typename ei_meta_if<
((ei_traits<T>::Flags & RowMajorBit)==0)
|| (!(int(ei_traits<T>::Flags) & DirectAccessBit)),
typename ei_plain_matrix_type_row_major<T>::type,
const T& const T&
>::ret type; >::ret type;
}; };
@@ -752,9 +787,9 @@ template<typename Lhs, typename Rhs, int ProductMode>
template<typename DestDerived> template<typename DestDerived>
inline void Product<Lhs,Rhs,ProductMode>::_cacheFriendlyEvalAndAdd(DestDerived& res) const inline void Product<Lhs,Rhs,ProductMode>::_cacheFriendlyEvalAndAdd(DestDerived& res) const
{ {
typedef typename ei_product_copy_lhs<_LhsNested>::type LhsCopy; typedef typename ei_product_copy_lhs<_LhsNested,DestDerived::Flags&RowMajorBit>::type LhsCopy;
typedef typename ei_unref<LhsCopy>::type _LhsCopy; typedef typename ei_unref<LhsCopy>::type _LhsCopy;
typedef typename ei_product_copy_rhs<_RhsNested>::type RhsCopy; typedef typename ei_product_copy_rhs<_RhsNested,DestDerived::Flags&RowMajorBit>::type RhsCopy;
typedef typename ei_unref<RhsCopy>::type _RhsCopy; typedef typename ei_unref<RhsCopy>::type _RhsCopy;
LhsCopy lhs(m_lhs); LhsCopy lhs(m_lhs);
RhsCopy rhs(m_rhs); RhsCopy rhs(m_rhs);
@@ -764,6 +799,7 @@ inline void Product<Lhs,Rhs,ProductMode>::_cacheFriendlyEvalAndAdd(DestDerived&
_RhsCopy::Flags&RowMajorBit, (const Scalar*)&(rhs.const_cast_derived().coeffRef(0,0)), rhs.stride(), _RhsCopy::Flags&RowMajorBit, (const Scalar*)&(rhs.const_cast_derived().coeffRef(0,0)), rhs.stride(),
DestDerived::Flags&RowMajorBit, (Scalar*)&(res.coeffRef(0,0)), res.stride() DestDerived::Flags&RowMajorBit, (Scalar*)&(res.coeffRef(0,0)), res.stride()
); );
} }
#endif // EIGEN_PRODUCT_H #endif // EIGEN_PRODUCT_H

View File

@@ -30,7 +30,7 @@
#define EIGEN_WORLD_VERSION 2 #define EIGEN_WORLD_VERSION 2
#define EIGEN_MAJOR_VERSION 0 #define EIGEN_MAJOR_VERSION 0
#define EIGEN_MINOR_VERSION 11 #define EIGEN_MINOR_VERSION 12
#define EIGEN_VERSION_AT_LEAST(x,y,z) (EIGEN_WORLD_VERSION>x || (EIGEN_WORLD_VERSION>=x && \ #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_MAJOR_VERSION>y || (EIGEN_MAJOR_VERSION>=y && \
@@ -257,6 +257,9 @@ enum { RowsAtCompileTime = Eigen::ei_traits<Derived>::RowsAtCompileTime, \
_EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, Eigen::MatrixBase<Derived>) _EIGEN_GENERIC_PUBLIC_INTERFACE(Derived, Eigen::MatrixBase<Derived>)
#define EIGEN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b) #define EIGEN_ENUM_MIN(a,b) (((int)a <= (int)b) ? (int)a : (int)b)
#define EIGEN_SIZE_MIN(a,b) (((int)a == 1 || (int)b == 1) ? 1 \
: ((int)a == Dynamic || (int)b == Dynamic) ? Dynamic \
: ((int)a <= (int)b) ? (int)a : (int)b)
#define EIGEN_ENUM_MAX(a,b) (((int)a >= (int)b) ? (int)a : (int)b) #define EIGEN_ENUM_MAX(a,b) (((int)a >= (int)b) ? (int)a : (int)b)
// just an empty macro ! // just an empty macro !

View File

@@ -59,10 +59,10 @@
* Fast, but wastes 16 additional bytes of memory. * Fast, but wastes 16 additional bytes of memory.
* Does not throw any exception. * Does not throw any exception.
*/ */
inline void* ei_handmade_aligned_malloc(size_t size) inline void* ei_handmade_aligned_malloc(std::size_t size)
{ {
void *original = malloc(size+16); void *original = std::malloc(size+16);
void *aligned = reinterpret_cast<void*>((reinterpret_cast<size_t>(original) & ~(size_t(15))) + 16); void *aligned = reinterpret_cast<void*>((reinterpret_cast<std::size_t>(original) & ~(std::size_t(15))) + 16);
*(reinterpret_cast<void**>(aligned) - 1) = original; *(reinterpret_cast<void**>(aligned) - 1) = original;
return aligned; return aligned;
} }
@@ -71,13 +71,13 @@ inline void* ei_handmade_aligned_malloc(size_t size)
inline void ei_handmade_aligned_free(void *ptr) inline void ei_handmade_aligned_free(void *ptr)
{ {
if(ptr) if(ptr)
free(*(reinterpret_cast<void**>(ptr) - 1)); std::free(*(reinterpret_cast<void**>(ptr) - 1));
} }
/** \internal allocates \a size bytes. The returned pointer is guaranteed to have 16 bytes alignment. /** \internal allocates \a size bytes. The returned pointer is guaranteed to have 16 bytes alignment.
* On allocation error, the returned pointer is null, and if exceptions are enabled then a std::bad_alloc is thrown. * On allocation error, the returned pointer is null, and if exceptions are enabled then a std::bad_alloc is thrown.
*/ */
inline void* ei_aligned_malloc(size_t size) inline void* ei_aligned_malloc(std::size_t size)
{ {
#ifdef EIGEN_NO_MALLOC #ifdef EIGEN_NO_MALLOC
ei_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)"); ei_assert(false && "heap allocation is forbidden (EIGEN_NO_MALLOC is defined)");
@@ -108,18 +108,18 @@ inline void* ei_aligned_malloc(size_t size)
/** allocates \a size bytes. If Align is true, then the returned ptr is 16-byte-aligned. /** allocates \a size bytes. If Align is true, then the returned ptr is 16-byte-aligned.
* On allocation error, the returned pointer is null, and if exceptions are enabled then a std::bad_alloc is thrown. * On allocation error, the returned pointer is null, and if exceptions are enabled then a std::bad_alloc is thrown.
*/ */
template<bool Align> inline void* ei_conditional_aligned_malloc(size_t size) template<bool Align> inline void* ei_conditional_aligned_malloc(std::size_t size)
{ {
return ei_aligned_malloc(size); return ei_aligned_malloc(size);
} }
template<> inline void* ei_conditional_aligned_malloc<false>(size_t size) template<> inline void* ei_conditional_aligned_malloc<false>(std::size_t size)
{ {
#ifdef EIGEN_NO_MALLOC #ifdef EIGEN_NO_MALLOC
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 *result = malloc(size); void *result = std::malloc(size);
#ifdef EIGEN_EXCEPTIONS #ifdef EIGEN_EXCEPTIONS
if(!result) throw std::bad_alloc(); if(!result) throw std::bad_alloc();
#endif #endif
@@ -129,9 +129,9 @@ template<> inline void* ei_conditional_aligned_malloc<false>(size_t size)
/** \internal construct the elements of an array. /** \internal construct the elements of an array.
* The \a size parameter tells on how many objects to call the constructor of T. * The \a size parameter tells on how many objects to call the constructor of T.
*/ */
template<typename T> inline T* ei_construct_elements_of_array(T *ptr, size_t size) template<typename T> inline T* ei_construct_elements_of_array(T *ptr, std::size_t size)
{ {
for (size_t i=0; i < size; ++i) ::new (ptr + i) T; for (std::size_t i=0; i < size; ++i) ::new (ptr + i) T;
return ptr; return ptr;
} }
@@ -139,13 +139,13 @@ template<typename T> inline T* ei_construct_elements_of_array(T *ptr, size_t siz
* On allocation error, the returned pointer is undefined, but if exceptions are enabled then a std::bad_alloc is thrown. * On allocation error, the returned pointer is undefined, but if exceptions are enabled then a std::bad_alloc is thrown.
* The default constructor of T is called. * The default constructor of T is called.
*/ */
template<typename T> inline T* ei_aligned_new(size_t size) template<typename T> inline T* ei_aligned_new(std::size_t size)
{ {
T *result = reinterpret_cast<T*>(ei_aligned_malloc(sizeof(T)*size)); T *result = reinterpret_cast<T*>(ei_aligned_malloc(sizeof(T)*size));
return ei_construct_elements_of_array(result, size); return ei_construct_elements_of_array(result, size);
} }
template<typename T, bool Align> inline T* ei_conditional_aligned_new(size_t size) template<typename T, bool Align> inline T* ei_conditional_aligned_new(std::size_t size)
{ {
T *result = reinterpret_cast<T*>(ei_conditional_aligned_malloc<Align>(sizeof(T)*size)); T *result = reinterpret_cast<T*>(ei_conditional_aligned_malloc<Align>(sizeof(T)*size));
return ei_construct_elements_of_array(result, size); return ei_construct_elements_of_array(result, size);
@@ -179,13 +179,13 @@ template<bool Align> inline void ei_conditional_aligned_free(void *ptr)
template<> inline void ei_conditional_aligned_free<false>(void *ptr) template<> inline void ei_conditional_aligned_free<false>(void *ptr)
{ {
free(ptr); std::free(ptr);
} }
/** \internal destruct the elements of an array. /** \internal destruct the elements of an array.
* The \a size parameters tells on how many objects to call the destructor of T. * The \a size parameters tells on how many objects to call the destructor of T.
*/ */
template<typename T> inline void ei_destruct_elements_of_array(T *ptr, size_t size) template<typename T> inline void ei_destruct_elements_of_array(T *ptr, std::size_t size)
{ {
// always destruct an array starting from the end. // always destruct an array starting from the end.
while(size) ptr[--size].~T(); while(size) ptr[--size].~T();
@@ -194,7 +194,7 @@ template<typename T> inline void ei_destruct_elements_of_array(T *ptr, size_t si
/** \internal delete objects constructed with ei_aligned_new /** \internal delete objects constructed with ei_aligned_new
* The \a size parameters tells on how many objects to call the destructor of T. * The \a size parameters tells on how many objects to call the destructor of T.
*/ */
template<typename T> inline void ei_aligned_delete(T *ptr, size_t size) template<typename T> inline void ei_aligned_delete(T *ptr, std::size_t size)
{ {
ei_destruct_elements_of_array<T>(ptr, size); ei_destruct_elements_of_array<T>(ptr, size);
ei_aligned_free(ptr); ei_aligned_free(ptr);
@@ -203,7 +203,7 @@ template<typename T> inline void ei_aligned_delete(T *ptr, size_t size)
/** \internal delete objects constructed with ei_conditional_aligned_new /** \internal delete objects constructed with ei_conditional_aligned_new
* The \a size parameters tells on how many objects to call the destructor of T. * The \a size parameters tells on how many objects to call the destructor of T.
*/ */
template<typename T, bool Align> inline void ei_conditional_aligned_delete(T *ptr, size_t size) template<typename T, bool Align> inline void ei_conditional_aligned_delete(T *ptr, std::size_t size)
{ {
ei_destruct_elements_of_array<T>(ptr, size); ei_destruct_elements_of_array<T>(ptr, size);
ei_conditional_aligned_free<Align>(ptr); ei_conditional_aligned_free<Align>(ptr);
@@ -281,23 +281,23 @@ inline static Integer ei_alignmentOffset(const Scalar* array, Integer size)
#if EIGEN_ALIGN #if EIGEN_ALIGN
#ifdef EIGEN_EXCEPTIONS #ifdef EIGEN_EXCEPTIONS
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \ #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
void* operator new(size_t size, const std::nothrow_t&) throw() { \ void* operator new(std::size_t size, const std::nothrow_t&) throw() { \
try { return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); } \ try { return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); } \
catch (...) { return 0; } \ catch (...) { return 0; } \
return 0; \ return 0; \
} }
#else #else
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \ #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
void* operator new(size_t size, const std::nothrow_t&) throw() { \ void* operator new(std::size_t size, const std::nothrow_t&) throw() { \
return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); \ return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); \
} }
#endif #endif
#define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) \ #define EIGEN_MAKE_ALIGNED_OPERATOR_NEW_IF(NeedsToAlign) \
void *operator new(size_t size) { \ void *operator new(std::size_t size) { \
return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); \ return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); \
} \ } \
void *operator new[](size_t size) { \ void *operator new[](std::size_t size) { \
return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); \ return Eigen::ei_conditional_aligned_malloc<NeedsToAlign>(size); \
} \ } \
void operator delete(void * ptr) throw() { Eigen::ei_conditional_aligned_free<NeedsToAlign>(ptr); } \ void operator delete(void * ptr) throw() { Eigen::ei_conditional_aligned_free<NeedsToAlign>(ptr); } \
@@ -305,7 +305,7 @@ inline static Integer ei_alignmentOffset(const Scalar* array, Integer size)
/* in-place new and delete. since (at least afaik) there is no actual */ \ /* in-place new and delete. since (at least afaik) there is no actual */ \
/* memory allocated we can safely let the default implementation handle */ \ /* memory allocated we can safely let the default implementation handle */ \
/* this particular case. */ \ /* this particular case. */ \
static void *operator new(size_t size, void *ptr) { return ::operator new(size,ptr); } \ static void *operator new(std::size_t size, void *ptr) { return ::operator new(size,ptr); } \
void operator delete(void * memory, void *ptr) throw() { return ::operator delete(memory,ptr); } \ void operator delete(void * memory, void *ptr) throw() { return ::operator delete(memory,ptr); } \
/* nothrow-new (returns zero instead of std::bad_alloc) */ \ /* nothrow-new (returns zero instead of std::bad_alloc) */ \
EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \ EIGEN_MAKE_ALIGNED_OPERATOR_NEW_NOTHROW(NeedsToAlign) \
@@ -339,8 +339,8 @@ template<class T>
class aligned_allocator class aligned_allocator
{ {
public: public:
typedef size_t size_type; typedef std::size_t size_type;
typedef ptrdiff_t difference_type; typedef std::ptrdiff_t difference_type;
typedef T* pointer; typedef T* pointer;
typedef const T* const_pointer; typedef const T* const_pointer;
typedef T& reference; typedef T& reference;

View File

@@ -161,6 +161,19 @@ template<typename T> struct ei_plain_matrix_type_column_major
> type; > type;
}; };
/* ei_plain_matrix_type_row_major : same as ei_plain_matrix_type but guaranteed to be row-major
*/
template<typename T> struct ei_plain_matrix_type_row_major
{
typedef Matrix<typename ei_traits<T>::Scalar,
ei_traits<T>::RowsAtCompileTime,
ei_traits<T>::ColsAtCompileTime,
AutoAlign | RowMajor,
ei_traits<T>::MaxRowsAtCompileTime,
ei_traits<T>::MaxColsAtCompileTime
> type;
};
template<typename T> struct ei_must_nest_by_value { enum { ret = false }; }; template<typename T> struct ei_must_nest_by_value { enum { ret = false }; };
template<typename T> struct ei_must_nest_by_value<NestByValue<T> > { enum { ret = true }; }; template<typename T> struct ei_must_nest_by_value<NestByValue<T> > { enum { ret = true }; };

View File

@@ -54,10 +54,10 @@ bool ei_compute_inverse_in_size2_case_with_check(const XprType& matrix, MatrixTy
return true; return true;
} }
template<typename MatrixType> template<typename Derived, typename OtherDerived>
void ei_compute_inverse_in_size3_case(const MatrixType& matrix, MatrixType* result) void ei_compute_inverse_in_size3_case(const Derived& matrix, OtherDerived* result)
{ {
typedef typename MatrixType::Scalar Scalar; typedef typename Derived::Scalar Scalar;
const Scalar det_minor00 = matrix.minor(0,0).determinant(); const Scalar det_minor00 = matrix.minor(0,0).determinant();
const Scalar det_minor10 = matrix.minor(1,0).determinant(); const Scalar det_minor10 = matrix.minor(1,0).determinant();
const Scalar det_minor20 = matrix.minor(2,0).determinant(); const Scalar det_minor20 = matrix.minor(2,0).determinant();
@@ -75,10 +75,10 @@ void ei_compute_inverse_in_size3_case(const MatrixType& matrix, MatrixType* resu
result->coeffRef(2, 2) = matrix.minor(2,2).determinant() * invdet; result->coeffRef(2, 2) = matrix.minor(2,2).determinant() * invdet;
} }
template<typename MatrixType, typename Scalar = typename MatrixType::Scalar> template<typename Derived, typename OtherDerived, typename Scalar = typename Derived::Scalar>
struct ei_compute_inverse_in_size4_case struct ei_compute_inverse_in_size4_case
{ {
static void run(const MatrixType& matrix, MatrixType& result) static void run(const Derived& matrix, OtherDerived& result)
{ {
result.coeffRef(0,0) = matrix.minor(0,0).determinant(); result.coeffRef(0,0) = matrix.minor(0,0).determinant();
result.coeffRef(1,0) = -matrix.minor(0,1).determinant(); result.coeffRef(1,0) = -matrix.minor(0,1).determinant();
@@ -109,10 +109,10 @@ struct ei_compute_inverse_in_size4_case
// here that if Intel makes this document publically available, with source code // here that if Intel makes this document publically available, with source code
// and detailed explanations, it's because they want their CPUs to be fed with // and detailed explanations, it's because they want their CPUs to be fed with
// good code, and therefore they presumably don't mind us using it in Eigen. // good code, and therefore they presumably don't mind us using it in Eigen.
template<typename MatrixType> template<typename Derived, typename OtherDerived>
struct ei_compute_inverse_in_size4_case<MatrixType, float> struct ei_compute_inverse_in_size4_case<Derived, OtherDerived, float>
{ {
static void run(const MatrixType& matrix, MatrixType& result) static void run(const Derived& matrix, OtherDerived& result)
{ {
// Variables (Streaming SIMD Extensions registers) which will contain cofactors and, later, the // Variables (Streaming SIMD Extensions registers) which will contain cofactors and, later, the
// lines of the inverted matrix. // lines of the inverted matrix.
@@ -229,50 +229,50 @@ struct ei_compute_inverse_in_size4_case<MatrixType, float>
*** Part 2 : selector and MatrixBase methods *** *** Part 2 : selector and MatrixBase methods ***
***********************************************/ ***********************************************/
template<typename MatrixType, int Size = MatrixType::RowsAtCompileTime> template<typename Derived, typename OtherDerived, int Size = Derived::RowsAtCompileTime>
struct ei_compute_inverse struct ei_compute_inverse
{ {
static inline void run(const MatrixType& matrix, MatrixType* result) static inline void run(const Derived& matrix, OtherDerived* result)
{ {
LU<MatrixType> lu(matrix); LU<Derived> lu(matrix);
lu.computeInverse(result); lu.computeInverse(result);
} }
}; };
template<typename MatrixType> template<typename Derived, typename OtherDerived>
struct ei_compute_inverse<MatrixType, 1> struct ei_compute_inverse<Derived, OtherDerived, 1>
{ {
static inline void run(const MatrixType& matrix, MatrixType* result) static inline void run(const Derived& matrix, OtherDerived* result)
{ {
typedef typename MatrixType::Scalar Scalar; typedef typename Derived::Scalar Scalar;
result->coeffRef(0,0) = Scalar(1) / matrix.coeff(0,0); result->coeffRef(0,0) = Scalar(1) / matrix.coeff(0,0);
} }
}; };
template<typename MatrixType> template<typename Derived, typename OtherDerived>
struct ei_compute_inverse<MatrixType, 2> struct ei_compute_inverse<Derived, OtherDerived, 2>
{ {
static inline void run(const MatrixType& matrix, MatrixType* result) static inline void run(const Derived& matrix, OtherDerived* result)
{ {
ei_compute_inverse_in_size2_case(matrix, result); ei_compute_inverse_in_size2_case(matrix, result);
} }
}; };
template<typename MatrixType> template<typename Derived, typename OtherDerived>
struct ei_compute_inverse<MatrixType, 3> struct ei_compute_inverse<Derived, OtherDerived, 3>
{ {
static inline void run(const MatrixType& matrix, MatrixType* result) static inline void run(const Derived& matrix, OtherDerived* result)
{ {
ei_compute_inverse_in_size3_case(matrix, result); ei_compute_inverse_in_size3_case(matrix, result);
} }
}; };
template<typename MatrixType> template<typename Derived, typename OtherDerived>
struct ei_compute_inverse<MatrixType, 4> struct ei_compute_inverse<Derived, OtherDerived, 4>
{ {
static inline void run(const MatrixType& matrix, MatrixType* result) static inline void run(const Derived& matrix, OtherDerived* result)
{ {
ei_compute_inverse_in_size4_case<MatrixType>::run(matrix, *result); ei_compute_inverse_in_size4_case<Derived, OtherDerived>::run(matrix, *result);
} }
}; };
@@ -290,11 +290,12 @@ struct ei_compute_inverse<MatrixType, 4>
* \sa inverse() * \sa inverse()
*/ */
template<typename Derived> template<typename Derived>
inline void MatrixBase<Derived>::computeInverse(PlainMatrixType *result) const template<typename OtherDerived>
inline void MatrixBase<Derived>::computeInverse(MatrixBase<OtherDerived> *result) const
{ {
ei_assert(rows() == cols()); ei_assert(rows() == cols());
EIGEN_STATIC_ASSERT(NumTraits<Scalar>::HasFloatingPoint,NUMERIC_TYPE_MUST_BE_FLOATING_POINT) EIGEN_STATIC_ASSERT(NumTraits<Scalar>::HasFloatingPoint,NUMERIC_TYPE_MUST_BE_FLOATING_POINT)
ei_compute_inverse<PlainMatrixType>::run(eval(), result); ei_compute_inverse<PlainMatrixType, OtherDerived>::run(eval(), static_cast<OtherDerived*>(result));
} }
/** \lu_module /** \lu_module

View File

@@ -68,7 +68,7 @@ template<typename MatrixType> class LU
typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType; typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType; typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType;
enum { MaxSmallDimAtCompileTime = EIGEN_ENUM_MIN( enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN(
MatrixType::MaxColsAtCompileTime, MatrixType::MaxColsAtCompileTime,
MatrixType::MaxRowsAtCompileTime) MatrixType::MaxRowsAtCompileTime)
}; };
@@ -297,7 +297,8 @@ template<typename MatrixType> class LU
* *
* \sa MatrixBase::computeInverse(), inverse() * \sa MatrixBase::computeInverse(), inverse()
*/ */
inline void computeInverse(MatrixType *result) const template<typename ResultType>
inline void computeInverse(ResultType *result) const
{ {
solve(MatrixType::Identity(m_lu.rows(), m_lu.cols()), result); solve(MatrixType::Identity(m_lu.rows(), m_lu.cols()), result);
} }
@@ -508,7 +509,7 @@ bool LU<MatrixType>::solve(
if(!isSurjective()) if(!isSurjective())
{ {
// is c is in the image of U ? // is c is in the image of U ?
RealScalar biggest_in_c = m_rank>0 ? c.corner(TopLeft, m_rank, c.cols()).cwise().abs().maxCoeff() : 0; RealScalar biggest_in_c = m_rank>0 ? c.corner(TopLeft, m_rank, c.cols()).cwise().abs().maxCoeff() : RealScalar(0);
for(int col = 0; col < c.cols(); ++col) for(int col = 0; col < c.cols(); ++col)
for(int row = m_rank; row < c.rows(); ++row) for(int row = m_rank; row < c.rows(); ++row)
if(!ei_isMuchSmallerThan(c.coeff(row,col), biggest_in_c, m_precision)) if(!ei_isMuchSmallerThan(c.coeff(row,col), biggest_in_c, m_precision))

View File

@@ -293,7 +293,7 @@ void Tridiagonalization<MatrixType>::_compute(MatrixType& matA, CoeffVectorType&
{ {
int starti = i+1; int starti = i+1;
int alignedEnd = starti; int alignedEnd = starti;
if (PacketSize>1) if (PacketSize>1 && (int(MatrixType::Flags)&RowMajor) == 0)
{ {
int alignedStart = (starti) + ei_alignmentOffset(&matA.coeffRef(starti,j1), n-starti); int alignedStart = (starti) + ei_alignmentOffset(&matA.coeffRef(starti,j1), n-starti);
alignedEnd = alignedStart + ((n-alignedStart)/PacketSize)*PacketSize; alignedEnd = alignedStart + ((n-alignedStart)/PacketSize)*PacketSize;

View File

@@ -49,7 +49,7 @@ template<typename MatrixType> class SVD
enum { enum {
PacketSize = ei_packet_traits<Scalar>::size, PacketSize = ei_packet_traits<Scalar>::size,
AlignmentMask = int(PacketSize)-1, AlignmentMask = int(PacketSize)-1,
MinSize = EIGEN_ENUM_MIN(MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime) MinSize = EIGEN_SIZE_MIN(MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime)
}; };
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVector; typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVector;

View File

@@ -97,7 +97,7 @@ struct ei_traits<SparseProduct<LhsNested, RhsNested, ProductMode> >
RowsAtCompileTime = _LhsNested::RowsAtCompileTime, RowsAtCompileTime = _LhsNested::RowsAtCompileTime,
ColsAtCompileTime = _RhsNested::ColsAtCompileTime, ColsAtCompileTime = _RhsNested::ColsAtCompileTime,
InnerSize = EIGEN_ENUM_MIN(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime), InnerSize = EIGEN_SIZE_MIN(_LhsNested::ColsAtCompileTime, _RhsNested::RowsAtCompileTime),
MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime, MaxRowsAtCompileTime = _LhsNested::MaxRowsAtCompileTime,
MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime, MaxColsAtCompileTime = _RhsNested::MaxColsAtCompileTime,

View File

@@ -1,8 +1,8 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project. // for linear algebra.
// //
// Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr> // Copyright (C) 2008 Gael Guennebaud <g.gael@free.fr>
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@@ -26,8 +26,15 @@
#ifndef EIGEN_BENCH_TIMER_H #ifndef EIGEN_BENCH_TIMER_H
#define EIGEN_BENCH_TIMER_H #define EIGEN_BENCH_TIMER_H
#include <sys/time.h> #if defined(_WIN32) || defined(__CYGWIN__)
#define NOMINMAX
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#else
#include <time.h>
#include <unistd.h> #include <unistd.h>
#endif
#include <cstdlib> #include <cstdlib>
#include <numeric> #include <numeric>
@@ -35,12 +42,25 @@ namespace Eigen
{ {
/** Elapsed time timer keeping the best try. /** Elapsed time timer keeping the best try.
*
* On POSIX platforms we use clock_gettime with CLOCK_PROCESS_CPUTIME_ID.
* On Windows we use QueryPerformanceCounter
*
* Important: on linux, you must link with -lrt
*/ */
class BenchTimer class BenchTimer
{ {
public: public:
BenchTimer() { reset(); } BenchTimer()
{
#if defined(_WIN32) || defined(__CYGWIN__)
LARGE_INTEGER freq;
QueryPerformanceFrequency(&freq);
m_frequency = (double)freq.QuadPart;
#endif
reset();
}
~BenchTimer() {} ~BenchTimer() {}
@@ -51,23 +71,34 @@ public:
m_best = std::min(m_best, getTime() - m_start); m_best = std::min(m_best, getTime() - m_start);
} }
/** Return the best elapsed time. /** Return the best elapsed time in seconds.
*/ */
inline double value(void) inline double value(void)
{ {
return m_best; return m_best;
} }
#if defined(_WIN32) || defined(__CYGWIN__)
inline double getTime(void)
#else
static inline double getTime(void) static inline double getTime(void)
#endif
{ {
struct timeval tv; #ifdef WIN32
struct timezone tz; LARGE_INTEGER query_ticks;
gettimeofday(&tv, &tz); QueryPerformanceCounter(&query_ticks);
return (double)tv.tv_sec + 1.e-6 * (double)tv.tv_usec; return query_ticks.QuadPart/m_frequency;
#else
timespec ts;
clock_gettime(CLOCK_PROCESS_CPUTIME_ID, &ts);
return double(ts.tv_sec) + 1e-9 * double(ts.tv_nsec);
#endif
} }
protected: protected:
#if defined(_WIN32) || defined(__CYGWIN__)
double m_frequency;
#endif
double m_best, m_start; double m_best, m_start;
}; };

View File

@@ -57,10 +57,10 @@ void makeFloor(const MatrixBase<OtherDerived>& other) { derived() = derived().cw
template<typename OtherDerived> template<typename OtherDerived>
void makeCeil(const MatrixBase<OtherDerived>& other) { derived() = derived().cwise().max(other.derived()); } void makeCeil(const MatrixBase<OtherDerived>& other) { derived() = derived().cwise().max(other.derived()); }
const typename Cwise<Derived>::ScalarAddReturnType const const CwiseUnaryOp<ei_scalar_add_op<Scalar>, Derived>
operator+(const Scalar& scalar) const { return cwise() + scalar } operator+(const Scalar& scalar) const { return cwise() + scalar; }
friend const typename Cwise<Derived>::ScalarAddReturnType friend const CwiseUnaryOp<ei_scalar_add_op<Scalar>, Derived>
operator+(const Scalar& scalar, const MatrixBase<Derived>& mat) { return mat + scalar; } operator+(const Scalar& scalar, const MatrixBase<Derived>& mat) { return mat + scalar; }
\endcode \endcode

View File

@@ -1,8 +1,5 @@
#!/bin/sh #!/bin/sh
# TODO : actually exit on exit, currently it only exit from the ()
# TODO : display error msg on stderr instead of stdout
# configuration # configuration
# You should call this script with USER set as you want, else some default # You should call this script with USER set as you want, else some default
# will be used # will be used
@@ -11,16 +8,12 @@ USER=${USER:-'orzel'}
# step 1 : build # step 1 : build
# todo if 'build is not there, create one: # todo if 'build is not there, create one:
#mkdir build #mkdir build
(cd build && cmake .. && make -j3 doc) || echo "make failed"; exit 1 (cd build && cmake .. && make -j3 doc) || { echo "make failed"; exit 1; }
#todo: n+1 where n = number of cpus #todo: n+1 where n = number of cpus
#step 2 : upload #step 2 : upload
BRANCH=`hg branch`
if [ $BRANCH == "default" ]
then
BRANCH='devel'
fi
# (the '/' at the end of path are very important, see rsync documentation) # (the '/' at the end of path are very important, see rsync documentation)
rsync -az build/doc/html/ $USER@ssh.tuxfamily.org:eigen/eigen.tuxfamily.org-web/htdocs/dox-$BRANCH/ || (echo "upload failed"; exit 1) rsync -az build/doc/html/ $USER@ssh.tuxfamily.org:eigen/eigen.tuxfamily.org-web/htdocs/dox-2.0/ || { echo "upload failed"; exit 1; }
echo "Uploaded successfully"

View File

@@ -1,3 +1,7 @@
option(EIGEN_DEFAULT_TO_ROW_MAJOR "Use row-major as default matrix storage order" OFF)
if(EIGEN_DEFAULT_TO_ROW_MAJOR)
add_definitions("-DEIGEN_DEFAULT_TO_ROW_MAJOR")
endif()
find_package(GSL) find_package(GSL)
if(GSL_FOUND AND GSL_VERSION_MINOR LESS 9) if(GSL_FOUND AND GSL_VERSION_MINOR LESS 9)
@@ -93,12 +97,20 @@ else(CMAKE_COMPILER_IS_GNUCXX)
endif(CMAKE_COMPILER_IS_GNUCXX) endif(CMAKE_COMPILER_IS_GNUCXX)
option(EIGEN_NO_ASSERTION_CHECKING "Disable checking of assertions" OFF) option(EIGEN_NO_ASSERTION_CHECKING "Disable checking of assertions" OFF)
if(EIGEN_NO_ASSERTION_CHECKING)
add_definitions("-DEIGEN_NO_ASSERTION_CHECKING=1")
endif()
# similar to set_target_properties but append the property instead of overwriting it # similar to set_target_properties but append the property instead of overwriting it
macro(ei_add_target_property target prop value) macro(ei_add_target_property target prop value)
get_target_property(previous ${target} ${prop}) get_target_property(previous ${target} ${prop})
if(previous MATCHES "NOTFOUND")
set_target_properties(${target} PROPERTIES ${prop} "${value}")
else()
set_target_properties(${target} PROPERTIES ${prop} "${previous} ${value}") set_target_properties(${target} PROPERTIES ${prop} "${previous} ${value}")
endif()
endmacro(ei_add_target_property) endmacro(ei_add_target_property)
@@ -134,13 +146,9 @@ macro(ei_add_test testname)
option(EIGEN_DEBUG_ASSERTS "Enable debuging of assertions" OFF) option(EIGEN_DEBUG_ASSERTS "Enable debuging of assertions" OFF)
if(EIGEN_DEBUG_ASSERTS) if(EIGEN_DEBUG_ASSERTS)
set_target_properties(${targetname} PROPERTIES COMPILE_DEFINITIONS "-DEIGEN_DEBUG_ASSERTS=1") set_target_properties(${targetname} PROPERTIES COMPILE_DEFINITIONS "EIGEN_DEBUG_ASSERTS=1")
endif(EIGEN_DEBUG_ASSERTS) endif(EIGEN_DEBUG_ASSERTS)
else(NOT EIGEN_NO_ASSERTION_CHECKING)
set_target_properties(${targetname} PROPERTIES COMPILE_DEFINITIONS "-DEIGEN_NO_ASSERTION_CHECKING=1")
endif(NOT EIGEN_NO_ASSERTION_CHECKING) endif(NOT EIGEN_NO_ASSERTION_CHECKING)
if(${ARGC} GREATER 1) if(${ARGC} GREATER 1)
@@ -201,7 +209,7 @@ ei_add_test(array)
ei_add_test(triangular) ei_add_test(triangular)
ei_add_test(cholesky " " "${GSL_LIBRARIES}") ei_add_test(cholesky " " "${GSL_LIBRARIES}")
ei_add_test(lu ${EI_OFLAG}) ei_add_test(lu ${EI_OFLAG})
ei_add_test(determinant) ei_add_test(determinant ${EI_OFLAG})
ei_add_test(inverse) ei_add_test(inverse)
ei_add_test(qr) ei_add_test(qr)
ei_add_test(eigensolver " " "${GSL_LIBRARIES}") ei_add_test(eigensolver " " "${GSL_LIBRARIES}")
@@ -216,10 +224,12 @@ ei_add_test(newstdvector)
if(QT4_FOUND) if(QT4_FOUND)
ei_add_test(qtvector " " "${QT_QTCORE_LIBRARY}") ei_add_test(qtvector " " "${QT_QTCORE_LIBRARY}")
endif(QT4_FOUND) endif(QT4_FOUND)
if(NOT EIGEN_DEFAULT_TO_ROW_MAJOR)
ei_add_test(sparse_vector) ei_add_test(sparse_vector)
ei_add_test(sparse_basic) ei_add_test(sparse_basic)
ei_add_test(sparse_solvers " " "${SPARSE_LIBS}") ei_add_test(sparse_solvers " " "${SPARSE_LIBS}")
ei_add_test(sparse_product) ei_add_test(sparse_product)
endif()
ei_add_test(swap) ei_add_test(swap)
ei_add_test(visitor) ei_add_test(visitor)
@@ -268,6 +278,12 @@ else(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)
message("Explicit vec: AUTO") message("Explicit vec: AUTO")
endif(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION) endif(EIGEN_TEST_NO_EXPLICIT_VECTORIZATION)
if(EIGEN_DEFAULT_TO_ROW_MAJOR)
message("Default order: Row-major")
else()
message("Default order: Column-major")
endif()
message("CXX: ${CMAKE_CXX_COMPILER}") message("CXX: ${CMAKE_CXX_COMPILER}")
if(CMAKE_COMPILER_IS_GNUCXX) if(CMAKE_COMPILER_IS_GNUCXX)
execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version COMMAND head -n 1 OUTPUT_VARIABLE EIGEN_CXX_VERSION_STRING OUTPUT_STRIP_TRAILING_WHITESPACE) execute_process(COMMAND ${CMAKE_CXX_COMPILER} --version COMMAND head -n 1 OUTPUT_VARIABLE EIGEN_CXX_VERSION_STRING OUTPUT_STRIP_TRAILING_WHITESPACE)

View File

@@ -50,9 +50,9 @@ void test_first_aligned()
test_first_aligned_helper(array_float+5, 50); test_first_aligned_helper(array_float+5, 50);
EIGEN_ALIGN_128 double array_double[100]; EIGEN_ALIGN_128 double array_double[100];
test_first_aligned_helper(array_float, 50); test_first_aligned_helper(array_double, 50);
test_first_aligned_helper(array_float+1, 50); test_first_aligned_helper(array_double+1, 50);
test_first_aligned_helper(array_float+2, 50); test_first_aligned_helper(array_double+2, 50);
double *array_double_plus_4_bytes = (double*)(size_t(array_double)+4); double *array_double_plus_4_bytes = (double*)(size_t(array_double)+4);
test_none_aligned_helper(array_double_plus_4_bytes, 50); test_none_aligned_helper(array_double_plus_4_bytes, 50);

View File

@@ -43,11 +43,9 @@ template<typename MatrixType> void inverse(const MatrixType& m)
mzero = MatrixType::Zero(rows, cols), mzero = MatrixType::Zero(rows, cols),
identity = MatrixType::Identity(rows, rows); identity = MatrixType::Identity(rows, rows);
if (ei_is_same_type<RealScalar,float>::ret) while(ei_abs(m1.determinant()) < RealScalar(0.1) && rows <= 8)
{ {
// let's build a more stable to inverse matrix m1 = MatrixType::Random(rows, cols);
MatrixType a = MatrixType::Random(rows,cols);
m1 += m1 * m1.adjoint() + a * a.adjoint();
} }
m2 = m1.inverse(); m2 = m1.inverse();

View File

@@ -1,7 +1,7 @@
// This file is part of Eigen, a lightweight C++ template library // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project. // for linear algebra. Eigen itself is part of the KDE project.
// //
// Copyright (C) 2006-2008 Benoit Jacob <jacob.benoit.1@gmail.com> // Copyright (C) 2007-2010 Benoit Jacob <jacob.benoit.1@gmail.com>
// //
// Eigen is free software; you can redistribute it and/or // Eigen is free software; you can redistribute it and/or
// modify it under the terms of the GNU Lesser General Public // modify it under the terms of the GNU Lesser General Public
@@ -24,7 +24,7 @@
#include "main.h" #include "main.h"
template<typename VectorType> void map_class(const VectorType& m) template<typename VectorType> void map_class_vector(const VectorType& m)
{ {
typedef typename VectorType::Scalar Scalar; typedef typename VectorType::Scalar Scalar;
@@ -50,6 +50,34 @@ template<typename VectorType> void map_class(const VectorType& m)
delete[] array3; delete[] array3;
} }
template<typename MatrixType> void map_class_matrix(const MatrixType& m)
{
typedef typename MatrixType::Scalar Scalar;
int rows = m.rows(), cols = m.cols(), size = rows*cols;
// test Map.h
Scalar* array1 = ei_aligned_new<Scalar>(size);
for(int i = 0; i < size; i++) array1[i] = Scalar(1);
Scalar* array2 = ei_aligned_new<Scalar>(size);
for(int i = 0; i < size; i++) array2[i] = Scalar(1);
Scalar* array3 = new Scalar[size+1];
for(int i = 0; i < size+1; i++) array3[i] = Scalar(1);
Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;
Map<MatrixType, Aligned>(array1, rows, cols) = MatrixType::Ones(rows,cols);
Map<MatrixType>(array2, rows, cols) = Map<MatrixType>(array1, rows, cols);
Map<MatrixType>(array3unaligned, rows, cols) = Map<MatrixType>(array1, rows, cols);
MatrixType ma1 = Map<MatrixType>(array1, rows, cols);
MatrixType ma2 = Map<MatrixType, Aligned>(array2, rows, cols);
VERIFY_IS_APPROX(ma1, ma2);
MatrixType ma3 = Map<MatrixType>(array3unaligned, rows, cols);
VERIFY_IS_APPROX(ma1, ma3);
ei_aligned_delete(array1, size);
ei_aligned_delete(array2, size);
delete[] array3;
}
template<typename VectorType> void map_static_methods(const VectorType& m) template<typename VectorType> void map_static_methods(const VectorType& m)
{ {
typedef typename VectorType::Scalar Scalar; typedef typename VectorType::Scalar Scalar;
@@ -80,11 +108,17 @@ template<typename VectorType> void map_static_methods(const VectorType& m)
void test_map() void test_map()
{ {
for(int i = 0; i < g_repeat; i++) { for(int i = 0; i < g_repeat; i++) {
CALL_SUBTEST( map_class(Matrix<float, 1, 1>()) ); CALL_SUBTEST( map_class_vector(Matrix<float, 1, 1>()) );
CALL_SUBTEST( map_class(Vector4d()) ); CALL_SUBTEST( map_class_vector(Vector4d()) );
CALL_SUBTEST( map_class(RowVector4f()) ); CALL_SUBTEST( map_class_vector(RowVector4f()) );
CALL_SUBTEST( map_class(VectorXcf(8)) ); CALL_SUBTEST( map_class_vector(VectorXcf(8)) );
CALL_SUBTEST( map_class(VectorXi(12)) ); CALL_SUBTEST( map_class_vector(VectorXi(12)) );
CALL_SUBTEST( map_class_matrix(Matrix<float, 1, 1>()) );
CALL_SUBTEST( map_class_matrix(Matrix4d()) );
CALL_SUBTEST( map_class_matrix(Matrix<float,3,5>()) );
CALL_SUBTEST( map_class_matrix(MatrixXcf(ei_random<int>(1,10),ei_random<int>(1,10))) );
CALL_SUBTEST( map_class_matrix(MatrixXi(ei_random<int>(1,10),ei_random<int>(1,10))) );
CALL_SUBTEST( map_static_methods(Matrix<double, 1, 1>()) ); CALL_SUBTEST( map_static_methods(Matrix<double, 1, 1>()) );
CALL_SUBTEST( map_static_methods(Vector3f()) ); CALL_SUBTEST( map_static_methods(Vector3f()) );

View File

@@ -46,7 +46,7 @@ template<typename MatrixType> void product(const MatrixType& m)
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> RowSquareMatrixType; typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::RowsAtCompileTime> RowSquareMatrixType;
typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, MatrixType::ColsAtCompileTime> ColSquareMatrixType; typedef Matrix<Scalar, MatrixType::ColsAtCompileTime, MatrixType::ColsAtCompileTime> ColSquareMatrixType;
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime, typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, MatrixType::ColsAtCompileTime,
MatrixType::Flags&RowMajorBit> OtherMajorMatrixType; MatrixType::Options^RowMajor> OtherMajorMatrixType;
int rows = m.rows(); int rows = m.rows();
int cols = m.cols(); int cols = m.cols();
@@ -77,6 +77,7 @@ template<typename MatrixType> void product(const MatrixType& m)
// begin testing Product.h: only associativity for now // begin testing Product.h: only associativity for now
// (we use Transpose.h but this doesn't count as a test for it) // (we use Transpose.h but this doesn't count as a test for it)
VERIFY_IS_APPROX((m1*m1.transpose())*m2, m1*(m1.transpose()*m2)); VERIFY_IS_APPROX((m1*m1.transpose())*m2, m1*(m1.transpose()*m2));
m3 = m1; m3 = m1;
m3 *= m1.transpose() * m2; m3 *= m1.transpose() * m2;
@@ -137,6 +138,7 @@ template<typename MatrixType> void product(const MatrixType& m)
res2 = square2; res2 = square2;
res2 += (m1.transpose() * m2).lazy(); res2 += (m1.transpose() * m2).lazy();
VERIFY_IS_APPROX(res2, square2 + m1.transpose() * m2); VERIFY_IS_APPROX(res2, square2 + m1.transpose() * m2);
if (NumTraits<Scalar>::HasFloatingPoint && std::min(rows,cols)>1) if (NumTraits<Scalar>::HasFloatingPoint && std::min(rows,cols)>1)
{ {
VERIFY(areNotApprox(res2,square2 + m2.transpose() * m1)); VERIFY(areNotApprox(res2,square2 + m2.transpose() * m1));

View File

@@ -44,12 +44,21 @@ void test_vectorization_logic()
#ifdef EIGEN_VECTORIZE #ifdef EIGEN_VECTORIZE
#ifdef EIGEN_DEFAULT_TO_ROW_MAJOR
VERIFY(test_assign(Vector4f(),Vector4f(),
LinearVectorization,CompleteUnrolling));
VERIFY(test_assign(Vector4f(),Vector4f()+Vector4f(),
LinearVectorization,CompleteUnrolling));
VERIFY(test_assign(Vector4f(),Vector4f().cwise() * Vector4f(),
LinearVectorization,CompleteUnrolling));
#else
VERIFY(test_assign(Vector4f(),Vector4f(), VERIFY(test_assign(Vector4f(),Vector4f(),
InnerVectorization,CompleteUnrolling)); InnerVectorization,CompleteUnrolling));
VERIFY(test_assign(Vector4f(),Vector4f()+Vector4f(), VERIFY(test_assign(Vector4f(),Vector4f()+Vector4f(),
InnerVectorization,CompleteUnrolling)); InnerVectorization,CompleteUnrolling));
VERIFY(test_assign(Vector4f(),Vector4f().cwise() * Vector4f(), VERIFY(test_assign(Vector4f(),Vector4f().cwise() * Vector4f(),
InnerVectorization,CompleteUnrolling)); InnerVectorization,CompleteUnrolling));
#endif
VERIFY(test_assign(Matrix4f(),Matrix4f(), VERIFY(test_assign(Matrix4f(),Matrix4f(),
InnerVectorization,CompleteUnrolling)); InnerVectorization,CompleteUnrolling));
@@ -92,8 +101,10 @@ void test_vectorization_logic()
VERIFY(test_sum(Matrix<float,16,16>().block<4,4>(1,2), VERIFY(test_sum(Matrix<float,16,16>().block<4,4>(1,2),
NoVectorization,CompleteUnrolling)); NoVectorization,CompleteUnrolling));
#ifndef EIGEN_DEFAULT_TO_ROW_MAJOR
VERIFY(test_sum(Matrix<float,16,16>().block<8,1>(1,2), VERIFY(test_sum(Matrix<float,16,16>().block<8,1>(1,2),
LinearVectorization,CompleteUnrolling)); LinearVectorization,CompleteUnrolling));
#endif
VERIFY(test_sum(Matrix<double,7,3>(), VERIFY(test_sum(Matrix<double,7,3>(),
NoVectorization,CompleteUnrolling)); NoVectorization,CompleteUnrolling));