mirror of
https://gitlab.com/libeigen/eigen.git
synced 2026-04-10 11:34:33 +08:00
Compare commits
40 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee499a855c | ||
|
|
bc0ce37395 | ||
|
|
65c0b2a04d | ||
|
|
93d8d0e1b5 | ||
|
|
501063d9e9 | ||
|
|
c76c8d6917 | ||
|
|
0bb8688d70 | ||
|
|
ea87337647 | ||
|
|
12557fb2a2 | ||
|
|
8a95876825 | ||
|
|
82d7c4e1d0 | ||
|
|
8d4b0aae04 | ||
|
|
4785e27d6a | ||
|
|
20b544b444 | ||
|
|
135013c608 | ||
|
|
1625a5e3f8 | ||
|
|
47a61bbd80 | ||
|
|
12bcfae0c5 | ||
|
|
5f42104e0a | ||
|
|
6b3f81b414 | ||
|
|
1f4b8e6a36 | ||
|
|
e1f61b40c8 | ||
|
|
f369dc873e | ||
|
|
c03bca21c4 | ||
|
|
ed6eb5a625 | ||
|
|
9488a12125 | ||
|
|
7b44957c4b | ||
|
|
743ad75595 | ||
|
|
a9eabed421 | ||
|
|
cd34a1d351 | ||
|
|
3e963ee69d | ||
|
|
6cc9dc17f2 | ||
|
|
7852a48a2f | ||
|
|
d209120180 | ||
|
|
55c0707b1d | ||
|
|
72044ca925 | ||
|
|
c2b8ca7493 | ||
|
|
018cb8975a | ||
|
|
3ab280ce4e | ||
|
|
b40030753b |
@@ -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.11")
|
set(EIGEN_VERSION_NUMBER "2.0.13")
|
||||||
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
|
||||||
|
|||||||
10
Eigen/Core
10
Eigen/Core
@@ -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
|
||||||
@@ -26,7 +28,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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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
|
||||||
@@ -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
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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()];
|
||||||
|
|||||||
@@ -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()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -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));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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 ///////////
|
||||||
|
|||||||
@@ -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
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -639,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>
|
||||||
@@ -650,7 +648,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);
|
||||||
@@ -667,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>
|
||||||
@@ -678,7 +677,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 +708,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 +733,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 +757,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 +789,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 +801,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
|
||||||
|
|||||||
@@ -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 13
|
||||||
|
|
||||||
#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
|
||||||
@@ -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 !
|
||||||
|
|||||||
@@ -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
|
||||||
@@ -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)");
|
||||||
@@ -85,9 +85,9 @@ inline void* ei_aligned_malloc(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
|
||||||
@@ -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);
|
||||||
@@ -156,11 +156,11 @@ template<typename T, bool Align> inline T* ei_conditional_aligned_new(size_t siz
|
|||||||
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)
|
||||||
@@ -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);
|
||||||
@@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -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;
|
||||||
|
|||||||
@@ -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 }; };
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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))
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -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()
|
||||||
@@ -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
|
||||||
|
|
||||||
|
|||||||
@@ -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(
|
||||||
|
|||||||
@@ -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"
|
||||||
|
|
||||||
|
|||||||
@@ -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})
|
||||||
set_target_properties(${target} PROPERTIES ${prop} "${previous} ${value}")
|
if(previous MATCHES "NOTFOUND")
|
||||||
|
set_target_properties(${target} PROPERTIES ${prop} "${value}")
|
||||||
|
else()
|
||||||
|
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)
|
||||||
@@ -153,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)
|
||||||
@@ -201,7 +213,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,12 +228,15 @@ 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)
|
||||||
ei_add_test(sparse_vector)
|
if(NOT EIGEN_DEFAULT_TO_ROW_MAJOR)
|
||||||
ei_add_test(sparse_basic)
|
ei_add_test(sparse_vector)
|
||||||
ei_add_test(sparse_solvers " " "${SPARSE_LIBS}")
|
ei_add_test(sparse_basic)
|
||||||
ei_add_test(sparse_product)
|
ei_add_test(sparse_solvers " " "${SPARSE_LIBS}")
|
||||||
|
ei_add_test(sparse_product)
|
||||||
|
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})
|
||||||
|
|
||||||
@@ -268,11 +283,22 @@ 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()
|
||||||
|
|
||||||
|
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>
|
||||||
@@ -50,11 +50,11 @@ 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*)(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);
|
||||||
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
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;
|
||||||
|
|||||||
52
test/map.cpp
52
test/map.cpp
@@ -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;
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ template<typename VectorType> void map_class(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);
|
||||||
@@ -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 = std::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;
|
||||||
@@ -60,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);
|
||||||
@@ -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()) );
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
@@ -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();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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));
|
||||||
|
|||||||
Reference in New Issue
Block a user