mirror of
https://gitlab.com/libeigen/eigen.git
synced 2025-05-18 23:57:39 +08:00
Pulled latest updates from trunk
This commit is contained in:
commit
4286b2d494
@ -748,13 +748,13 @@ template<typename T> EIGEN_DEVICE_FUNC bool isinf_msvc_helper(T x)
|
||||
}
|
||||
|
||||
//MSVC defines a _isnan builtin function, but for double only
|
||||
template<> EIGEN_DEVICE_FUNC inline bool isnan_impl(const long double& x) { return _isnan(x); }
|
||||
template<> EIGEN_DEVICE_FUNC inline bool isnan_impl(const double& x) { return _isnan(x); }
|
||||
template<> EIGEN_DEVICE_FUNC inline bool isnan_impl(const float& x) { return _isnan(x); }
|
||||
EIGEN_DEVICE_FUNC inline bool isnan_impl(const long double& x) { return _isnan(x); }
|
||||
EIGEN_DEVICE_FUNC inline bool isnan_impl(const double& x) { return _isnan(x); }
|
||||
EIGEN_DEVICE_FUNC inline bool isnan_impl(const float& x) { return _isnan(x); }
|
||||
|
||||
template<> EIGEN_DEVICE_FUNC inline bool isinf_impl(const long double& x) { return isinf_msvc_helper(x); }
|
||||
template<> EIGEN_DEVICE_FUNC inline bool isinf_impl(const double& x) { return isinf_msvc_helper(x); }
|
||||
template<> EIGEN_DEVICE_FUNC inline bool isinf_impl(const float& x) { return isinf_msvc_helper(x); }
|
||||
EIGEN_DEVICE_FUNC inline bool isinf_impl(const long double& x) { return isinf_msvc_helper(x); }
|
||||
EIGEN_DEVICE_FUNC inline bool isinf_impl(const double& x) { return isinf_msvc_helper(x); }
|
||||
EIGEN_DEVICE_FUNC inline bool isinf_impl(const float& x) { return isinf_msvc_helper(x); }
|
||||
|
||||
#elif (defined __FINITE_MATH_ONLY__ && __FINITE_MATH_ONLY__ && EIGEN_COMP_GNUC)
|
||||
|
||||
|
@ -36,37 +36,40 @@ const std::ptrdiff_t defaultL3CacheSize = 512*1024;
|
||||
#endif
|
||||
|
||||
/** \internal */
|
||||
inline void manage_caching_sizes(Action action, std::ptrdiff_t* l1, std::ptrdiff_t* l2, std::ptrdiff_t* l3)
|
||||
{
|
||||
static bool m_cache_sizes_initialized = false;
|
||||
static std::ptrdiff_t m_l1CacheSize = 0;
|
||||
static std::ptrdiff_t m_l2CacheSize = 0;
|
||||
static std::ptrdiff_t m_l3CacheSize = 0;
|
||||
|
||||
if(!m_cache_sizes_initialized)
|
||||
{
|
||||
struct CacheSizes {
|
||||
CacheSizes(): m_l1(-1),m_l2(-1),m_l3(-1) {
|
||||
int l1CacheSize, l2CacheSize, l3CacheSize;
|
||||
queryCacheSizes(l1CacheSize, l2CacheSize, l3CacheSize);
|
||||
m_l1CacheSize = manage_caching_sizes_helper(l1CacheSize, defaultL1CacheSize);
|
||||
m_l2CacheSize = manage_caching_sizes_helper(l2CacheSize, defaultL2CacheSize);
|
||||
m_l3CacheSize = manage_caching_sizes_helper(l3CacheSize, defaultL3CacheSize);
|
||||
m_cache_sizes_initialized = true;
|
||||
m_l1 = manage_caching_sizes_helper(l1CacheSize, defaultL1CacheSize);
|
||||
m_l2 = manage_caching_sizes_helper(l2CacheSize, defaultL2CacheSize);
|
||||
m_l3 = manage_caching_sizes_helper(l3CacheSize, defaultL3CacheSize);
|
||||
}
|
||||
|
||||
std::ptrdiff_t m_l1;
|
||||
std::ptrdiff_t m_l2;
|
||||
std::ptrdiff_t m_l3;
|
||||
};
|
||||
|
||||
|
||||
/** \internal */
|
||||
inline void manage_caching_sizes(Action action, std::ptrdiff_t* l1, std::ptrdiff_t* l2, std::ptrdiff_t* l3)
|
||||
{
|
||||
static CacheSizes m_cacheSizes;
|
||||
|
||||
if(action==SetAction)
|
||||
{
|
||||
// set the cpu cache size and cache all block sizes from a global cache size in byte
|
||||
eigen_internal_assert(l1!=0 && l2!=0);
|
||||
m_l1CacheSize = *l1;
|
||||
m_l2CacheSize = *l2;
|
||||
m_l3CacheSize = *l3;
|
||||
m_cacheSizes.m_l1 = *l1;
|
||||
m_cacheSizes.m_l2 = *l2;
|
||||
m_cacheSizes.m_l3 = *l3;
|
||||
}
|
||||
else if(action==GetAction)
|
||||
{
|
||||
eigen_internal_assert(l1!=0 && l2!=0);
|
||||
*l1 = m_l1CacheSize;
|
||||
*l2 = m_l2CacheSize;
|
||||
*l3 = m_l3CacheSize;
|
||||
*l1 = m_cacheSizes.m_l1;
|
||||
*l2 = m_cacheSizes.m_l2;
|
||||
*l3 = m_cacheSizes.m_l3;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -10,6 +10,7 @@
|
||||
// 4244 - 'argument' : conversion from 'type1' to 'type2', possible loss of data
|
||||
// 4273 - QtAlignedMalloc, inconsistent DLL linkage
|
||||
// 4324 - structure was padded due to declspec(align())
|
||||
// 4503 - decorated name length exceeded, name was truncated
|
||||
// 4512 - assignment operator could not be generated
|
||||
// 4522 - 'class' : multiple assignment operators specified
|
||||
// 4700 - uninitialized local variable 'xyz' used
|
||||
@ -17,7 +18,7 @@
|
||||
#ifndef EIGEN_PERMANENTLY_DISABLE_STUPID_WARNINGS
|
||||
#pragma warning( push )
|
||||
#endif
|
||||
#pragma warning( disable : 4100 4101 4127 4181 4211 4244 4273 4324 4512 4522 4700 4717 )
|
||||
#pragma warning( disable : 4100 4101 4127 4181 4211 4244 4273 4324 4503 4512 4522 4700 4717 )
|
||||
#elif defined __INTEL_COMPILER
|
||||
// 2196 - routine is both "inline" and "noinline" ("noinline" assumed)
|
||||
// ICC 12 generates this warning even without any inline keyword, when defining class methods 'inline' i.e. inside of class body
|
||||
|
@ -720,7 +720,7 @@ void FullPivLU<_MatrixType>::_solve_impl(const RhsType &rhs, DstType &dst) const
|
||||
|
||||
const Index rows = this->rows(),
|
||||
cols = this->cols(),
|
||||
nonzero_pivots = this->nonzeroPivots();
|
||||
nonzero_pivots = this->rank();
|
||||
eigen_assert(rhs.rows() == rows);
|
||||
const Index smalldim = (std::min)(rows, cols);
|
||||
|
||||
|
@ -39,10 +39,9 @@ class CwiseBinaryOpImpl<BinaryOp, Lhs, Rhs, Sparse>
|
||||
EIGEN_SPARSE_PUBLIC_INTERFACE(Derived)
|
||||
CwiseBinaryOpImpl()
|
||||
{
|
||||
typedef typename internal::traits<Lhs>::StorageKind LhsStorageKind;
|
||||
typedef typename internal::traits<Rhs>::StorageKind RhsStorageKind;
|
||||
EIGEN_STATIC_ASSERT((
|
||||
(!internal::is_same<LhsStorageKind,RhsStorageKind>::value)
|
||||
(!internal::is_same<typename internal::traits<Lhs>::StorageKind,
|
||||
typename internal::traits<Rhs>::StorageKind>::value)
|
||||
|| ((Lhs::Flags&RowMajorBit) == (Rhs::Flags&RowMajorBit))),
|
||||
THE_STORAGE_ORDER_OF_BOTH_SIDES_MUST_MATCH);
|
||||
}
|
||||
|
@ -43,6 +43,8 @@ int main(int argc, char** argv)
|
||||
}
|
||||
\endcode
|
||||
|
||||
\note With Eigen 3.3, and a fully C++11 compliant compiler (i.e., <a href="http://en.cppreference.com/w/cpp/language/storage_duration#Static_local_variables">thread-safe static local variable initialization</a>), then calling \c initParallel() is optional.
|
||||
|
||||
\warning note that all functions generating random matrices are \b not re-entrant nor thread-safe. Those include DenseBase::Random(), and DenseBase::setRandom() despite a call to Eigen::initParallel(). This is because these functions are based on std::rand which is not re-entrant. For thread-safe random generator, we recommend the use of boost::random or c++11 random feature.
|
||||
|
||||
In the case your application is parallelized with OpenMP, you might want to disable Eigen's own parallization as detailed in the previous section.
|
||||
|
@ -12,6 +12,12 @@
|
||||
#include <Eigen/LU>
|
||||
#include <Eigen/SVD>
|
||||
|
||||
template<typename T>
|
||||
Matrix<T,2,1> angleToVec(T a)
|
||||
{
|
||||
return Matrix<T,2,1>(std::cos(a), std::sin(a));
|
||||
}
|
||||
|
||||
template<typename Scalar, int Mode, int Options> void non_projective_only()
|
||||
{
|
||||
/* this test covers the following files:
|
||||
@ -130,14 +136,16 @@ template<typename Scalar, int Mode, int Options> void transformations()
|
||||
AngleAxisx aa = AngleAxisx(q1);
|
||||
VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1);
|
||||
|
||||
if(abs(aa.angle()) > NumTraits<Scalar>::dummy_precision())
|
||||
// The following test is stable only if 2*angle != angle and v1 is not colinear with axis
|
||||
if( (abs(aa.angle()) > test_precision<Scalar>()) && (abs(aa.axis().dot(v1.normalized()))<(Scalar(1)-Scalar(4)*test_precision<Scalar>())) )
|
||||
{
|
||||
VERIFY( !(q1 * v1).isApprox(Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1) );
|
||||
}
|
||||
|
||||
aa.fromRotationMatrix(aa.toRotationMatrix());
|
||||
VERIFY_IS_APPROX(q1 * v1, Quaternionx(aa) * v1);
|
||||
if(abs(aa.angle()) > NumTraits<Scalar>::dummy_precision())
|
||||
// The following test is stable only if 2*angle != angle and v1 is not colinear with axis
|
||||
if( (abs(aa.angle()) > test_precision<Scalar>()) && (abs(aa.axis().dot(v1.normalized()))<(Scalar(1)-Scalar(4)*test_precision<Scalar>())) )
|
||||
{
|
||||
VERIFY( !(q1 * v1).isApprox(Quaternionx(AngleAxisx(aa.angle()*2,aa.axis())) * v1) );
|
||||
}
|
||||
@ -214,7 +222,9 @@ template<typename Scalar, int Mode, int Options> void transformations()
|
||||
t4 *= aa3;
|
||||
VERIFY_IS_APPROX(t3.matrix(), t4.matrix());
|
||||
|
||||
v3 = Vector3::Random();
|
||||
do {
|
||||
v3 = Vector3::Random();
|
||||
} while (v3.cwiseAbs().minCoeff()<NumTraits<Scalar>::epsilon());
|
||||
Translation3 tv3(v3);
|
||||
Transform3 t5(tv3);
|
||||
t4 = tv3;
|
||||
@ -414,14 +424,12 @@ template<typename Scalar, int Mode, int Options> void transformations()
|
||||
Scalar angle = internal::random<Scalar>(-100,100);
|
||||
Rotation2D<Scalar> rot2(angle);
|
||||
VERIFY( rot2.smallestPositiveAngle() >= 0 );
|
||||
VERIFY( rot2.smallestPositiveAngle() < Scalar(2)*Scalar(EIGEN_PI) );
|
||||
VERIFY_IS_APPROX( std::cos(rot2.smallestPositiveAngle()), std::cos(rot2.angle()) );
|
||||
VERIFY_IS_APPROX( std::sin(rot2.smallestPositiveAngle()), std::sin(rot2.angle()) );
|
||||
VERIFY( rot2.smallestPositiveAngle() <= Scalar(2)*Scalar(EIGEN_PI) );
|
||||
VERIFY_IS_APPROX( angleToVec(rot2.smallestPositiveAngle()), angleToVec(rot2.angle()) );
|
||||
|
||||
VERIFY( rot2.smallestAngle() >= -Scalar(EIGEN_PI) );
|
||||
VERIFY( rot2.smallestAngle() <= Scalar(EIGEN_PI) );
|
||||
VERIFY_IS_APPROX( std::cos(rot2.smallestAngle()), std::cos(rot2.angle()) );
|
||||
VERIFY_IS_APPROX( std::sin(rot2.smallestAngle()), std::sin(rot2.angle()) );
|
||||
VERIFY_IS_APPROX( angleToVec(rot2.smallestAngle()), angleToVec(rot2.angle()) );
|
||||
}
|
||||
|
||||
s0 = internal::random<Scalar>(-100,100);
|
||||
@ -437,7 +445,7 @@ template<typename Scalar, int Mode, int Options> void transformations()
|
||||
VERIFY_IS_APPROX(t20,t21);
|
||||
|
||||
VERIFY_IS_APPROX(s0, (R0.slerp(0, R1)).angle());
|
||||
VERIFY_IS_APPROX(R1.smallestPositiveAngle(), (R0.slerp(1, R1)).smallestPositiveAngle());
|
||||
VERIFY_IS_APPROX( angleToVec(R1.smallestPositiveAngle()), angleToVec((R0.slerp(1, R1)).smallestPositiveAngle()) );
|
||||
VERIFY_IS_APPROX(R0.smallestPositiveAngle(), (R0.slerp(0.5, R0)).smallestPositiveAngle());
|
||||
|
||||
if(std::cos(s0)>0)
|
||||
@ -447,13 +455,14 @@ template<typename Scalar, int Mode, int Options> void transformations()
|
||||
|
||||
// Check path length
|
||||
Scalar l = 0;
|
||||
for(int k=0; k<100; ++k)
|
||||
int path_steps = 100;
|
||||
for(int k=0; k<path_steps; ++k)
|
||||
{
|
||||
Scalar a1 = R0.slerp(Scalar(k)/Scalar(100), R1).angle();
|
||||
Scalar a2 = R0.slerp(Scalar(k+1)/Scalar(100), R1).angle();
|
||||
Scalar a1 = R0.slerp(Scalar(k)/Scalar(path_steps), R1).angle();
|
||||
Scalar a2 = R0.slerp(Scalar(k+1)/Scalar(path_steps), R1).angle();
|
||||
l += std::abs(a2-a1);
|
||||
}
|
||||
VERIFY(l<=EIGEN_PI);
|
||||
VERIFY(l<=EIGEN_PI*(Scalar(1)+NumTraits<Scalar>::epsilon()*Scalar(path_steps/2)));
|
||||
|
||||
// check basic features
|
||||
{
|
||||
|
Loading…
x
Reference in New Issue
Block a user