mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Compare commits
30 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
e18e51d891 | ||
|
|
58fc972ed3 | ||
|
|
e7b6a4bcba | ||
|
|
eaa81c135a | ||
|
|
ad8b6c2342 | ||
|
|
37fe67372b | ||
|
|
ee499a855c | ||
|
|
bc0ce37395 | ||
|
|
65c0b2a04d | ||
|
|
93d8d0e1b5 | ||
|
|
501063d9e9 | ||
|
|
c76c8d6917 | ||
|
|
0bb8688d70 | ||
|
|
ea87337647 | ||
|
|
12557fb2a2 | ||
|
|
8a95876825 | ||
|
|
82d7c4e1d0 | ||
|
|
8d4b0aae04 | ||
|
|
4785e27d6a | ||
|
|
20b544b444 | ||
|
|
135013c608 | ||
|
|
1625a5e3f8 | ||
|
|
47a61bbd80 | ||
|
|
12bcfae0c5 | ||
|
|
5f42104e0a | ||
|
|
6b3f81b414 | ||
|
|
1f4b8e6a36 | ||
|
|
e1f61b40c8 | ||
|
|
f369dc873e | ||
|
|
c03bca21c4 |
@@ -5,6 +5,7 @@ qrc_*cxx
|
|||||||
*.diff
|
*.diff
|
||||||
diff
|
diff
|
||||||
*.save
|
*.save
|
||||||
|
save
|
||||||
*.old
|
*.old
|
||||||
*.gmo
|
*.gmo
|
||||||
*.qm
|
*.qm
|
||||||
@@ -12,7 +13,7 @@ core
|
|||||||
core.*
|
core.*
|
||||||
*.bak
|
*.bak
|
||||||
*~
|
*~
|
||||||
build
|
build*
|
||||||
*.moc.*
|
*.moc.*
|
||||||
*.moc
|
*.moc
|
||||||
ui_*
|
ui_*
|
||||||
|
|||||||
@@ -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.12")
|
set(EIGEN_VERSION_NUMBER "2.0.14")
|
||||||
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)
|
||||||
@@ -26,6 +26,38 @@ if(EIGEN_BUILD_LIB)
|
|||||||
option(EIGEN_TEST_LIB "Build the unit tests using the library (disable -pedantic)" OFF)
|
option(EIGEN_TEST_LIB "Build the unit tests using the library (disable -pedantic)" OFF)
|
||||||
endif(EIGEN_BUILD_LIB)
|
endif(EIGEN_BUILD_LIB)
|
||||||
|
|
||||||
|
|
||||||
|
#############################################################################
|
||||||
|
# find how to link to the standard libraries #
|
||||||
|
#############################################################################
|
||||||
|
|
||||||
|
find_package(StandardMathLibrary)
|
||||||
|
|
||||||
|
set(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO "")
|
||||||
|
|
||||||
|
if(NOT STANDARD_MATH_LIBRARY_FOUND)
|
||||||
|
|
||||||
|
message(FATAL_ERROR
|
||||||
|
"Can't link to the standard math library. Please report to the Eigen developers, telling them about your platform.")
|
||||||
|
|
||||||
|
else()
|
||||||
|
|
||||||
|
if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)
|
||||||
|
set(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO "${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO} ${STANDARD_MATH_LIBRARY}")
|
||||||
|
else()
|
||||||
|
set(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO "${STANDARD_MATH_LIBRARY}")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)
|
||||||
|
message(STATUS "Standard libraries to link to explicitly: ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO}")
|
||||||
|
else()
|
||||||
|
message(STATUS "Standard libraries to link to explicitly: none")
|
||||||
|
endif()
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
set(CMAKE_INCLUDE_CURRENT_DIR ON)
|
||||||
|
|
||||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
if(CMAKE_COMPILER_IS_GNUCXX)
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
set(Eigen_HEADERS Core LU Cholesky QR Geometry
|
set(Eigen_HEADERS Core LU Cholesky QR Geometry
|
||||||
Sparse Array SVD LeastSquares
|
Sparse Array SVD LeastSquares
|
||||||
QtAlignedMalloc StdVector NewStdVector)
|
QtAlignedMalloc StdVector NewStdVector
|
||||||
|
Eigen Dense)
|
||||||
|
|
||||||
if(EIGEN_BUILD_LIB)
|
if(EIGEN_BUILD_LIB)
|
||||||
set(Eigen_SRCS
|
set(Eigen_SRCS
|
||||||
|
|||||||
@@ -15,7 +15,9 @@
|
|||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __GNUC__
|
// FIXME: this check should not be against __QNXNTO__, which is also defined
|
||||||
|
// while compiling with GCC for QNX target. Better solution is welcome!
|
||||||
|
#if defined(__GNUC__) && !defined(__QNXNTO__)
|
||||||
#define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__>=x && __GNUC_MINOR__>=y) || __GNUC__>x)
|
#define EIGEN_GNUC_AT_LEAST(x,y) ((__GNUC__>=x && __GNUC_MINOR__>=y) || __GNUC__>x)
|
||||||
#else
|
#else
|
||||||
#define EIGEN_GNUC_AT_LEAST(x,y) 0
|
#define EIGEN_GNUC_AT_LEAST(x,y) 0
|
||||||
@@ -77,6 +79,10 @@
|
|||||||
|
|
||||||
namespace Eigen {
|
namespace Eigen {
|
||||||
|
|
||||||
|
// we use size_t frequently and we'll never remember to prepend it with std:: everytime just to
|
||||||
|
// ensure QNX/QCC support
|
||||||
|
using std::size_t;
|
||||||
|
|
||||||
/** \defgroup Core_Module Core module
|
/** \defgroup Core_Module Core module
|
||||||
* This is the main module of Eigen providing dense matrix and vector support
|
* This is the main module of Eigen providing dense matrix and vector support
|
||||||
* (both fixed and dynamic size) with all the features corresponding to a BLAS library
|
* (both fixed and dynamic size) with all the features corresponding to a BLAS library
|
||||||
|
|||||||
@@ -36,8 +36,8 @@ template <class T>
|
|||||||
class aligned_allocator_indirection : public aligned_allocator<T>
|
class aligned_allocator_indirection : public aligned_allocator<T>
|
||||||
{
|
{
|
||||||
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;
|
||||||
|
|||||||
@@ -160,13 +160,15 @@ template<typename ExpressionType, int Direction> class PartialRedux
|
|||||||
public:
|
public:
|
||||||
|
|
||||||
typedef typename ei_traits<ExpressionType>::Scalar Scalar;
|
typedef typename ei_traits<ExpressionType>::Scalar Scalar;
|
||||||
|
typedef typename NumTraits<Scalar>::Real RealScalar;
|
||||||
typedef typename ei_meta_if<ei_must_nest_by_value<ExpressionType>::ret,
|
typedef typename ei_meta_if<ei_must_nest_by_value<ExpressionType>::ret,
|
||||||
ExpressionType, const ExpressionType&>::ret ExpressionTypeNested;
|
ExpressionType, const ExpressionType&>::ret ExpressionTypeNested;
|
||||||
|
|
||||||
template<template<typename _Scalar> class Functor> struct ReturnType
|
template<template<typename _Scalar> class Functor,
|
||||||
|
typename Scalar = typename ei_traits<ExpressionType>::Scalar> struct ReturnType
|
||||||
{
|
{
|
||||||
typedef PartialReduxExpr<ExpressionType,
|
typedef PartialReduxExpr<ExpressionType,
|
||||||
Functor<typename ei_traits<ExpressionType>::Scalar>,
|
Functor<Scalar>,
|
||||||
Direction
|
Direction
|
||||||
> Type;
|
> Type;
|
||||||
};
|
};
|
||||||
@@ -217,7 +219,7 @@ template<typename ExpressionType, int Direction> class PartialRedux
|
|||||||
* Output: \verbinclude PartialRedux_squaredNorm.out
|
* Output: \verbinclude PartialRedux_squaredNorm.out
|
||||||
*
|
*
|
||||||
* \sa MatrixBase::squaredNorm() */
|
* \sa MatrixBase::squaredNorm() */
|
||||||
const typename ReturnType<ei_member_squaredNorm>::Type squaredNorm() const
|
const typename ReturnType<ei_member_squaredNorm,RealScalar>::Type squaredNorm() const
|
||||||
{ return _expression(); }
|
{ return _expression(); }
|
||||||
|
|
||||||
/** \returns a row (or column) vector expression of the norm
|
/** \returns a row (or column) vector expression of the norm
|
||||||
@@ -227,7 +229,7 @@ template<typename ExpressionType, int Direction> class PartialRedux
|
|||||||
* Output: \verbinclude PartialRedux_norm.out
|
* Output: \verbinclude PartialRedux_norm.out
|
||||||
*
|
*
|
||||||
* \sa MatrixBase::norm() */
|
* \sa MatrixBase::norm() */
|
||||||
const typename ReturnType<ei_member_norm>::Type norm() const
|
const typename ReturnType<ei_member_norm,RealScalar>::Type norm() const
|
||||||
{ return _expression(); }
|
{ return _expression(); }
|
||||||
|
|
||||||
/** \returns a row (or column) vector expression of the sum
|
/** \returns a row (or column) vector expression of the sum
|
||||||
|
|||||||
@@ -96,8 +96,7 @@ void LDLT<MatrixType>::compute(const MatrixType& a)
|
|||||||
assert(a.rows()==a.cols());
|
assert(a.rows()==a.cols());
|
||||||
const int size = a.rows();
|
const int size = a.rows();
|
||||||
m_matrix.resize(size, size);
|
m_matrix.resize(size, size);
|
||||||
m_isPositiveDefinite = true;
|
m_isPositiveDefinite = true; // always true. This decomposition is not rank-revealing anyway.
|
||||||
const RealScalar eps = ei_sqrt(precision<Scalar>());
|
|
||||||
|
|
||||||
if (size<=1)
|
if (size<=1)
|
||||||
{
|
{
|
||||||
@@ -121,12 +120,6 @@ void LDLT<MatrixType>::compute(const MatrixType& a)
|
|||||||
RealScalar tmp = ei_real(a.coeff(j,j) - (m_matrix.row(j).start(j) * m_matrix.col(j).start(j).conjugate()).coeff(0,0));
|
RealScalar tmp = ei_real(a.coeff(j,j) - (m_matrix.row(j).start(j) * m_matrix.col(j).start(j).conjugate()).coeff(0,0));
|
||||||
m_matrix.coeffRef(j,j) = tmp;
|
m_matrix.coeffRef(j,j) = tmp;
|
||||||
|
|
||||||
if (tmp < eps)
|
|
||||||
{
|
|
||||||
m_isPositiveDefinite = false;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
int endSize = size-j-1;
|
int endSize = size-j-1;
|
||||||
if (endSize>0)
|
if (endSize>0)
|
||||||
{
|
{
|
||||||
@@ -136,7 +129,8 @@ void LDLT<MatrixType>::compute(const MatrixType& a)
|
|||||||
m_matrix.row(j).end(endSize) = a.row(j).end(endSize).conjugate()
|
m_matrix.row(j).end(endSize) = a.row(j).end(endSize).conjugate()
|
||||||
- _temporary.end(endSize).transpose();
|
- _temporary.end(endSize).transpose();
|
||||||
|
|
||||||
m_matrix.col(j).end(endSize) = m_matrix.row(j).end(endSize) / tmp;
|
if(tmp != RealScalar(0))
|
||||||
|
m_matrix.col(j).end(endSize) = m_matrix.row(j).end(endSize) / tmp;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -192,7 +186,7 @@ template<typename Derived>
|
|||||||
inline const LDLT<typename MatrixBase<Derived>::PlainMatrixType>
|
inline const LDLT<typename MatrixBase<Derived>::PlainMatrixType>
|
||||||
MatrixBase<Derived>::ldlt() const
|
MatrixBase<Derived>::ldlt() const
|
||||||
{
|
{
|
||||||
return derived();
|
return LDLT<PlainMatrixType>(derived());
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // EIGEN_LDLT_H
|
#endif // EIGEN_LDLT_H
|
||||||
|
|||||||
@@ -90,6 +90,28 @@ public:
|
|||||||
? ( int(MayUnrollCompletely) && int(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) )
|
? ( int(MayUnrollCompletely) && int(DstIsAligned) ? int(CompleteUnrolling) : int(NoUnrolling) )
|
||||||
: int(NoUnrolling)
|
: int(NoUnrolling)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifdef EIGEN_DEBUG_ASSIGN
|
||||||
|
#define EIGEN_DEBUG_VAR(x) std::cerr << #x << " = " << x << std::endl;
|
||||||
|
static void debug()
|
||||||
|
{
|
||||||
|
EIGEN_DEBUG_VAR(DstIsAligned)
|
||||||
|
EIGEN_DEBUG_VAR(SrcIsAligned)
|
||||||
|
EIGEN_DEBUG_VAR(SrcAlignment)
|
||||||
|
EIGEN_DEBUG_VAR(InnerSize)
|
||||||
|
EIGEN_DEBUG_VAR(InnerMaxSize)
|
||||||
|
EIGEN_DEBUG_VAR(PacketSize)
|
||||||
|
EIGEN_DEBUG_VAR(MightVectorize)
|
||||||
|
EIGEN_DEBUG_VAR(MayInnerVectorize)
|
||||||
|
EIGEN_DEBUG_VAR(MayLinearVectorize)
|
||||||
|
EIGEN_DEBUG_VAR(MaySliceVectorize)
|
||||||
|
EIGEN_DEBUG_VAR(Vectorization)
|
||||||
|
EIGEN_DEBUG_VAR(UnrollingLimit)
|
||||||
|
EIGEN_DEBUG_VAR(MayUnrollCompletely)
|
||||||
|
EIGEN_DEBUG_VAR(MayUnrollInner)
|
||||||
|
EIGEN_DEBUG_VAR(Unrolling)
|
||||||
|
}
|
||||||
|
#endif
|
||||||
};
|
};
|
||||||
|
|
||||||
/***************************************************************************
|
/***************************************************************************
|
||||||
@@ -400,6 +422,9 @@ template<typename OtherDerived>
|
|||||||
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>
|
EIGEN_STRONG_INLINE Derived& MatrixBase<Derived>
|
||||||
::lazyAssign(const MatrixBase<OtherDerived>& other)
|
::lazyAssign(const MatrixBase<OtherDerived>& other)
|
||||||
{
|
{
|
||||||
|
#ifdef EIGEN_DEBUG_ASSIGN
|
||||||
|
ei_assign_traits<Derived, OtherDerived>::debug();
|
||||||
|
#endif
|
||||||
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
|
EIGEN_STATIC_ASSERT_SAME_MATRIX_SIZE(Derived,OtherDerived)
|
||||||
EIGEN_STATIC_ASSERT((ei_is_same_type<typename Derived::Scalar, typename OtherDerived::Scalar>::ret),
|
EIGEN_STATIC_ASSERT((ei_is_same_type<typename Derived::Scalar, typename OtherDerived::Scalar>::ret),
|
||||||
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
|
||||||
|
|||||||
@@ -33,7 +33,7 @@ struct ei_L2_block_traits {
|
|||||||
#ifndef EIGEN_EXTERN_INSTANTIATIONS
|
#ifndef EIGEN_EXTERN_INSTANTIATIONS
|
||||||
|
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
static void ei_cache_friendly_product(
|
void ei_cache_friendly_product(
|
||||||
int _rows, int _cols, int depth,
|
int _rows, int _cols, int depth,
|
||||||
bool _lhsRowMajor, const Scalar* _lhs, int _lhsStride,
|
bool _lhsRowMajor, const Scalar* _lhs, int _lhsStride,
|
||||||
bool _rhsRowMajor, const Scalar* _rhs, int _rhsStride,
|
bool _rhsRowMajor, const Scalar* _rhs, int _rhsStride,
|
||||||
@@ -84,7 +84,7 @@ static void ei_cache_friendly_product(
|
|||||||
MaxL2BlockSize = ei_L2_block_traits<EIGEN_TUNE_FOR_CPU_CACHE_SIZE,Scalar>::width
|
MaxL2BlockSize = ei_L2_block_traits<EIGEN_TUNE_FOR_CPU_CACHE_SIZE,Scalar>::width
|
||||||
};
|
};
|
||||||
|
|
||||||
const bool resIsAligned = (PacketSize==1) || (((resStride%PacketSize) == 0) && (size_t(res)%16==0));
|
const bool resIsAligned = (PacketSize==1) || (((resStride%PacketSize) == 0) && (std::size_t(res)%16==0));
|
||||||
|
|
||||||
const int remainingSize = depth % PacketSize;
|
const int remainingSize = depth % PacketSize;
|
||||||
const int size = depth - remainingSize; // third dimension of the product clamped to packet boundaries
|
const int size = depth - remainingSize; // third dimension of the product clamped to packet boundaries
|
||||||
@@ -92,7 +92,7 @@ static void ei_cache_friendly_product(
|
|||||||
const int l2BlockCols = MaxL2BlockSize > cols ? cols : MaxL2BlockSize;
|
const int l2BlockCols = MaxL2BlockSize > cols ? cols : MaxL2BlockSize;
|
||||||
const int l2BlockSize = MaxL2BlockSize > size ? size : MaxL2BlockSize;
|
const int l2BlockSize = MaxL2BlockSize > size ? size : MaxL2BlockSize;
|
||||||
const int l2BlockSizeAligned = (1 + std::max(l2BlockSize,l2BlockCols)/PacketSize)*PacketSize;
|
const int l2BlockSizeAligned = (1 + std::max(l2BlockSize,l2BlockCols)/PacketSize)*PacketSize;
|
||||||
const bool needRhsCopy = (PacketSize>1) && ((rhsStride%PacketSize!=0) || (size_t(rhs)%16!=0));
|
const bool needRhsCopy = (PacketSize>1) && ((rhsStride%PacketSize!=0) || (std::size_t(rhs)%16!=0));
|
||||||
Scalar* EIGEN_RESTRICT block = 0;
|
Scalar* EIGEN_RESTRICT block = 0;
|
||||||
const int allocBlockSize = l2BlockRows*size;
|
const int allocBlockSize = l2BlockRows*size;
|
||||||
block = ei_aligned_stack_new(Scalar, allocBlockSize);
|
block = ei_aligned_stack_new(Scalar, allocBlockSize);
|
||||||
@@ -172,7 +172,7 @@ static void ei_cache_friendly_product(
|
|||||||
for(int l1j=l2j; l1j<l2blockColEnd; l1j+=1)
|
for(int l1j=l2j; l1j<l2blockColEnd; l1j+=1)
|
||||||
{
|
{
|
||||||
ei_internal_assert(l2BlockSizeAligned*(l1j-l2j)+(l2blockSizeEnd-l2k) < l2BlockSizeAligned*l2BlockSizeAligned);
|
ei_internal_assert(l2BlockSizeAligned*(l1j-l2j)+(l2blockSizeEnd-l2k) < l2BlockSizeAligned*l2BlockSizeAligned);
|
||||||
memcpy(rhsCopy+l2BlockSizeAligned*(l1j-l2j),&(rhs[l1j*rhsStride+l2k]),(l2blockSizeEnd-l2k)*sizeof(Scalar));
|
std::memcpy(rhsCopy+l2BlockSizeAligned*(l1j-l2j),&(rhs[l1j*rhsStride+l2k]),(l2blockSizeEnd-l2k)*sizeof(Scalar));
|
||||||
}
|
}
|
||||||
|
|
||||||
// for each bw x 1 result's block
|
// for each bw x 1 result's block
|
||||||
@@ -352,7 +352,7 @@ static void ei_cache_friendly_product(
|
|||||||
* TODO: since rhs gets evaluated only once, no need to evaluate it
|
* TODO: since rhs gets evaluated only once, no need to evaluate it
|
||||||
*/
|
*/
|
||||||
template<typename Scalar, typename RhsType>
|
template<typename Scalar, typename RhsType>
|
||||||
static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
|
EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
|
||||||
int size,
|
int size,
|
||||||
const Scalar* lhs, int lhsStride,
|
const Scalar* lhs, int lhsStride,
|
||||||
const RhsType& rhs,
|
const RhsType& rhs,
|
||||||
@@ -397,7 +397,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
|
|||||||
int skipColumns = 0;
|
int skipColumns = 0;
|
||||||
if (PacketSize>1)
|
if (PacketSize>1)
|
||||||
{
|
{
|
||||||
ei_internal_assert(size_t(lhs+lhsAlignmentOffset)%sizeof(Packet)==0 || size<PacketSize);
|
ei_internal_assert(std::size_t(lhs+lhsAlignmentOffset)%sizeof(Packet)==0 || size<PacketSize);
|
||||||
|
|
||||||
while (skipColumns<PacketSize &&
|
while (skipColumns<PacketSize &&
|
||||||
alignedStart != ((lhsAlignmentOffset + alignmentStep*skipColumns)%PacketSize))
|
alignedStart != ((lhsAlignmentOffset + alignmentStep*skipColumns)%PacketSize))
|
||||||
@@ -414,7 +414,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
|
|||||||
// note that the skiped columns are processed later.
|
// note that the skiped columns are processed later.
|
||||||
}
|
}
|
||||||
|
|
||||||
ei_internal_assert((alignmentPattern==NoneAligned) || (size_t(lhs+alignedStart+lhsStride*skipColumns)%sizeof(Packet))==0);
|
ei_internal_assert((alignmentPattern==NoneAligned) || (std::size_t(lhs+alignedStart+lhsStride*skipColumns)%sizeof(Packet))==0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int offset1 = (FirstAligned && alignmentStep==1?3:1);
|
int offset1 = (FirstAligned && alignmentStep==1?3:1);
|
||||||
@@ -516,7 +516,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
|
|||||||
res[j] += ei_pfirst(ptmp0) * lhs0[j];
|
res[j] += ei_pfirst(ptmp0) * lhs0[j];
|
||||||
|
|
||||||
// process aligned result's coeffs
|
// process aligned result's coeffs
|
||||||
if ((size_t(lhs0+alignedStart)%sizeof(Packet))==0)
|
if ((std::size_t(lhs0+alignedStart)%sizeof(Packet))==0)
|
||||||
for (int j = alignedStart;j<alignedSize;j+=PacketSize)
|
for (int j = alignedStart;j<alignedSize;j+=PacketSize)
|
||||||
ei_pstore(&res[j], ei_pmadd(ptmp0,ei_pload(&lhs0[j]),ei_pload(&res[j])));
|
ei_pstore(&res[j], ei_pmadd(ptmp0,ei_pload(&lhs0[j]),ei_pload(&res[j])));
|
||||||
else
|
else
|
||||||
@@ -542,7 +542,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_colmajor_times_vector(
|
|||||||
|
|
||||||
// TODO add peeling to mask unaligned load/stores
|
// TODO add peeling to mask unaligned load/stores
|
||||||
template<typename Scalar, typename ResType>
|
template<typename Scalar, typename ResType>
|
||||||
static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
|
EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
|
||||||
const Scalar* lhs, int lhsStride,
|
const Scalar* lhs, int lhsStride,
|
||||||
const Scalar* rhs, int rhsSize,
|
const Scalar* rhs, int rhsSize,
|
||||||
ResType& res)
|
ResType& res)
|
||||||
@@ -586,7 +586,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
|
|||||||
int skipRows = 0;
|
int skipRows = 0;
|
||||||
if (PacketSize>1)
|
if (PacketSize>1)
|
||||||
{
|
{
|
||||||
ei_internal_assert(size_t(lhs+lhsAlignmentOffset)%sizeof(Packet)==0 || size<PacketSize);
|
ei_internal_assert(std::size_t(lhs+lhsAlignmentOffset)%sizeof(Packet)==0 || size<PacketSize);
|
||||||
|
|
||||||
while (skipRows<PacketSize &&
|
while (skipRows<PacketSize &&
|
||||||
alignedStart != ((lhsAlignmentOffset + alignmentStep*skipRows)%PacketSize))
|
alignedStart != ((lhsAlignmentOffset + alignmentStep*skipRows)%PacketSize))
|
||||||
@@ -603,7 +603,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
|
|||||||
// note that the skiped columns are processed later.
|
// note that the skiped columns are processed later.
|
||||||
}
|
}
|
||||||
ei_internal_assert((alignmentPattern==NoneAligned) || PacketSize==1
|
ei_internal_assert((alignmentPattern==NoneAligned) || PacketSize==1
|
||||||
|| (size_t(lhs+alignedStart+lhsStride*skipRows)%sizeof(Packet))==0);
|
|| (std::size_t(lhs+alignedStart+lhsStride*skipRows)%sizeof(Packet))==0);
|
||||||
}
|
}
|
||||||
|
|
||||||
int offset1 = (FirstAligned && alignmentStep==1?3:1);
|
int offset1 = (FirstAligned && alignmentStep==1?3:1);
|
||||||
@@ -722,7 +722,7 @@ static EIGEN_DONT_INLINE void ei_cache_friendly_product_rowmajor_times_vector(
|
|||||||
if (alignedSize>alignedStart)
|
if (alignedSize>alignedStart)
|
||||||
{
|
{
|
||||||
// process aligned rhs coeffs
|
// process aligned rhs coeffs
|
||||||
if ((size_t(lhs0+alignedStart)%sizeof(Packet))==0)
|
if ((std::size_t(lhs0+alignedStart)%sizeof(Packet))==0)
|
||||||
for (int j = alignedStart;j<alignedSize;j+=PacketSize)
|
for (int j = alignedStart;j<alignedSize;j+=PacketSize)
|
||||||
ptmp0 = ei_pmadd(ei_pload(&rhs[j]), ei_pload(&lhs0[j]), ptmp0);
|
ptmp0 = ei_pmadd(ei_pload(&rhs[j]), ei_pload(&lhs0[j]), ptmp0);
|
||||||
else
|
else
|
||||||
|
|||||||
@@ -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<std::size_t>(array) & 0xf) == 0
|
ei_assert((reinterpret_cast<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
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,7 +94,7 @@ template<typename _Real> struct NumTraits<std::complex<_Real> >
|
|||||||
enum {
|
enum {
|
||||||
IsComplex = 1,
|
IsComplex = 1,
|
||||||
HasFloatingPoint = NumTraits<Real>::HasFloatingPoint,
|
HasFloatingPoint = NumTraits<Real>::HasFloatingPoint,
|
||||||
ReadCost = 2,
|
ReadCost = 2 * NumTraits<_Real>::ReadCost,
|
||||||
AddCost = 2 * NumTraits<Real>::AddCost,
|
AddCost = 2 * NumTraits<Real>::AddCost,
|
||||||
MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost
|
MulCost = 4 * NumTraits<Real>::MulCost + 2 * NumTraits<Real>::AddCost
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -636,6 +636,7 @@ struct ei_cache_friendly_product_selector<ProductType,LhsRows,RowMajor,HasDirect
|
|||||||
typedef typename ei_traits<ProductType>::_RhsNested Rhs;
|
typedef typename ei_traits<ProductType>::_RhsNested Rhs;
|
||||||
enum {
|
enum {
|
||||||
UseRhsDirectly = ((ei_packet_traits<Scalar>::size==1) || (Rhs::Flags&ActualPacketAccessBit))
|
UseRhsDirectly = ((ei_packet_traits<Scalar>::size==1) || (Rhs::Flags&ActualPacketAccessBit))
|
||||||
|
&& (Rhs::Flags&DirectAccessBit)
|
||||||
&& (!(Rhs::Flags & RowMajorBit)) };
|
&& (!(Rhs::Flags & RowMajorBit)) };
|
||||||
|
|
||||||
template<typename DestDerived>
|
template<typename DestDerived>
|
||||||
@@ -664,6 +665,7 @@ struct ei_cache_friendly_product_selector<ProductType,1,LhsOrder,LhsAccess,RhsCo
|
|||||||
typedef typename ei_traits<ProductType>::_LhsNested Lhs;
|
typedef typename ei_traits<ProductType>::_LhsNested Lhs;
|
||||||
enum {
|
enum {
|
||||||
UseLhsDirectly = ((ei_packet_traits<Scalar>::size==1) || (Lhs::Flags&ActualPacketAccessBit))
|
UseLhsDirectly = ((ei_packet_traits<Scalar>::size==1) || (Lhs::Flags&ActualPacketAccessBit))
|
||||||
|
&& (Lhs::Flags&DirectAccessBit)
|
||||||
&& (Lhs::Flags & RowMajorBit) };
|
&& (Lhs::Flags & RowMajorBit) };
|
||||||
|
|
||||||
template<typename DestDerived>
|
template<typename DestDerived>
|
||||||
|
|||||||
@@ -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 12
|
#define EIGEN_MINOR_VERSION 14
|
||||||
|
|
||||||
#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 && \
|
||||||
@@ -52,7 +52,7 @@
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
// FIXME vectorization + alignment is completely disabled with sun studio
|
// FIXME vectorization + alignment is completely disabled with sun studio
|
||||||
#if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_ALIGNMENT && !EIGEN_GCC3_OR_OLDER && !defined(__SUNPRO_CC)
|
#if !EIGEN_GCC_AND_ARCH_DOESNT_WANT_ALIGNMENT && !EIGEN_GCC3_OR_OLDER && !defined(__SUNPRO_CC) && !defined(__QNXNTO__)
|
||||||
#define EIGEN_ARCH_WANTS_ALIGNMENT 1
|
#define EIGEN_ARCH_WANTS_ALIGNMENT 1
|
||||||
#else
|
#else
|
||||||
#define EIGEN_ARCH_WANTS_ALIGNMENT 0
|
#define EIGEN_ARCH_WANTS_ALIGNMENT 0
|
||||||
|
|||||||
@@ -43,7 +43,7 @@
|
|||||||
#define EIGEN_MALLOC_ALREADY_ALIGNED 0
|
#define EIGEN_MALLOC_ALREADY_ALIGNED 0
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if ((defined _GNU_SOURCE) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0)
|
#if (defined __QNXNTO__) || (((defined _GNU_SOURCE) || ((defined _XOPEN_SOURCE) && (_XOPEN_SOURCE >= 600))) && (defined _POSIX_ADVISORY_INFO) && (_POSIX_ADVISORY_INFO > 0))
|
||||||
#define EIGEN_HAS_POSIX_MEMALIGN 1
|
#define EIGEN_HAS_POSIX_MEMALIGN 1
|
||||||
#else
|
#else
|
||||||
#define EIGEN_HAS_POSIX_MEMALIGN 0
|
#define EIGEN_HAS_POSIX_MEMALIGN 0
|
||||||
@@ -85,9 +85,9 @@ inline void* ei_aligned_malloc(std::size_t size)
|
|||||||
|
|
||||||
void *result;
|
void *result;
|
||||||
#if !EIGEN_ALIGN
|
#if !EIGEN_ALIGN
|
||||||
result = malloc(size);
|
result = std::malloc(size);
|
||||||
#elif EIGEN_MALLOC_ALREADY_ALIGNED
|
#elif EIGEN_MALLOC_ALREADY_ALIGNED
|
||||||
result = malloc(size);
|
result = std::malloc(size);
|
||||||
#elif EIGEN_HAS_POSIX_MEMALIGN
|
#elif EIGEN_HAS_POSIX_MEMALIGN
|
||||||
if(posix_memalign(&result, 16, size)) result = 0;
|
if(posix_memalign(&result, 16, size)) result = 0;
|
||||||
#elif EIGEN_HAS_MM_MALLOC
|
#elif EIGEN_HAS_MM_MALLOC
|
||||||
@@ -156,11 +156,11 @@ template<typename T, bool Align> inline T* ei_conditional_aligned_new(std::size_
|
|||||||
inline void ei_aligned_free(void *ptr)
|
inline void ei_aligned_free(void *ptr)
|
||||||
{
|
{
|
||||||
#if !EIGEN_ALIGN
|
#if !EIGEN_ALIGN
|
||||||
free(ptr);
|
std::free(ptr);
|
||||||
#elif EIGEN_MALLOC_ALREADY_ALIGNED
|
#elif EIGEN_MALLOC_ALREADY_ALIGNED
|
||||||
free(ptr);
|
std::free(ptr);
|
||||||
#elif EIGEN_HAS_POSIX_MEMALIGN
|
#elif EIGEN_HAS_POSIX_MEMALIGN
|
||||||
free(ptr);
|
std::free(ptr);
|
||||||
#elif EIGEN_HAS_MM_MALLOC
|
#elif EIGEN_HAS_MM_MALLOC
|
||||||
_mm_free(ptr);
|
_mm_free(ptr);
|
||||||
#elif defined(_MSC_VER)
|
#elif defined(_MSC_VER)
|
||||||
@@ -239,7 +239,7 @@ inline static Integer ei_alignmentOffset(const Scalar* array, Integer size)
|
|||||||
// of the array have the same aligment.
|
// of the array have the same aligment.
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
else if(size_t(array) & (sizeof(Scalar)-1))
|
else if(std::size_t(array) & (sizeof(Scalar)-1))
|
||||||
{
|
{
|
||||||
// There is vectorization for this scalar type, but the array is not aligned to the size of a single scalar.
|
// There is vectorization for this scalar type, but the array is not aligned to the size of a single scalar.
|
||||||
// Consequently, no element of the array is well aligned.
|
// Consequently, no element of the array is well aligned.
|
||||||
@@ -247,7 +247,7 @@ inline static Integer ei_alignmentOffset(const Scalar* array, Integer size)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
return std::min<Integer>( (PacketSize - (Integer((size_t(array)/sizeof(Scalar))) & PacketAlignedMask))
|
return std::min<Integer>( (PacketSize - (Integer((std::size_t(array)/sizeof(Scalar))) & PacketAlignedMask))
|
||||||
& PacketAlignedMask, size);
|
& PacketAlignedMask, size);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -94,10 +94,16 @@ class ei_compute_matrix_flags
|
|||||||
{
|
{
|
||||||
enum {
|
enum {
|
||||||
row_major_bit = Options&RowMajor ? RowMajorBit : 0,
|
row_major_bit = Options&RowMajor ? RowMajorBit : 0,
|
||||||
inner_max_size = row_major_bit ? MaxCols : MaxRows,
|
inner_max_size = int(MaxRows==1) ? int(MaxCols)
|
||||||
|
: int(MaxCols==1) ? int(MaxRows)
|
||||||
|
: int(row_major_bit) ? int(MaxCols) : int(MaxRows),
|
||||||
is_big = inner_max_size == Dynamic,
|
is_big = inner_max_size == Dynamic,
|
||||||
is_packet_size_multiple = (Cols*Rows) % ei_packet_traits<Scalar>::size == 0,
|
storage_has_fixed_size = MaxRows != Dynamic && MaxCols != Dynamic,
|
||||||
aligned_bit = ((Options&AutoAlign) && (is_big || is_packet_size_multiple)) ? AlignedBit : 0,
|
storage_has_aligned_fixed_size = storage_has_fixed_size
|
||||||
|
&& ( (MaxCols*MaxRows) % ei_packet_traits<Scalar>::size == 0 ),
|
||||||
|
aligned_bit = ( (Options&AutoAlign)
|
||||||
|
&& (is_big || storage_has_aligned_fixed_size)
|
||||||
|
) ? AlignedBit : 0,
|
||||||
packet_access_bit = ei_packet_traits<Scalar>::size > 1 && aligned_bit ? PacketAccessBit : 0
|
packet_access_bit = ei_packet_traits<Scalar>::size > 1 && aligned_bit ? PacketAccessBit : 0
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -63,10 +63,10 @@ template<typename MatrixType> class LU
|
|||||||
|
|
||||||
typedef typename MatrixType::Scalar Scalar;
|
typedef typename MatrixType::Scalar Scalar;
|
||||||
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
typedef typename NumTraits<typename MatrixType::Scalar>::Real RealScalar;
|
||||||
typedef Matrix<int, 1, MatrixType::ColsAtCompileTime> IntRowVectorType;
|
typedef Matrix<int, 1, MatrixType::ColsAtCompileTime, MatrixType::Options, 1, MatrixType::MaxColsAtCompileTime> IntRowVectorType;
|
||||||
typedef Matrix<int, MatrixType::RowsAtCompileTime, 1> IntColVectorType;
|
typedef Matrix<int, MatrixType::RowsAtCompileTime, 1, MatrixType::Options, MatrixType::MaxRowsAtCompileTime, 1> IntColVectorType;
|
||||||
typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime> RowVectorType;
|
typedef Matrix<Scalar, 1, MatrixType::ColsAtCompileTime, MatrixType::Options, 1, MatrixType::MaxColsAtCompileTime> RowVectorType;
|
||||||
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1> ColVectorType;
|
typedef Matrix<Scalar, MatrixType::RowsAtCompileTime, 1, MatrixType::Options, MatrixType::MaxRowsAtCompileTime, 1> ColVectorType;
|
||||||
|
|
||||||
enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN(
|
enum { MaxSmallDimAtCompileTime = EIGEN_SIZE_MIN(
|
||||||
MatrixType::MaxColsAtCompileTime,
|
MatrixType::MaxColsAtCompileTime,
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ template<typename _Scalar> class AmbiVector
|
|||||||
int allocSize = m_allocatedElements * sizeof(ListEl);
|
int allocSize = m_allocatedElements * sizeof(ListEl);
|
||||||
allocSize = allocSize/sizeof(Scalar) + (allocSize%sizeof(Scalar)>0?1:0);
|
allocSize = allocSize/sizeof(Scalar) + (allocSize%sizeof(Scalar)>0?1:0);
|
||||||
Scalar* newBuffer = new Scalar[allocSize];
|
Scalar* newBuffer = new Scalar[allocSize];
|
||||||
memcpy(newBuffer, m_buffer, copyElements * sizeof(ListEl));
|
std::memcpy(newBuffer, m_buffer, copyElements * sizeof(ListEl));
|
||||||
delete[] m_buffer;
|
delete[] m_buffer;
|
||||||
m_buffer = newBuffer;
|
m_buffer = newBuffer;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ class CompressedStorage
|
|||||||
: m_values(0), m_indices(0), m_size(0), m_allocatedSize(0)
|
: m_values(0), m_indices(0), m_size(0), m_allocatedSize(0)
|
||||||
{}
|
{}
|
||||||
|
|
||||||
CompressedStorage(size_t size)
|
CompressedStorage(std::size_t size)
|
||||||
: m_values(0), m_indices(0), m_size(0), m_allocatedSize(0)
|
: m_values(0), m_indices(0), m_size(0), m_allocatedSize(0)
|
||||||
{
|
{
|
||||||
resize(size);
|
resize(size);
|
||||||
@@ -52,8 +52,8 @@ class CompressedStorage
|
|||||||
CompressedStorage& operator=(const CompressedStorage& other)
|
CompressedStorage& operator=(const CompressedStorage& other)
|
||||||
{
|
{
|
||||||
resize(other.size());
|
resize(other.size());
|
||||||
memcpy(m_values, other.m_values, m_size * sizeof(Scalar));
|
std::memcpy(m_values, other.m_values, m_size * sizeof(Scalar));
|
||||||
memcpy(m_indices, other.m_indices, m_size * sizeof(int));
|
std::memcpy(m_indices, other.m_indices, m_size * sizeof(int));
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -71,9 +71,9 @@ class CompressedStorage
|
|||||||
delete[] m_indices;
|
delete[] m_indices;
|
||||||
}
|
}
|
||||||
|
|
||||||
void reserve(size_t size)
|
void reserve(std::size_t size)
|
||||||
{
|
{
|
||||||
size_t newAllocatedSize = m_size + size;
|
std::size_t newAllocatedSize = m_size + size;
|
||||||
if (newAllocatedSize > m_allocatedSize)
|
if (newAllocatedSize > m_allocatedSize)
|
||||||
reallocate(newAllocatedSize);
|
reallocate(newAllocatedSize);
|
||||||
}
|
}
|
||||||
@@ -84,10 +84,10 @@ class CompressedStorage
|
|||||||
reallocate(m_size);
|
reallocate(m_size);
|
||||||
}
|
}
|
||||||
|
|
||||||
void resize(size_t size, float reserveSizeFactor = 0)
|
void resize(std::size_t size, float reserveSizeFactor = 0)
|
||||||
{
|
{
|
||||||
if (m_allocatedSize<size)
|
if (m_allocatedSize<size)
|
||||||
reallocate(size + size_t(reserveSizeFactor*size));
|
reallocate(size + std::size_t(reserveSizeFactor*size));
|
||||||
m_size = size;
|
m_size = size;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -99,17 +99,17 @@ class CompressedStorage
|
|||||||
m_indices[id] = i;
|
m_indices[id] = i;
|
||||||
}
|
}
|
||||||
|
|
||||||
inline size_t size() const { return m_size; }
|
inline std::size_t size() const { return m_size; }
|
||||||
inline size_t allocatedSize() const { return m_allocatedSize; }
|
inline std::size_t allocatedSize() const { return m_allocatedSize; }
|
||||||
inline void clear() { m_size = 0; }
|
inline void clear() { m_size = 0; }
|
||||||
|
|
||||||
inline Scalar& value(size_t i) { return m_values[i]; }
|
inline Scalar& value(std::size_t i) { return m_values[i]; }
|
||||||
inline const Scalar& value(size_t i) const { return m_values[i]; }
|
inline const Scalar& value(std::size_t i) const { return m_values[i]; }
|
||||||
|
|
||||||
inline int& index(size_t i) { return m_indices[i]; }
|
inline int& index(std::size_t i) { return m_indices[i]; }
|
||||||
inline const int& index(size_t i) const { return m_indices[i]; }
|
inline const int& index(std::size_t i) const { return m_indices[i]; }
|
||||||
|
|
||||||
static CompressedStorage Map(int* indices, Scalar* values, size_t size)
|
static CompressedStorage Map(int* indices, Scalar* values, std::size_t size)
|
||||||
{
|
{
|
||||||
CompressedStorage res;
|
CompressedStorage res;
|
||||||
res.m_indices = indices;
|
res.m_indices = indices;
|
||||||
@@ -125,11 +125,11 @@ class CompressedStorage
|
|||||||
}
|
}
|
||||||
|
|
||||||
/** \returns the largest \c k in [start,end) such that for all \c j in [start,k) index[\c j]\<\a key */
|
/** \returns the largest \c k in [start,end) such that for all \c j in [start,k) index[\c j]\<\a key */
|
||||||
inline int searchLowerIndex(size_t start, size_t end, int key) const
|
inline int searchLowerIndex(std::size_t start, std::size_t end, int key) const
|
||||||
{
|
{
|
||||||
while(end>start)
|
while(end>start)
|
||||||
{
|
{
|
||||||
size_t mid = (end+start)>>1;
|
std::size_t mid = (end+start)>>1;
|
||||||
if (m_indices[mid]<key)
|
if (m_indices[mid]<key)
|
||||||
start = mid+1;
|
start = mid+1;
|
||||||
else
|
else
|
||||||
@@ -148,12 +148,12 @@ class CompressedStorage
|
|||||||
return m_values[m_size-1];
|
return m_values[m_size-1];
|
||||||
// ^^ optimization: let's first check if it is the last coefficient
|
// ^^ optimization: let's first check if it is the last coefficient
|
||||||
// (very common in high level algorithms)
|
// (very common in high level algorithms)
|
||||||
const size_t id = searchLowerIndex(0,m_size-1,key);
|
const std::size_t id = searchLowerIndex(0,m_size-1,key);
|
||||||
return ((id<m_size) && (m_indices[id]==key)) ? m_values[id] : defaultValue;
|
return ((id<m_size) && (m_indices[id]==key)) ? m_values[id] : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Like at(), but the search is performed in the range [start,end) */
|
/** Like at(), but the search is performed in the range [start,end) */
|
||||||
inline Scalar atInRange(size_t start, size_t end, int key, Scalar defaultValue = Scalar(0)) const
|
inline Scalar atInRange(std::size_t start, std::size_t end, int key, Scalar defaultValue = Scalar(0)) const
|
||||||
{
|
{
|
||||||
if (start==end)
|
if (start==end)
|
||||||
return Scalar(0);
|
return Scalar(0);
|
||||||
@@ -161,7 +161,7 @@ class CompressedStorage
|
|||||||
return m_values[end-1];
|
return m_values[end-1];
|
||||||
// ^^ optimization: let's first check if it is the last coefficient
|
// ^^ optimization: let's first check if it is the last coefficient
|
||||||
// (very common in high level algorithms)
|
// (very common in high level algorithms)
|
||||||
const size_t id = searchLowerIndex(start,end-1,key);
|
const std::size_t id = searchLowerIndex(start,end-1,key);
|
||||||
return ((id<end) && (m_indices[id]==key)) ? m_values[id] : defaultValue;
|
return ((id<end) && (m_indices[id]==key)) ? m_values[id] : defaultValue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -170,11 +170,11 @@ class CompressedStorage
|
|||||||
* such that the keys are sorted. */
|
* such that the keys are sorted. */
|
||||||
inline Scalar& atWithInsertion(int key, Scalar defaultValue = Scalar(0))
|
inline Scalar& atWithInsertion(int key, Scalar defaultValue = Scalar(0))
|
||||||
{
|
{
|
||||||
size_t id = searchLowerIndex(0,m_size,key);
|
std::size_t id = searchLowerIndex(0,m_size,key);
|
||||||
if (id>=m_size || m_indices[id]!=key)
|
if (id>=m_size || m_indices[id]!=key)
|
||||||
{
|
{
|
||||||
resize(m_size+1,1);
|
resize(m_size+1,1);
|
||||||
for (size_t j=m_size-1; j>id; --j)
|
for (std::size_t j=m_size-1; j>id; --j)
|
||||||
{
|
{
|
||||||
m_indices[j] = m_indices[j-1];
|
m_indices[j] = m_indices[j-1];
|
||||||
m_values[j] = m_values[j-1];
|
m_values[j] = m_values[j-1];
|
||||||
@@ -187,9 +187,9 @@ class CompressedStorage
|
|||||||
|
|
||||||
void prune(Scalar reference, RealScalar epsilon = precision<RealScalar>())
|
void prune(Scalar reference, RealScalar epsilon = precision<RealScalar>())
|
||||||
{
|
{
|
||||||
size_t k = 0;
|
std::size_t k = 0;
|
||||||
size_t n = size();
|
std::size_t n = size();
|
||||||
for (size_t i=0; i<n; ++i)
|
for (std::size_t i=0; i<n; ++i)
|
||||||
{
|
{
|
||||||
if (!ei_isMuchSmallerThan(value(i), reference, epsilon))
|
if (!ei_isMuchSmallerThan(value(i), reference, epsilon))
|
||||||
{
|
{
|
||||||
@@ -203,14 +203,14 @@ class CompressedStorage
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
inline void reallocate(size_t size)
|
inline void reallocate(std::size_t size)
|
||||||
{
|
{
|
||||||
Scalar* newValues = new Scalar[size];
|
Scalar* newValues = new Scalar[size];
|
||||||
int* newIndices = new int[size];
|
int* newIndices = new int[size];
|
||||||
size_t copySize = std::min(size, m_size);
|
std::size_t copySize = std::min(size, m_size);
|
||||||
// copy
|
// copy
|
||||||
memcpy(newValues, m_values, copySize * sizeof(Scalar));
|
std::memcpy(newValues, m_values, copySize * sizeof(Scalar));
|
||||||
memcpy(newIndices, m_indices, copySize * sizeof(int));
|
std::memcpy(newIndices, m_indices, copySize * sizeof(int));
|
||||||
// delete old stuff
|
// delete old stuff
|
||||||
delete[] m_values;
|
delete[] m_values;
|
||||||
delete[] m_indices;
|
delete[] m_indices;
|
||||||
@@ -222,8 +222,8 @@ class CompressedStorage
|
|||||||
protected:
|
protected:
|
||||||
Scalar* m_values;
|
Scalar* m_values;
|
||||||
int* m_indices;
|
int* m_indices;
|
||||||
size_t m_size;
|
std::size_t m_size;
|
||||||
size_t m_allocatedSize;
|
std::size_t m_allocatedSize;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -212,7 +212,7 @@ class DynamicSparseMatrix
|
|||||||
// remove all coefficients with innerCoord>=innerSize
|
// remove all coefficients with innerCoord>=innerSize
|
||||||
// TODO
|
// TODO
|
||||||
std::cerr << "not implemented yet\n";
|
std::cerr << "not implemented yet\n";
|
||||||
exit(2);
|
std::exit(2);
|
||||||
}
|
}
|
||||||
if (m_data.size() != outerSize)
|
if (m_data.size() != outerSize)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -122,7 +122,7 @@ class SparseMatrix
|
|||||||
{
|
{
|
||||||
m_data.clear();
|
m_data.clear();
|
||||||
//if (m_outerSize)
|
//if (m_outerSize)
|
||||||
memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(int));
|
std::memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(int));
|
||||||
// for (int i=0; i<m_outerSize; ++i)
|
// for (int i=0; i<m_outerSize; ++i)
|
||||||
// m_outerIndex[i] = 0;
|
// m_outerIndex[i] = 0;
|
||||||
// if (m_outerSize)
|
// if (m_outerSize)
|
||||||
@@ -164,7 +164,7 @@ class SparseMatrix
|
|||||||
{
|
{
|
||||||
ei_assert(m_data.index(m_data.size()-1)<inner && "wrong sorted insertion");
|
ei_assert(m_data.index(m_data.size()-1)<inner && "wrong sorted insertion");
|
||||||
}
|
}
|
||||||
assert(size_t(m_outerIndex[outer+1]) == m_data.size());
|
assert(std::size_t(m_outerIndex[outer+1]) == m_data.size());
|
||||||
int id = m_outerIndex[outer+1];
|
int id = m_outerIndex[outer+1];
|
||||||
++m_outerIndex[outer+1];
|
++m_outerIndex[outer+1];
|
||||||
|
|
||||||
@@ -190,10 +190,10 @@ class SparseMatrix
|
|||||||
}
|
}
|
||||||
m_outerIndex[outer+1] = m_outerIndex[outer];
|
m_outerIndex[outer+1] = m_outerIndex[outer];
|
||||||
}
|
}
|
||||||
assert(size_t(m_outerIndex[outer+1]) == m_data.size() && "invalid outer index");
|
assert(std::size_t(m_outerIndex[outer+1]) == m_data.size() && "invalid outer index");
|
||||||
size_t startId = m_outerIndex[outer];
|
std::size_t startId = m_outerIndex[outer];
|
||||||
// FIXME let's make sure sizeof(long int) == sizeof(size_t)
|
// FIXME let's make sure sizeof(long int) == sizeof(std::size_t)
|
||||||
size_t id = m_outerIndex[outer+1];
|
std::size_t id = m_outerIndex[outer+1];
|
||||||
++m_outerIndex[outer+1];
|
++m_outerIndex[outer+1];
|
||||||
|
|
||||||
float reallocRatio = 1;
|
float reallocRatio = 1;
|
||||||
@@ -273,7 +273,7 @@ class SparseMatrix
|
|||||||
m_outerIndex = new int [outerSize+1];
|
m_outerIndex = new int [outerSize+1];
|
||||||
m_outerSize = outerSize;
|
m_outerSize = outerSize;
|
||||||
}
|
}
|
||||||
memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(int));
|
std::memset(m_outerIndex, 0, (m_outerSize+1)*sizeof(int));
|
||||||
}
|
}
|
||||||
void resizeNonZeros(int size)
|
void resizeNonZeros(int size)
|
||||||
{
|
{
|
||||||
@@ -324,7 +324,7 @@ class SparseMatrix
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
resize(other.rows(), other.cols());
|
resize(other.rows(), other.cols());
|
||||||
memcpy(m_outerIndex, other.m_outerIndex, (m_outerSize+1)*sizeof(int));
|
std::memcpy(m_outerIndex, other.m_outerIndex, (m_outerSize+1)*sizeof(int));
|
||||||
m_data = other.m_data;
|
m_data = other.m_data;
|
||||||
}
|
}
|
||||||
return *this;
|
return *this;
|
||||||
|
|||||||
@@ -142,7 +142,7 @@ public :
|
|||||||
}
|
}
|
||||||
|
|
||||||
static inline void cholesky(const gene_matrix & X, gene_matrix & C, int N){
|
static inline void cholesky(const gene_matrix & X, gene_matrix & C, int N){
|
||||||
C = X.cholesky().matrixL();
|
C = X.llt().matrixL();
|
||||||
// C = X;
|
// C = X;
|
||||||
// Cholesky<gene_matrix>::computeInPlace(C);
|
// Cholesky<gene_matrix>::computeInPlace(C);
|
||||||
// Cholesky<gene_matrix>::computeInPlaceBlock(C);
|
// Cholesky<gene_matrix>::computeInPlaceBlock(C);
|
||||||
|
|||||||
64
cmake/FindStandardMathLibrary.cmake
Normal file
64
cmake/FindStandardMathLibrary.cmake
Normal file
@@ -0,0 +1,64 @@
|
|||||||
|
# - Try to find how to link to the standard math library, if anything at all is needed to do.
|
||||||
|
# On most platforms this is automatic, but for example it's not automatic on QNX.
|
||||||
|
#
|
||||||
|
# Once done this will define
|
||||||
|
#
|
||||||
|
# STANDARD_MATH_LIBRARY_FOUND - we found how to successfully link to the standard math library
|
||||||
|
# STANDARD_MATH_LIBRARY - the name of the standard library that one has to link to.
|
||||||
|
# -- this will be left empty if it's automatic (most platforms).
|
||||||
|
# -- this will be set to "m" on platforms where one must explicitly
|
||||||
|
# pass the "-lm" linker flag.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
|
||||||
|
# Redistribution and use is allowed according to the terms of the 2-clause BSD license.
|
||||||
|
|
||||||
|
|
||||||
|
include(CheckCXXSourceCompiles)
|
||||||
|
|
||||||
|
# a little test program for c++ math functions.
|
||||||
|
# notice the std:: is required on some platforms such as QNX
|
||||||
|
|
||||||
|
set(find_standard_math_library_test_program
|
||||||
|
"#include<cmath>
|
||||||
|
int main() { std::sin(0.0); std::log(0.0f); }")
|
||||||
|
|
||||||
|
# first try compiling/linking the test program without any linker flags
|
||||||
|
|
||||||
|
set(CMAKE_REQUIRED_FLAGS "")
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES "")
|
||||||
|
CHECK_CXX_SOURCE_COMPILES(
|
||||||
|
"${find_standard_math_library_test_program}"
|
||||||
|
standard_math_library_linked_to_automatically
|
||||||
|
)
|
||||||
|
|
||||||
|
if(standard_math_library_linked_to_automatically)
|
||||||
|
|
||||||
|
# the test program linked successfully without any linker flag.
|
||||||
|
set(STANDARD_MATH_LIBRARY "")
|
||||||
|
set(STANDARD_MATH_LIBRARY_FOUND TRUE)
|
||||||
|
|
||||||
|
else()
|
||||||
|
|
||||||
|
# the test program did not link successfully without any linker flag.
|
||||||
|
# This is a very uncommon case that so far we only saw on QNX. The next try is the
|
||||||
|
# standard name 'm' for the standard math library.
|
||||||
|
|
||||||
|
set(CMAKE_REQUIRED_LIBRARIES "m")
|
||||||
|
CHECK_CXX_SOURCE_COMPILES(
|
||||||
|
"${find_standard_math_library_test_program}"
|
||||||
|
standard_math_library_linked_to_as_m)
|
||||||
|
|
||||||
|
if(standard_math_library_linked_to_as_m)
|
||||||
|
|
||||||
|
# the test program linked successfully when linking to the 'm' library
|
||||||
|
set(STANDARD_MATH_LIBRARY "m")
|
||||||
|
set(STANDARD_MATH_LIBRARY_FOUND TRUE)
|
||||||
|
|
||||||
|
else()
|
||||||
|
|
||||||
|
# the test program still doesn't link successfully
|
||||||
|
set(STANDARD_MATH_LIBRARY_FOUND FALSE)
|
||||||
|
|
||||||
|
endif()
|
||||||
|
|
||||||
|
endif()
|
||||||
@@ -4,6 +4,10 @@ namespace Eigen {
|
|||||||
|
|
||||||
This is an issue that, so far, we met only with GCC on Windows: for instance, MinGW and TDM-GCC.
|
This is an issue that, so far, we met only with GCC on Windows: for instance, MinGW and TDM-GCC.
|
||||||
|
|
||||||
|
\htmlonly
|
||||||
|
<b><big><big>It seems that this GCC bug has been <a href="http://gcc.gnu.org/gcc-4.5/changes.html">fixed in GCC 4.5</a>. We encourage all GCC/Windows users to upgrade to GCC 4.5.</big></big></b>
|
||||||
|
\endhtmlonly
|
||||||
|
|
||||||
By default, in a function like this,
|
By default, in a function like this,
|
||||||
|
|
||||||
\code
|
\code
|
||||||
|
|||||||
@@ -107,7 +107,7 @@ However there are a few corner cases where these alignment settings get overridd
|
|||||||
|
|
||||||
Two possibilities:
|
Two possibilities:
|
||||||
<ul>
|
<ul>
|
||||||
<li>Define EIGEN_DONT_ALIGN. That disables all 128-bit alignment code, and in particular everything vectorization-related. But do note that this in particular breaks ABI compatibility with vectorized code.</li>
|
<li>Define EIGEN_DONT_ALIGN. That disables all 128-bit alignment code, and in particular everything vectorization-related. But do note that this in particular breaks ABI compatibility with vectorized code. This requires Eigen 2.0.6 or later, and with Eigen 2.0.12 or later it automatically implies EIGEN_DONT_VECTORIZE (before 2.0.12 you had to define both).</li>
|
||||||
<li>Or define both EIGEN_DONT_VECTORIZE and EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT. This keeps the 128-bit alignment code and thus preserves ABI compatibility.</li>
|
<li>Or define both EIGEN_DONT_VECTORIZE and EIGEN_DISABLE_UNALIGNED_ARRAY_ASSERT. This keeps the 128-bit alignment code and thus preserves ABI compatibility.</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ ADD_CUSTOM_TARGET(all_examples)
|
|||||||
FOREACH(example_src ${examples_SRCS})
|
FOREACH(example_src ${examples_SRCS})
|
||||||
GET_FILENAME_COMPONENT(example ${example_src} NAME_WE)
|
GET_FILENAME_COMPONENT(example ${example_src} NAME_WE)
|
||||||
ADD_EXECUTABLE(${example} ${example_src})
|
ADD_EXECUTABLE(${example} ${example_src})
|
||||||
|
if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)
|
||||||
|
target_link_libraries(${example} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})
|
||||||
|
endif()
|
||||||
GET_TARGET_PROPERTY(example_executable
|
GET_TARGET_PROPERTY(example_executable
|
||||||
${example} LOCATION)
|
${example} LOCATION)
|
||||||
ADD_CUSTOM_COMMAND(
|
ADD_CUSTOM_COMMAND(
|
||||||
|
|||||||
@@ -11,6 +11,9 @@ CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/compile_snippet.cpp.in
|
|||||||
${CMAKE_CURRENT_BINARY_DIR}/${compile_snippet_src})
|
${CMAKE_CURRENT_BINARY_DIR}/${compile_snippet_src})
|
||||||
ADD_EXECUTABLE(${compile_snippet_target}
|
ADD_EXECUTABLE(${compile_snippet_target}
|
||||||
${CMAKE_CURRENT_BINARY_DIR}/${compile_snippet_src})
|
${CMAKE_CURRENT_BINARY_DIR}/${compile_snippet_src})
|
||||||
|
if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)
|
||||||
|
target_link_libraries(${compile_snippet_target} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})
|
||||||
|
endif()
|
||||||
GET_TARGET_PROPERTY(compile_snippet_executable
|
GET_TARGET_PROPERTY(compile_snippet_executable
|
||||||
${compile_snippet_target} LOCATION)
|
${compile_snippet_target} LOCATION)
|
||||||
ADD_CUSTOM_COMMAND(
|
ADD_CUSTOM_COMMAND(
|
||||||
|
|||||||
@@ -161,6 +161,10 @@ macro(ei_add_test testname)
|
|||||||
target_link_libraries(${targetname} Eigen2)
|
target_link_libraries(${targetname} Eigen2)
|
||||||
endif(TEST_LIB)
|
endif(TEST_LIB)
|
||||||
|
|
||||||
|
if(EIGEN_STANDARD_LIBRARIES_TO_LINK_TO)
|
||||||
|
target_link_libraries(${targetname} ${EIGEN_STANDARD_LIBRARIES_TO_LINK_TO})
|
||||||
|
endif()
|
||||||
|
|
||||||
target_link_libraries(${targetname} ${EXTERNAL_LIBS})
|
target_link_libraries(${targetname} ${EXTERNAL_LIBS})
|
||||||
if(${ARGC} GREATER 2)
|
if(${ARGC} GREATER 2)
|
||||||
string(STRIP "${ARGV2}" ARGV2_stripped)
|
string(STRIP "${ARGV2}" ARGV2_stripped)
|
||||||
@@ -232,6 +236,7 @@ if(NOT EIGEN_DEFAULT_TO_ROW_MAJOR)
|
|||||||
endif()
|
endif()
|
||||||
ei_add_test(swap)
|
ei_add_test(swap)
|
||||||
ei_add_test(visitor)
|
ei_add_test(visitor)
|
||||||
|
ei_add_test(bug_132)
|
||||||
|
|
||||||
ei_add_test(prec_inverse_4x4 ${EI_OFLAG})
|
ei_add_test(prec_inverse_4x4 ${EI_OFLAG})
|
||||||
|
|
||||||
@@ -284,11 +289,16 @@ else()
|
|||||||
message("Default order: Column-major")
|
message("Default order: Column-major")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
string(TOLOWER "${CMAKE_CXX_COMPILER}" cmake_cxx_compiler_tolower)
|
||||||
|
if(cmake_cxx_compiler_tolower MATCHES "qcc")
|
||||||
|
set(CXX_IS_QCC "ON")
|
||||||
|
endif()
|
||||||
|
|
||||||
message("CXX: ${CMAKE_CXX_COMPILER}")
|
message("CXX: ${CMAKE_CXX_COMPILER}")
|
||||||
if(CMAKE_COMPILER_IS_GNUCXX)
|
if(CMAKE_COMPILER_IS_GNUCXX AND NOT CXX_IS_QCC)
|
||||||
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)
|
||||||
message("CXX_VERSION: ${EIGEN_CXX_VERSION_STRING}")
|
message("CXX_VERSION: ${EIGEN_CXX_VERSION_STRING}")
|
||||||
endif(CMAKE_COMPILER_IS_GNUCXX)
|
endif()
|
||||||
message("CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
|
message("CXX_FLAGS: ${CMAKE_CXX_FLAGS}")
|
||||||
message("Sparse lib flags: ${SPARSE_LIBS}")
|
message("Sparse lib flags: ${SPARSE_LIBS}")
|
||||||
|
|
||||||
|
|||||||
41
test/bug_132.cpp
Normal file
41
test/bug_132.cpp
Normal file
@@ -0,0 +1,41 @@
|
|||||||
|
// This file is part of Eigen, a lightweight C++ template library
|
||||||
|
// for linear algebra. Eigen itself is part of the KDE project.
|
||||||
|
//
|
||||||
|
// Copyright (C) 2010 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
|
||||||
|
// 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/>.
|
||||||
|
|
||||||
|
#include "main.h"
|
||||||
|
|
||||||
|
void test_bug_132() {
|
||||||
|
enum { size = 100 };
|
||||||
|
MatrixXd A(size, size);
|
||||||
|
VectorXd b(size), c(size);
|
||||||
|
{
|
||||||
|
VectorXd y = A.transpose() * (b-c); // bug 132: infinite recursion in coeffRef
|
||||||
|
VectorXd z = (b-c).transpose() * A; // bug 132: infinite recursion in coeffRef
|
||||||
|
}
|
||||||
|
|
||||||
|
// the following ones weren't failing, but let's include them for completeness:
|
||||||
|
{
|
||||||
|
VectorXd y = A * (b-c);
|
||||||
|
VectorXd z = (b-c).transpose() * A.transpose();
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -100,6 +100,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
|
|||||||
VERIFY_IS_APPROX(symm * matX, matB);
|
VERIFY_IS_APPROX(symm * matX, matB);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0 // cholesky is not rank-revealing anyway
|
||||||
// test isPositiveDefinite on non definite matrix
|
// test isPositiveDefinite on non definite matrix
|
||||||
if (rows>4)
|
if (rows>4)
|
||||||
{
|
{
|
||||||
@@ -109,6 +110,7 @@ template<typename MatrixType> void cholesky(const MatrixType& m)
|
|||||||
LDLT<SquareMatrixType> cholnosqrt(symm);
|
LDLT<SquareMatrixType> cholnosqrt(symm);
|
||||||
VERIFY(!cholnosqrt.isPositiveDefinite());
|
VERIFY(!cholnosqrt.isPositiveDefinite());
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void test_cholesky()
|
void test_cholesky()
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ void check_handmade_aligned_malloc()
|
|||||||
for(int i = 1; i < 1000; i++)
|
for(int i = 1; i < 1000; i++)
|
||||||
{
|
{
|
||||||
char *p = (char*)ei_handmade_aligned_malloc(i);
|
char *p = (char*)ei_handmade_aligned_malloc(i);
|
||||||
VERIFY(size_t(p)%ALIGNMENT==0);
|
VERIFY(std::size_t(p)%ALIGNMENT==0);
|
||||||
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
|
// 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;
|
for(int j = 0; j < i; j++) p[j]=0;
|
||||||
ei_handmade_aligned_free(p);
|
ei_handmade_aligned_free(p);
|
||||||
@@ -47,7 +47,7 @@ void check_aligned_malloc()
|
|||||||
for(int i = 1; i < 1000; i++)
|
for(int i = 1; i < 1000; i++)
|
||||||
{
|
{
|
||||||
char *p = (char*)ei_aligned_malloc(i);
|
char *p = (char*)ei_aligned_malloc(i);
|
||||||
VERIFY(size_t(p)%ALIGNMENT==0);
|
VERIFY(std::size_t(p)%ALIGNMENT==0);
|
||||||
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
|
// 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;
|
for(int j = 0; j < i; j++) p[j]=0;
|
||||||
ei_aligned_free(p);
|
ei_aligned_free(p);
|
||||||
@@ -59,7 +59,7 @@ void check_aligned_new()
|
|||||||
for(int i = 1; i < 1000; i++)
|
for(int i = 1; i < 1000; i++)
|
||||||
{
|
{
|
||||||
float *p = ei_aligned_new<float>(i);
|
float *p = ei_aligned_new<float>(i);
|
||||||
VERIFY(size_t(p)%ALIGNMENT==0);
|
VERIFY(std::size_t(p)%ALIGNMENT==0);
|
||||||
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
|
// 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;
|
for(int j = 0; j < i; j++) p[j]=0;
|
||||||
ei_aligned_delete(p,i);
|
ei_aligned_delete(p,i);
|
||||||
@@ -71,7 +71,7 @@ void check_aligned_stack_alloc()
|
|||||||
for(int i = 1; i < 1000; i++)
|
for(int i = 1; i < 1000; i++)
|
||||||
{
|
{
|
||||||
float *p = ei_aligned_stack_new(float,i);
|
float *p = ei_aligned_stack_new(float,i);
|
||||||
VERIFY(size_t(p)%ALIGNMENT==0);
|
VERIFY(std::size_t(p)%ALIGNMENT==0);
|
||||||
// if the buffer is wrongly allocated this will give a bad write --> check with valgrind
|
// 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;
|
for(int j = 0; j < i; j++) p[j]=0;
|
||||||
ei_aligned_stack_delete(float,p,i);
|
ei_aligned_stack_delete(float,p,i);
|
||||||
@@ -98,7 +98,7 @@ class MyClassA
|
|||||||
template<typename T> void check_dynaligned()
|
template<typename T> void check_dynaligned()
|
||||||
{
|
{
|
||||||
T* obj = new T;
|
T* obj = new T;
|
||||||
VERIFY(size_t(obj)%ALIGNMENT==0);
|
VERIFY(std::size_t(obj)%ALIGNMENT==0);
|
||||||
delete obj;
|
delete obj;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -121,15 +121,15 @@ void test_dynalloc()
|
|||||||
|
|
||||||
// check static allocation, who knows ?
|
// check static allocation, who knows ?
|
||||||
{
|
{
|
||||||
MyStruct foo0; VERIFY(size_t(foo0.avec.data())%ALIGNMENT==0);
|
MyStruct foo0; VERIFY(std::size_t(foo0.avec.data())%ALIGNMENT==0);
|
||||||
MyClassA fooA; VERIFY(size_t(fooA.avec.data())%ALIGNMENT==0);
|
MyClassA fooA; VERIFY(std::size_t(fooA.avec.data())%ALIGNMENT==0);
|
||||||
}
|
}
|
||||||
|
|
||||||
// dynamic allocation, single object
|
// dynamic allocation, single object
|
||||||
for (int i=0; i<g_repeat*100; ++i)
|
for (int i=0; i<g_repeat*100; ++i)
|
||||||
{
|
{
|
||||||
MyStruct *foo0 = new MyStruct(); VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0);
|
MyStruct *foo0 = new MyStruct(); VERIFY(std::size_t(foo0->avec.data())%ALIGNMENT==0);
|
||||||
MyClassA *fooA = new MyClassA(); VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0);
|
MyClassA *fooA = new MyClassA(); VERIFY(std::size_t(fooA->avec.data())%ALIGNMENT==0);
|
||||||
delete foo0;
|
delete foo0;
|
||||||
delete fooA;
|
delete fooA;
|
||||||
}
|
}
|
||||||
@@ -138,8 +138,8 @@ void test_dynalloc()
|
|||||||
const int N = 10;
|
const int N = 10;
|
||||||
for (int i=0; i<g_repeat*100; ++i)
|
for (int i=0; i<g_repeat*100; ++i)
|
||||||
{
|
{
|
||||||
MyStruct *foo0 = new MyStruct[N]; VERIFY(size_t(foo0->avec.data())%ALIGNMENT==0);
|
MyStruct *foo0 = new MyStruct[N]; VERIFY(std::size_t(foo0->avec.data())%ALIGNMENT==0);
|
||||||
MyClassA *fooA = new MyClassA[N]; VERIFY(size_t(fooA->avec.data())%ALIGNMENT==0);
|
MyClassA *fooA = new MyClassA[N]; VERIFY(std::size_t(fooA->avec.data())%ALIGNMENT==0);
|
||||||
delete[] foo0;
|
delete[] foo0;
|
||||||
delete[] fooA;
|
delete[] fooA;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,7 +28,7 @@ template<typename Scalar>
|
|||||||
void test_first_aligned_helper(Scalar *array, int size)
|
void test_first_aligned_helper(Scalar *array, int size)
|
||||||
{
|
{
|
||||||
const int packet_size = sizeof(Scalar) * ei_packet_traits<Scalar>::size;
|
const int packet_size = sizeof(Scalar) * ei_packet_traits<Scalar>::size;
|
||||||
VERIFY(((size_t(array) + sizeof(Scalar) * ei_alignmentOffset(array, size)) % packet_size) == 0);
|
VERIFY(((std::size_t(array) + sizeof(Scalar) * ei_alignmentOffset(array, size)) % packet_size) == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Scalar>
|
template<typename Scalar>
|
||||||
@@ -54,7 +54,7 @@ void test_first_aligned()
|
|||||||
test_first_aligned_helper(array_double+1, 50);
|
test_first_aligned_helper(array_double+1, 50);
|
||||||
test_first_aligned_helper(array_double+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*)(std::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);
|
||||||
test_none_aligned_helper(array_double_plus_4_bytes+1, 50);
|
test_none_aligned_helper(array_double_plus_4_bytes+1, 50);
|
||||||
|
|
||||||
|
|||||||
10
test/main.h
10
test/main.h
@@ -142,7 +142,7 @@ namespace Eigen
|
|||||||
#define VERIFY(a) do { if (!(a)) { \
|
#define VERIFY(a) do { if (!(a)) { \
|
||||||
std::cerr << "Test " << g_test_stack.back() << " failed in "EI_PP_MAKE_STRING(__FILE__) << " (" << EI_PP_MAKE_STRING(__LINE__) << ")" \
|
std::cerr << "Test " << g_test_stack.back() << " failed in "EI_PP_MAKE_STRING(__FILE__) << " (" << EI_PP_MAKE_STRING(__LINE__) << ")" \
|
||||||
<< std::endl << " " << EI_PP_MAKE_STRING(a) << std::endl << std::endl; \
|
<< std::endl << " " << EI_PP_MAKE_STRING(a) << std::endl << std::endl; \
|
||||||
exit(2); \
|
std::exit(2); \
|
||||||
} } while (0)
|
} } while (0)
|
||||||
|
|
||||||
#define VERIFY_IS_APPROX(a, b) VERIFY(test_ei_isApprox(a, b))
|
#define VERIFY_IS_APPROX(a, b) VERIFY(test_ei_isApprox(a, b))
|
||||||
@@ -257,7 +257,7 @@ int main(int argc, char *argv[])
|
|||||||
std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
|
std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
repeat = atoi(argv[i]+1);
|
repeat = std::atoi(argv[i]+1);
|
||||||
has_set_repeat = true;
|
has_set_repeat = true;
|
||||||
if(repeat <= 0)
|
if(repeat <= 0)
|
||||||
{
|
{
|
||||||
@@ -272,7 +272,7 @@ int main(int argc, char *argv[])
|
|||||||
std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
|
std::cout << "Argument " << argv[i] << " conflicting with a former argument" << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
seed = int(strtoul(argv[i]+1, 0, 10));
|
seed = int(std::strtoul(argv[i]+1, 0, 10));
|
||||||
has_set_seed = true;
|
has_set_seed = true;
|
||||||
bool ok = seed!=0;
|
bool ok = seed!=0;
|
||||||
if(!ok)
|
if(!ok)
|
||||||
@@ -295,11 +295,11 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!has_set_seed) seed = (unsigned int) time(NULL);
|
if(!has_set_seed) seed = (unsigned int) std::time(NULL);
|
||||||
if(!has_set_repeat) repeat = DEFAULT_REPEAT;
|
if(!has_set_repeat) repeat = DEFAULT_REPEAT;
|
||||||
|
|
||||||
std::cout << "Initializing random number generator with seed " << seed << std::endl;
|
std::cout << "Initializing random number generator with seed " << seed << std::endl;
|
||||||
srand(seed);
|
std::srand(seed);
|
||||||
std::cout << "Repeating each test " << repeat << " times" << std::endl;
|
std::cout << "Repeating each test " << repeat << " times" << std::endl;
|
||||||
|
|
||||||
Eigen::g_repeat = repeat;
|
Eigen::g_repeat = repeat;
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ template<typename VectorType> void map_class_vector(const VectorType& m)
|
|||||||
Scalar* array1 = ei_aligned_new<Scalar>(size);
|
Scalar* array1 = ei_aligned_new<Scalar>(size);
|
||||||
Scalar* array2 = ei_aligned_new<Scalar>(size);
|
Scalar* array2 = ei_aligned_new<Scalar>(size);
|
||||||
Scalar* array3 = new Scalar[size+1];
|
Scalar* array3 = new Scalar[size+1];
|
||||||
Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;
|
Scalar* array3unaligned = std::size_t(array3)%16 == 0 ? array3+1 : array3;
|
||||||
|
|
||||||
Map<VectorType, Aligned>(array1, size) = VectorType::Random(size);
|
Map<VectorType, Aligned>(array1, size) = VectorType::Random(size);
|
||||||
Map<VectorType>(array2, size) = Map<VectorType>(array1, size);
|
Map<VectorType>(array2, size) = Map<VectorType>(array1, size);
|
||||||
@@ -63,7 +63,7 @@ template<typename MatrixType> void map_class_matrix(const MatrixType& m)
|
|||||||
for(int i = 0; i < size; i++) array2[i] = Scalar(1);
|
for(int i = 0; i < size; i++) array2[i] = Scalar(1);
|
||||||
Scalar* array3 = new Scalar[size+1];
|
Scalar* array3 = new Scalar[size+1];
|
||||||
for(int i = 0; i < size+1; i++) array3[i] = Scalar(1);
|
for(int i = 0; i < size+1; i++) array3[i] = Scalar(1);
|
||||||
Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;
|
Scalar* array3unaligned = std::size_t(array3)%16 == 0 ? array3+1 : array3;
|
||||||
Map<MatrixType, Aligned>(array1, rows, cols) = MatrixType::Ones(rows,cols);
|
Map<MatrixType, Aligned>(array1, rows, cols) = MatrixType::Ones(rows,cols);
|
||||||
Map<MatrixType>(array2, rows, cols) = Map<MatrixType>(array1, rows, cols);
|
Map<MatrixType>(array2, rows, cols) = Map<MatrixType>(array1, rows, cols);
|
||||||
Map<MatrixType>(array3unaligned, rows, cols) = Map<MatrixType>(array1, rows, cols);
|
Map<MatrixType>(array3unaligned, rows, cols) = Map<MatrixType>(array1, rows, cols);
|
||||||
@@ -88,7 +88,7 @@ template<typename VectorType> void map_static_methods(const VectorType& m)
|
|||||||
Scalar* array1 = ei_aligned_new<Scalar>(size);
|
Scalar* array1 = ei_aligned_new<Scalar>(size);
|
||||||
Scalar* array2 = ei_aligned_new<Scalar>(size);
|
Scalar* array2 = ei_aligned_new<Scalar>(size);
|
||||||
Scalar* array3 = new Scalar[size+1];
|
Scalar* array3 = new Scalar[size+1];
|
||||||
Scalar* array3unaligned = size_t(array3)%16 == 0 ? array3+1 : array3;
|
Scalar* array3unaligned = std::size_t(array3)%16 == 0 ? array3+1 : array3;
|
||||||
|
|
||||||
VectorType::MapAligned(array1, size) = VectorType::Random(size);
|
VectorType::MapAligned(array1, size) = VectorType::Random(size);
|
||||||
VectorType::Map(array2, size) = VectorType::Map(array1, size);
|
VectorType::Map(array2, size) = VectorType::Map(array1, size);
|
||||||
|
|||||||
@@ -50,7 +50,7 @@ void check_stdvector_matrix(const MatrixType& m)
|
|||||||
VERIFY_IS_APPROX(v[21], y);
|
VERIFY_IS_APPROX(v[21], y);
|
||||||
v.push_back(x);
|
v.push_back(x);
|
||||||
VERIFY_IS_APPROX(v[22], x);
|
VERIFY_IS_APPROX(v[22], x);
|
||||||
VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(MatrixType));
|
VERIFY((std::size_t)&(v[22]) == (std::size_t)&(v[21]) + sizeof(MatrixType));
|
||||||
|
|
||||||
// do a lot of push_back such that the vector gets internally resized
|
// do a lot of push_back such that the vector gets internally resized
|
||||||
// (with memory reallocation)
|
// (with memory reallocation)
|
||||||
@@ -85,7 +85,7 @@ void check_stdvector_transform(const TransformType&)
|
|||||||
VERIFY_IS_APPROX(v[21], y);
|
VERIFY_IS_APPROX(v[21], y);
|
||||||
v.push_back(x);
|
v.push_back(x);
|
||||||
VERIFY_IS_APPROX(v[22], x);
|
VERIFY_IS_APPROX(v[22], x);
|
||||||
VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(TransformType));
|
VERIFY((std::size_t)&(v[22]) == (std::size_t)&(v[21]) + sizeof(TransformType));
|
||||||
|
|
||||||
// do a lot of push_back such that the vector gets internally resized
|
// do a lot of push_back such that the vector gets internally resized
|
||||||
// (with memory reallocation)
|
// (with memory reallocation)
|
||||||
@@ -120,7 +120,7 @@ void check_stdvector_quaternion(const QuaternionType&)
|
|||||||
VERIFY_IS_APPROX(v[21], y);
|
VERIFY_IS_APPROX(v[21], y);
|
||||||
v.push_back(x);
|
v.push_back(x);
|
||||||
VERIFY_IS_APPROX(v[22], x);
|
VERIFY_IS_APPROX(v[22], x);
|
||||||
VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(QuaternionType));
|
VERIFY((std::size_t)&(v[22]) == (std::size_t)&(v[21]) + sizeof(QuaternionType));
|
||||||
|
|
||||||
// do a lot of push_back such that the vector gets internally resized
|
// do a lot of push_back such that the vector gets internally resized
|
||||||
// (with memory reallocation)
|
// (with memory reallocation)
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ void check_stdvector_matrix(const MatrixType& m)
|
|||||||
VERIFY_IS_APPROX(v[21], y);
|
VERIFY_IS_APPROX(v[21], y);
|
||||||
v.push_back(x);
|
v.push_back(x);
|
||||||
VERIFY_IS_APPROX(v[22], x);
|
VERIFY_IS_APPROX(v[22], x);
|
||||||
VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(MatrixType));
|
VERIFY((std::size_t)&(v[22]) == (std::size_t)&(v[21]) + sizeof(MatrixType));
|
||||||
|
|
||||||
// do a lot of push_back such that the vector gets internally resized
|
// do a lot of push_back such that the vector gets internally resized
|
||||||
// (with memory reallocation)
|
// (with memory reallocation)
|
||||||
@@ -84,7 +84,7 @@ void check_stdvector_transform(const TransformType&)
|
|||||||
VERIFY_IS_APPROX(v[21], y);
|
VERIFY_IS_APPROX(v[21], y);
|
||||||
v.push_back(x);
|
v.push_back(x);
|
||||||
VERIFY_IS_APPROX(v[22], x);
|
VERIFY_IS_APPROX(v[22], x);
|
||||||
VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(TransformType));
|
VERIFY((std::size_t)&(v[22]) == (std::size_t)&(v[21]) + sizeof(TransformType));
|
||||||
|
|
||||||
// do a lot of push_back such that the vector gets internally resized
|
// do a lot of push_back such that the vector gets internally resized
|
||||||
// (with memory reallocation)
|
// (with memory reallocation)
|
||||||
@@ -119,7 +119,7 @@ void check_stdvector_quaternion(const QuaternionType&)
|
|||||||
VERIFY_IS_APPROX(v[21], y);
|
VERIFY_IS_APPROX(v[21], y);
|
||||||
v.push_back(x);
|
v.push_back(x);
|
||||||
VERIFY_IS_APPROX(v[22], x);
|
VERIFY_IS_APPROX(v[22], x);
|
||||||
VERIFY((size_t)&(v[22]) == (size_t)&(v[21]) + sizeof(QuaternionType));
|
VERIFY((std::size_t)&(v[22]) == (std::size_t)&(v[21]) + sizeof(QuaternionType));
|
||||||
|
|
||||||
// do a lot of push_back such that the vector gets internally resized
|
// do a lot of push_back such that the vector gets internally resized
|
||||||
// (with memory reallocation)
|
// (with memory reallocation)
|
||||||
|
|||||||
@@ -98,7 +98,7 @@ void check_unalignedassert_bad()
|
|||||||
{
|
{
|
||||||
float buf[sizeof(T)+16];
|
float buf[sizeof(T)+16];
|
||||||
float *unaligned = buf;
|
float *unaligned = buf;
|
||||||
while((reinterpret_cast<size_t>(unaligned)&0xf)==0) ++unaligned; // make sure unaligned is really unaligned
|
while((reinterpret_cast<std::size_t>(unaligned)&0xf)==0) ++unaligned; // make sure unaligned is really unaligned
|
||||||
T *x = ::new(static_cast<void*>(unaligned)) T;
|
T *x = ::new(static_cast<void*>(unaligned)) T;
|
||||||
x->~T();
|
x->~T();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -85,6 +85,8 @@ void test_vectorization_logic()
|
|||||||
VERIFY(test_assign(MatrixXf(10,10),MatrixXf(20,20).block(10,10,2,3),
|
VERIFY(test_assign(MatrixXf(10,10),MatrixXf(20,20).block(10,10,2,3),
|
||||||
SliceVectorization,NoUnrolling));
|
SliceVectorization,NoUnrolling));
|
||||||
|
|
||||||
|
VERIFY(test_assign(VectorXf(10),VectorXf(10)+VectorXf(10),
|
||||||
|
LinearVectorization,NoUnrolling));
|
||||||
|
|
||||||
VERIFY(test_sum(VectorXf(10),
|
VERIFY(test_sum(VectorXf(10),
|
||||||
LinearVectorization,NoUnrolling));
|
LinearVectorization,NoUnrolling));
|
||||||
|
|||||||
Reference in New Issue
Block a user