41 # include <vcl_msvc_warnings.h> 44 #include <vxl_config.h> 45 #include <vnl/vnl_config.h> 46 #include <vnl/vnl_export.h> 47 #ifdef VNL_CHECK_FPU_ROUNDING_MODE 52 #if VNL_CONFIG_ENABLE_SSE2_ROUNDING && defined(__SSE2__) 53 # if !VXL_HAS_EMMINTRIN_H 54 # error "Required file emmintrin.h for SSE2 not found" 56 # include <emmintrin.h> 57 # define USE_SSE2_IMPL 1 60 # define USE_SSE2_IMPL 0 64 #if defined(__GNUC__) && ((defined(__i386__) || defined(__i386) || defined(__x86_64__) || defined(__x86_64))) 65 # define GCC_USE_FAST_IMPL 1 67 # define GCC_USE_FAST_IMPL 0 70 #if defined(_MSC_VER) && !defined(_WIN64) 71 # define VC_USE_FAST_IMPL 1 73 # define VC_USE_FAST_IMPL 0 100 static constexpr
double e = 2.71828182845904523536;
101 static constexpr
double log2e = 1.44269504088896340736;
102 static constexpr
double log10e = 0.43429448190325182765;
103 static constexpr
double ln2 = 0.69314718055994530942;
104 static constexpr
double ln10 = 2.30258509299404568402;
105 static constexpr
double pi = 3.14159265358979323846;
106 static constexpr
double twopi = 6.28318530717958647692;
107 static constexpr
double pi_over_2 = 1.57079632679489661923;
108 static constexpr
double pi_over_4 = 0.78539816339744830962;
109 static constexpr
double pi_over_180 = 0.01745329251994329577;
110 static constexpr
double one_over_pi = 0.31830988618379067154;
111 static constexpr
double two_over_pi = 0.63661977236758134308;
112 static constexpr
double deg_per_rad = 57.2957795130823208772;
113 static constexpr
double sqrt2pi = 2.50662827463100024161;
114 static constexpr
double two_over_sqrtpi = 1.12837916709551257390;
115 static constexpr
double one_over_sqrt2pi = 0.39894228040143267794;
116 static constexpr
double sqrt2 = 1.41421356237309504880;
117 static constexpr
double sqrt1_2 = 0.70710678118654752440;
118 static constexpr
double sqrt1_3 = 0.57735026918962573106;
119 static constexpr
double euler = 0.57721566490153286061;
122 static constexpr
double eps = 2.2204460492503131e-16;
123 static constexpr
double sqrteps = 1.490116119384766e-08;
125 static constexpr
float float_eps = 1.192092896e-07f;
126 static constexpr
float float_sqrteps = 3.4526698307e-4f;
140 #if defined(_MSC_VER) 144 _Check_return_
typename std::enable_if<std::is_integral<T>::value,
bool>::type
isnan(_In_ T t)
throw()
149 _Check_return_
typename std::enable_if<std::is_integral<T>::value,
bool>::type
isinf(_In_ T t)
throw()
154 _Check_return_
typename std::enable_if<std::is_integral<T>::value,
bool>::type
isfinite(_In_ T t)
throw()
159 _Check_return_
typename std::enable_if<std::is_integral<T>::value,
bool>::type
isnormal(_In_ T t)
throw()
166 _Check_return_
typename std::enable_if<std::is_floating_point<T>::value,
bool>::type
isnan(_In_ T t)
throw()
171 _Check_return_
typename std::enable_if<std::is_floating_point<T>::value,
bool>::type
isinf(_In_ T t)
throw()
176 _Check_return_
typename std::enable_if<std::is_floating_point<T>::value,
bool>::type
isfinite(_In_ T t)
throw()
181 _Check_return_
typename std::enable_if<std::is_floating_point<T>::value,
bool>::type
isnormal(_In_ T t)
throw()
198 template <
typename TArg>
200 template <
typename TArg>
202 template <
typename TArg>
204 template <
typename TArg>
210 #if 0 // Use std::cbrt 211 template <
typename TArg>
212 TArg cuberoot(TArg&& arg)
214 return std::cbrt(std::forward<TArg>(arg));
219 #if USE_SSE2_IMPL // Fast sse2 implementation 232 # if defined(VNL_CHECK_FPU_ROUNDING_MODE) && defined(__GNUC__) 233 assert(fegetround()==FE_TONEAREST);
235 return _mm_cvtss_si32(_mm_set_ss(x));
240 # if defined(VNL_CHECK_FPU_ROUNDING_MODE) && defined(__GNUC__) 241 assert(fegetround()==FE_TONEAREST);
243 return _mm_cvtsd_si32(_mm_set_sd(x));
246 #elif GCC_USE_FAST_IMPL // Fast gcc asm implementation 250 # ifdef VNL_CHECK_FPU_ROUNDING_MODE 251 assert(fegetround()==FE_TONEAREST);
254 __asm__ __volatile__ (
"fistpl %0" :
"=m"(r) :
"t"(x) :
"st");
260 # ifdef VNL_CHECK_FPU_ROUNDING_MODE 261 assert(fegetround()==FE_TONEAREST);
264 __asm__ __volatile__ (
"fistpl %0" :
"=m"(r) :
"t"(x) :
"st");
268 #elif VC_USE_FAST_IMPL // Fast msvc asm implementation 290 #else // Vanilla implementation 297 const int r = static_cast<int>(x);
298 if ( x != static_cast<float>(r) )
return r;
304 const int r = static_cast<int>(x);
305 if ( x != static_cast<float>(r) )
return r;
315 const int r = static_cast<int>(x);
316 if ( x != static_cast<double>(r) )
return r;
322 const int r = static_cast<int>(x);
323 if ( x != static_cast<double>(r) )
return r;
331 #if USE_SSE2_IMPL || GCC_USE_FAST_IMPL || VC_USE_FAST_IMPL 347 #else // Vanilla implementation 352 return static_cast<int>(x>=0.f?x:(x==static_cast<int>(x)?x:x-1.f));
358 return static_cast<int>(x>=0.?x:(x==static_cast<int>(x)?x:x-1.));
363 #if USE_SSE2_IMPL || GCC_USE_FAST_IMPL || VC_USE_FAST_IMPL 377 #else // Vanilla implementation 379 inline int rnd(
float x) {
return x>=0.f?static_cast<int>(x+.5f):static_cast<int>(x-.5f); }
380 inline int rnd(
double x) {
return x>=0.0?static_cast<int>(x+0.5):static_cast<int>(x-0.5); }
384 #if USE_SSE2_IMPL // Fast sse2 implementation 392 inline int floor(
float x)
394 # if defined(VNL_CHECK_FPU_ROUNDING_MODE) && defined(__GNUC__) 395 assert(fegetround()==FE_TONEAREST);
397 return _mm_cvtss_si32(_mm_set_ss(2*x-.5f))>>1;
400 inline int floor(
double x)
402 # if defined(VNL_CHECK_FPU_ROUNDING_MODE) && defined(__GNUC__) 403 assert(fegetround()==FE_TONEAREST);
405 return _mm_cvtsd_si32(_mm_set_sd(2*x-.5))>>1;
408 #elif GCC_USE_FAST_IMPL // Fast gcc asm implementation 410 inline int floor(
float x)
412 # ifdef VNL_CHECK_FPU_ROUNDING_MODE 413 assert(fegetround()==FE_TONEAREST);
417 __asm__ __volatile__ (
"fistpl %0" :
"=m"(r) :
"t"(x) :
"st");
421 inline int floor(
double x)
423 # ifdef VNL_CHECK_FPU_ROUNDING_MODE 424 assert(fegetround()==FE_TONEAREST);
428 __asm__ __volatile__ (
"fistpl %0" :
"=m"(r) :
"t"(x) :
"st");
432 #elif VC_USE_FAST_IMPL // Fast msvc asm implementation 434 inline int floor(
float x)
445 inline int floor(
double x)
456 #else // Vanilla implementation 460 return static_cast<int>(x>=0.f?x:(x==static_cast<int>(x)?x:x-1.f));
465 return static_cast<int>(x>=0.0?x:(x==static_cast<int>(x)?x:x-1.0));
471 #if USE_SSE2_IMPL // Fast sse2 implementation 479 inline int ceil(
float x)
481 # if defined(VNL_CHECK_FPU_ROUNDING_MODE) && defined(__GNUC__) 482 assert(fegetround()==FE_TONEAREST);
484 return -(_mm_cvtss_si32(_mm_set_ss(-.5f-2*x))>>1);
487 inline int ceil(
double x)
489 # if defined(VNL_CHECK_FPU_ROUNDING_MODE) && defined(__GNUC__) 490 assert(fegetround()==FE_TONEAREST);
492 return -(_mm_cvtsd_si32(_mm_set_sd(-.5-2*x))>>1);
495 #elif GCC_USE_FAST_IMPL // Fast gcc asm implementation 497 inline int ceil(
float x)
499 # ifdef VNL_CHECK_FPU_ROUNDING_MODE 500 assert(fegetround()==FE_TONEAREST);
504 __asm__ __volatile__ (
"fistpl %0" :
"=m"(r) :
"t"(x) :
"st");
508 inline int ceil(
double x)
510 # ifdef VNL_CHECK_FPU_ROUNDING_MODE 511 assert(fegetround()==FE_TONEAREST);
515 __asm__ __volatile__ (
"fistpl %0" :
"=m"(r) :
"t"(x) :
"st");
519 #elif VC_USE_FAST_IMPL // Fast msvc asm implementation 521 inline int ceil(
float x)
532 inline int ceil(
double x)
543 #else // Vanilla implementation 547 return static_cast<int>(x<0.f?x:(x==static_cast<int>(x)?x:x+1.f));
552 return static_cast<int>(x<0.0?x:(x==static_cast<int>(x)?x:x+1.0));
558 inline bool abs(
bool x) {
return x; }
559 inline unsigned char abs(
unsigned char x) {
return x; }
560 inline unsigned char abs(
signed char x) {
return x < 0 ? static_cast<unsigned char>(-x) : x; }
561 inline unsigned char abs(
char x) {
return static_cast<unsigned char>(x); }
562 inline unsigned short abs(
short x) {
return x < 0 ? static_cast<unsigned short>(-x) : x; }
563 inline unsigned short abs(
unsigned short x) {
return x; }
564 inline unsigned int abs(
int x) {
return x < 0 ? -x : x; }
565 inline unsigned int abs(
unsigned int x) {
return x; }
566 inline unsigned long abs(
long x) {
return x < 0L ? -x : x; }
567 inline unsigned long abs(
unsigned long x) {
return x; }
569 inline unsigned long long abs(
long long x) {
return x < 0LL ? -x : x; }
570 inline unsigned long long abs(
unsigned long long x) {
return x; }
572 inline float abs(
float x) {
return x < 0.0f ? -x : x; }
573 inline double abs(
double x) {
return x < 0.0 ? -x : x; }
574 inline long double abs(
long double x) {
return x < 0.0 ? -x : x; }
577 inline bool sqr(
bool x) {
return x; }
578 inline int sqr(
int x) {
return x*x; }
579 inline unsigned int sqr(
unsigned int x) {
return x*x; }
580 inline long sqr(
long x) {
return x*x; }
581 inline unsigned long sqr(
unsigned long x) {
return x*x; }
583 inline long long sqr(
long long x) {
return x*x; }
584 inline unsigned long long sqr(
unsigned long long x) {
return x*x; }
586 inline float sqr(
float x) {
return x*x; }
587 inline double sqr(
double x) {
return x*x; }
590 inline bool cube(
bool x) {
return x; }
591 inline int cube(
int x) {
return x*x*x; }
592 inline unsigned int cube(
unsigned int x) {
return x*x*x; }
593 inline long cube(
long x) {
return x*x*x; }
594 inline unsigned long cube(
unsigned long x) {
return x*x*x; }
596 inline long long cube(
long long x) {
return x*x*x; }
597 inline unsigned long long cube(
unsigned long long x) {
return x*x*x; }
599 inline float cube(
float x) {
return x*x*x; }
600 inline double cube(
double x) {
return x*x*x; }
603 inline int sgn(
int x) {
return x?((x>0)?1:-1):0; }
604 inline int sgn(
long x) {
return x?((x>0)?1:-1):0; }
606 inline int sgn(
long long x) {
return x?((x>0)?1:-1):0; }
608 inline int sgn(
float x) {
return (x != 0)?((x>0)?1:-1):0; }
609 inline int sgn(
double x) {
return (x != 0)?((x>0)?1:-1):0; }
612 inline int sgn0(
int x) {
return (x>=0)?1:-1; }
613 inline int sgn0(
long x) {
return (x>=0)?1:-1; }
615 inline int sgn0(
long long x) {
return (x>=0)?1:-1; }
617 inline int sgn0(
float x) {
return (x>=0)?1:-1; }
618 inline int sgn0(
double x) {
return (x>=0)?1:-1; }
642 inline unsigned long long remainder_truncated(
unsigned long long x,
unsigned long long y) {
return x % y; }
653 inline unsigned long long remainder_floored(
unsigned long long x,
unsigned long long y) {
return x % y; }
656 inline long double remainder_floored(
long double x,
long double y) {
return fmod(fmod(x,y)+y,y); }
659 #endif // vnl_math_h_ double angle_0_to_2pi(double angle)
Convert an angle to [0, 2Pi) range.
double angle_minuspi_to_pi(double angle)
Convert an angle to [-Pi, Pi) range.
int remainder_floored(int x, int y)
int remainder_truncated(int x, int y)
real numerical constants.
vnl_bignum squared_magnitude(vnl_bignum const &x)
VNL_EXPORT double angle(v const &, v const &)
bool isnan(vnl_bignum const &)
bool isfinite(vnl_bignum const &x)
VNL_EXPORT T vnl_huge_val(T)
Type-accessible infinities for use in templates.
vnl_decnum cube(vnl_decnum const &x)
vnl_decnum max(vnl_decnum const &x, vnl_decnum const &y)
int rnd_halfinttoeven(float x)
vnl_bignum abs(vnl_bignum const &x)
vnl_decnum min(vnl_decnum const &x, vnl_decnum const &y)
vnl_bignum sqr(vnl_bignum const &x)
int rnd_halfintup(float x)