vnl_math.h
Go to the documentation of this file.
1 // This is core/vnl/vnl_math.h
2 #ifndef vnl_math_h_
3 #define vnl_math_h_
4 //:
5 // \file
6 // \brief Namespace with standard math functions
7 //
8 // The vnl_math namespace provides a standard set of the simple mathematical
9 // functions (min, max, sqr, sgn, rnd, abs), and some predefined constants
10 // such as pi and e, which are not defined by the ANSI C++ standard.
11 //
12 // There are complex versions defined in vnl_complex.h
13 //
14 // That's right, M_PI is nonstandard!
15 //
16 // Aside from e, pi and their associates the namespace also defines eps,
17 // the IEEE double machine precision. This is the smallest number
18 // eps such that 1+eps != 1.
19 //
20 // The operations are overloaded for int, float and double arguments,
21 // which in combination with inlining can make them more efficient than
22 // their counterparts in the standard C library.
23 //
24 // \author Andrew W. Fitzgibbon, Oxford RRG
25 // \date July 13, 1996
26 //
27 // \verbatim
28 // Modifications
29 // 21 May 1998 AWF Removed conditional VCL_IMPLEMENT_STATIC_CONSTS, sometimes gcc needs them.
30 // LSB (Modifications) 23 Jan 2001 Documentation tidied
31 // Peter Vanroose - 7 Sep 2002 - maxdouble etc. replaced by vnl_numeric_traits<T>::maxval
32 // Amitha Perera - 13 Sep 2002 - make constant initialization standards compliant.
33 // Peter Vanroose -22 Oct 2012 - was a class, now is a namespace
34 // also renamed functions vnl_math_isnan etc. to vnl_math::isnan
35 // \endverbatim
36 
37 #include <cmath>
38 #include <algorithm>
39 #include <complex>
40 #ifdef _MSC_VER
41 # include <vcl_msvc_warnings.h>
42 #endif
43 #include "dll.h"
44 #include <vxl_config.h>
45 #include <vnl/vnl_config.h> // for VNL_CONFIG_ENABLE_SSE2_ROUNDING
46 #include <vnl/vnl_export.h>
47 #ifdef VNL_CHECK_FPU_ROUNDING_MODE
48 #include <cassert>
49 #endif
50 
51 // Figure out when the fast implementation can be used
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"
55 # else
56 # include <emmintrin.h> // sse 2 intrinsics
57 # define USE_SSE2_IMPL 1
58 # endif
59 #else
60 # define USE_SSE2_IMPL 0
61 #endif
62 
63 // Turn on fast impl when using GCC on Intel-based machines with the following exception:
64 #if defined(__GNUC__) && ((defined(__i386__) || defined(__i386) || defined(__x86_64__) || defined(__x86_64)))
65 # define GCC_USE_FAST_IMPL 1
66 #else
67 # define GCC_USE_FAST_IMPL 0
68 #endif
69 // Turn on fast impl when using msvc on 32 bits windows
70 #if defined(_MSC_VER) && !defined(_WIN64)
71 # define VC_USE_FAST_IMPL 1
72 #else
73 # define VC_USE_FAST_IMPL 0
74 #endif
75 
76 
77 
78 //: Type-accessible infinities for use in templates.
79 template <class T> VNL_EXPORT T vnl_huge_val(T);
80 extern VNL_EXPORT long double vnl_huge_val(long double);
81 extern VNL_EXPORT double vnl_huge_val(double);
82 extern VNL_EXPORT float vnl_huge_val(float);
83 extern VNL_EXPORT long int vnl_huge_val(long int);
84 extern VNL_EXPORT int vnl_huge_val(int);
85 extern VNL_EXPORT short vnl_huge_val(short);
86 extern VNL_EXPORT char vnl_huge_val(char);
87 
88 //: real numerical constants
89 // Strictly speaking, the static declaration of the constant variables is
90 // redundant with the implicit behavior in C++ of objects declared const
91 // as defined at:
92 // "C++98 7.1.1/6: ...Objects declared const and not explicitly declared
93 // extern have internal linkage."
94 //
95 // Explicit use of the static keyword is used to make the code easier to
96 // understand.
97 namespace vnl_math
98 {
99  //: pi, e and all that
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;
120 
121  //: IEEE double machine precision
122  static constexpr double eps = 2.2204460492503131e-16;
123  static constexpr double sqrteps = 1.490116119384766e-08;
124  //: IEEE single machine precision
125  static constexpr float float_eps = 1.192092896e-07f;
126  static constexpr float float_sqrteps = 3.4526698307e-4f;
127 
128  //: Convert an angle to [0, 2Pi) range
129  VNL_EXPORT double angle_0_to_2pi(double angle);
130  //: Convert an angle to [-Pi, Pi) range
131  VNL_EXPORT double angle_minuspi_to_pi(double angle);
132 }
133 
134 // Note that the three template functions below should not be declared "inline"
135 // since that would override the non-inline specialisations. - PVr.
136 //
137 
138 namespace vnl_math
139 {
140 #if defined(_MSC_VER)
141  // MSVC does not properly implement isfinite, iinf, isnan for C++11 conformance for integral types
142  // For integral types only:
143  template<typename T>
144  _Check_return_ typename std::enable_if<std::is_integral<T>::value, bool>::type isnan(_In_ T t) throw()
145  {
146  return std::isnan(static_cast<double>(t));
147  }
148  template<typename T>
149  _Check_return_ typename std::enable_if<std::is_integral<T>::value, bool>::type isinf(_In_ T t) throw()
150  {
151  return std::isinf(static_cast<double>(t));
152  }
153  template<typename T>
154  _Check_return_ typename std::enable_if<std::is_integral<T>::value, bool>::type isfinite(_In_ T t) throw()
155  {
156  return std::isfinite(static_cast<double>(t));
157  }
158  template<typename T>
159  _Check_return_ typename std::enable_if<std::is_integral<T>::value, bool>::type isnormal(_In_ T t) throw()
160  {
161  return std::isnormal(static_cast<double>(t));
162  }
163 
164  // Floating point types can alias C++ standard that is implemented
165  template<typename T>
166  _Check_return_ typename std::enable_if<std::is_floating_point<T>::value, bool>::type isnan(_In_ T t) throw()
167  {
168  return std::isnan(t);
169  }
170  template<typename T>
171  _Check_return_ typename std::enable_if<std::is_floating_point<T>::value, bool>::type isinf(_In_ T t) throw()
172  {
173  return std::isinf(t);
174  }
175  template<typename T>
176  _Check_return_ typename std::enable_if<std::is_floating_point<T>::value, bool>::type isfinite(_In_ T t) throw()
177  {
178  return std::isfinite(t);
179  }
180  template<typename T>
181  _Check_return_ typename std::enable_if<std::is_floating_point<T>::value, bool>::type isnormal(_In_ T t) throw()
182  {
183  return std::isnormal(t);
184  }
185 #else
186  // https://en.cppreference.com/w/cpp/numeric/math/isinf indicates that isinf should return bool
187  // However, several compiler environments do not properly conform to the C++11 standard for
188  // returning bool from these functions. Wrap them to ensure conformance, and
189  // rely on the compiler to optimize the overhead away.
190 
191  // Return a signed integer type has been seen with the following
192  // compilers/libstdc++:
193  // RHEL7-devtool-6-gcc6.3
194  // RHEL7-devtool-6-gcc6.3-m32
195  // RHEL7-devtool-7-gcc7.2
196  // RHEL7-devtool-7-gcc7.2-m32
197 
198  template <typename TArg>
199  inline bool isinf(TArg arg) { return bool(std::isinf(arg)); }
200  template <typename TArg>
201  inline bool isnan(TArg arg) { return bool(std::isnan(arg)); }
202  template <typename TArg>
203  inline bool isfinite(TArg arg) { return bool(std::isfinite(arg)); }
204  template <typename TArg>
205  inline bool isnormal(TArg arg) { return bool(std::isnormal(arg)); }
206 #endif
207  using std::max;
208  using std::min;
209  using std::cbrt;
210 #if 0 // Use std::cbrt
211  template <typename TArg>
212  TArg cuberoot(TArg&& arg)
213  {
214  return std::cbrt(std::forward<TArg>(arg));
215  }
216 #endif
217  using std::hypot;
218 
219 #if USE_SSE2_IMPL // Fast sse2 implementation
220 
221 // rnd_halfinttoeven -- round towards nearest integer
222 // halfway cases are rounded towards the nearest even integer, e.g.
223 // rnd_halfinttoeven( 1.5) == 2
224 // rnd_halfinttoeven(-1.5) == -2
225 // rnd_halfinttoeven( 2.5) == 2
226 // rnd_halfinttoeven( 3.5) == 4
227 //
228 // We assume that the rounding mode is not changed from the default
229 // one (or at least that it is always restored to the default one).
230 inline int rnd_halfinttoeven(float x)
231 {
232 # if defined(VNL_CHECK_FPU_ROUNDING_MODE) && defined(__GNUC__)
233  assert(fegetround()==FE_TONEAREST);
234 # endif
235  return _mm_cvtss_si32(_mm_set_ss(x));
236 }
237 
238 inline int rnd_halfinttoeven(double x)
239 {
240 # if defined(VNL_CHECK_FPU_ROUNDING_MODE) && defined(__GNUC__)
241  assert(fegetround()==FE_TONEAREST);
242 # endif
243  return _mm_cvtsd_si32(_mm_set_sd(x));
244 }
245 
246 #elif GCC_USE_FAST_IMPL // Fast gcc asm implementation
247 
248 inline int rnd_halfinttoeven(float x)
249 {
250 # ifdef VNL_CHECK_FPU_ROUNDING_MODE
251  assert(fegetround()==FE_TONEAREST);
252 # endif
253  int r;
254  __asm__ __volatile__ ("fistpl %0" : "=m"(r) : "t"(x) : "st");
255  return r;
256 }
257 
258 inline int rnd_halfinttoeven(double x)
259 {
260 # ifdef VNL_CHECK_FPU_ROUNDING_MODE
261  assert(fegetround()==FE_TONEAREST);
262 # endif
263  int r;
264  __asm__ __volatile__ ("fistpl %0" : "=m"(r) : "t"(x) : "st");
265  return r;
266 }
267 
268 #elif VC_USE_FAST_IMPL // Fast msvc asm implementation
269 
270 inline int rnd_halfinttoeven(float x)
271 {
272  int r;
273  __asm {
274  fld x
275  fistp r
276  }
277  return r;
278 }
279 
280 inline int rnd_halfinttoeven(double x)
281 {
282  int r;
283  __asm {
284  fld x
285  fistp r
286  }
287  return r;
288 }
289 
290 #else // Vanilla implementation
291 
292 inline int rnd_halfinttoeven(float x)
293 {
294  if (x>=0.f)
295  {
296  x+=0.5f;
297  const int r = static_cast<int>(x);
298  if ( x != static_cast<float>(r) ) return r;
299  return 2*(r/2);
300  }
301  else
302  {
303  x-=0.5f;
304  const int r = static_cast<int>(x);
305  if ( x != static_cast<float>(r) ) return r;
306  return 2*(r/2);
307  }
308 }
309 
310 inline int rnd_halfinttoeven(double x)
311 {
312  if (x>=0.)
313  {
314  x+=0.5;
315  const int r = static_cast<int>(x);
316  if ( x != static_cast<double>(r) ) return r;
317  return 2*(r/2);
318  }
319  else
320  {
321  x-=0.5;
322  const int r = static_cast<int>(x);
323  if ( x != static_cast<double>(r) ) return r;
324  return 2*(r/2);
325  }
326 }
327 
328 #endif
329 
330 
331 #if USE_SSE2_IMPL || GCC_USE_FAST_IMPL || VC_USE_FAST_IMPL
332 
333 // rnd_halfintup -- round towards nearest integer
334 // halfway cases are rounded upward, e.g.
335 // rnd_halfintup( 1.5) == 2
336 // rnd_halfintup(-1.5) == -1
337 // rnd_halfintup( 2.5) == 3
338 //
339 // Be careful: argument absolute value must be less than INT_MAX/2
340 // for rnd_halfintup to be guaranteed to work.
341 // We also assume that the rounding mode is not changed from the default
342 // one (or at least that it is always restored to the default one).
343 
344 inline int rnd_halfintup(float x) { return rnd_halfinttoeven(2*x+0.5f)>>1; }
345 inline int rnd_halfintup(double x) { return rnd_halfinttoeven(2*x+0.5)>>1; }
346 
347 #else // Vanilla implementation
348 
349 inline int rnd_halfintup(float x)
350 {
351  x+=0.5f;
352  return static_cast<int>(x>=0.f?x:(x==static_cast<int>(x)?x:x-1.f));
353 }
354 
355 inline int rnd_halfintup(double x)
356 {
357  x+=0.5;
358  return static_cast<int>(x>=0.?x:(x==static_cast<int>(x)?x:x-1.));
359 }
360 
361 #endif
362 
363 #if USE_SSE2_IMPL || GCC_USE_FAST_IMPL || VC_USE_FAST_IMPL
364 // rnd -- round towards nearest integer
365 // halfway cases such as 0.5 may be rounded either up or down
366 // so as to maximize the efficiency, e.g.
367 // rnd_halfinttoeven( 1.5) == 1 or 2
368 // rnd_halfinttoeven(-1.5) == -2 or -1
369 // rnd_halfinttoeven( 2.5) == 2 or 3
370 // rnd_halfinttoeven( 3.5) == 3 or 4
371 //
372 // We assume that the rounding mode is not changed from the default
373 // one (or at least that it is always restored to the default one).
374 inline int rnd(float x) { return rnd_halfinttoeven(x); }
375 inline int rnd(double x) { return rnd_halfinttoeven(x); }
376 
377 #else // Vanilla implementation
378 
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); }
381 
382 #endif
383 
384 #if USE_SSE2_IMPL // Fast sse2 implementation
385 // floor -- round towards minus infinity
386 //
387 // Be careful: argument absolute value must be less than INT_MAX/2
388 // for floor to be guaranteed to work.
389 // We also assume that the rounding mode is not changed from the default
390 // one (or at least that it is always restored to the default one).
391 
392 inline int floor(float x)
393 {
394 # if defined(VNL_CHECK_FPU_ROUNDING_MODE) && defined(__GNUC__)
395  assert(fegetround()==FE_TONEAREST);
396 # endif
397  return _mm_cvtss_si32(_mm_set_ss(2*x-.5f))>>1;
398 }
399 
400 inline int floor(double x)
401 {
402 # if defined(VNL_CHECK_FPU_ROUNDING_MODE) && defined(__GNUC__)
403  assert(fegetround()==FE_TONEAREST);
404 # endif
405  return _mm_cvtsd_si32(_mm_set_sd(2*x-.5))>>1;
406 }
407 
408 #elif GCC_USE_FAST_IMPL // Fast gcc asm implementation
409 
410 inline int floor(float x)
411 {
412 # ifdef VNL_CHECK_FPU_ROUNDING_MODE
413  assert(fegetround()==FE_TONEAREST);
414 # endif
415  int r;
416  x = 2*x-.5f;
417  __asm__ __volatile__ ("fistpl %0" : "=m"(r) : "t"(x) : "st");
418  return r>>1;
419 }
420 
421 inline int floor(double x)
422 {
423 # ifdef VNL_CHECK_FPU_ROUNDING_MODE
424  assert(fegetround()==FE_TONEAREST);
425 # endif
426  int r;
427  x = 2*x-.5;
428  __asm__ __volatile__ ("fistpl %0" : "=m"(r) : "t"(x) : "st");
429  return r>>1;
430 }
431 
432 #elif VC_USE_FAST_IMPL // Fast msvc asm implementation
433 
434 inline int floor(float x)
435 {
436  int r;
437  x = 2*x-.5f;
438  __asm {
439  fld x
440  fistp r
441  }
442  return r>>1;
443 }
444 
445 inline int floor(double x)
446 {
447  int r;
448  x = 2*x-.5;
449  __asm {
450  fld x
451  fistp r
452  }
453  return r>>1;
454 }
455 
456 #else // Vanilla implementation
457 
458 inline int floor(float x)
459 {
460  return static_cast<int>(x>=0.f?x:(x==static_cast<int>(x)?x:x-1.f));
461 }
462 
463 inline int floor(double x)
464 {
465  return static_cast<int>(x>=0.0?x:(x==static_cast<int>(x)?x:x-1.0));
466 }
467 
468 #endif
469 
470 
471 #if USE_SSE2_IMPL // Fast sse2 implementation
472 // ceil -- round towards plus infinity
473 //
474 // Be careful: argument absolute value must be less than INT_MAX/2
475 // for ceil to be guaranteed to work.
476 // We also assume that the rounding mode is not changed from the default
477 // one (or at least that it is always restored to the default one).
478 
479 inline int ceil(float x)
480 {
481 # if defined(VNL_CHECK_FPU_ROUNDING_MODE) && defined(__GNUC__)
482  assert(fegetround()==FE_TONEAREST);
483 # endif
484  return -(_mm_cvtss_si32(_mm_set_ss(-.5f-2*x))>>1);
485 }
486 
487 inline int ceil(double x)
488 {
489 # if defined(VNL_CHECK_FPU_ROUNDING_MODE) && defined(__GNUC__)
490  assert(fegetround()==FE_TONEAREST);
491 # endif
492  return -(_mm_cvtsd_si32(_mm_set_sd(-.5-2*x))>>1);
493 }
494 
495 #elif GCC_USE_FAST_IMPL // Fast gcc asm implementation
496 
497 inline int ceil(float x)
498 {
499 # ifdef VNL_CHECK_FPU_ROUNDING_MODE
500  assert(fegetround()==FE_TONEAREST);
501 # endif
502  int r;
503  x = -.5f-2*x;
504  __asm__ __volatile__ ("fistpl %0" : "=m"(r) : "t"(x) : "st");
505  return -(r>>1);
506 }
507 
508 inline int ceil(double x)
509 {
510 # ifdef VNL_CHECK_FPU_ROUNDING_MODE
511  assert(fegetround()==FE_TONEAREST);
512 # endif
513  int r;
514  x = -.5-2*x;
515  __asm__ __volatile__ ("fistpl %0" : "=m"(r) : "t"(x) : "st");
516  return -(r>>1);
517 }
518 
519 #elif VC_USE_FAST_IMPL // Fast msvc asm implementation
520 
521 inline int ceil(float x)
522 {
523  int r;
524  x = -.5f-2*x;
525  __asm {
526  fld x
527  fistp r
528  }
529  return -(r>>1);
530 }
531 
532 inline int ceil(double x)
533 {
534  int r;
535  x = -.5-2*x;
536  __asm {
537  fld x
538  fistp r
539  }
540  return -(r>>1);
541 }
542 
543 #else // Vanilla implementation
544 
545 inline int ceil(float x)
546 {
547  return static_cast<int>(x<0.f?x:(x==static_cast<int>(x)?x:x+1.f));
548 }
549 
550 inline int ceil(double x)
551 {
552  return static_cast<int>(x<0.0?x:(x==static_cast<int>(x)?x:x+1.0));
553 }
554 
555 #endif
556 
557 // abs
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; }
568 //long long - target type will have width of at least 64 bits. (since C++11)
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; }
571 
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; }
575 
576 // sqr (square)
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; }
582 //long long - target type will have width of at least 64 bits. (since C++11)
583 inline long long sqr(long long x) { return x*x; }
584 inline unsigned long long sqr(unsigned long long x) { return x*x; }
585 
586 inline float sqr(float x) { return x*x; }
587 inline double sqr(double x) { return x*x; }
588 
589 // cube
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; }
595 //long long - target type will have width of at least 64 bits. (since C++11)
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; }
598 
599 inline float cube(float x) { return x*x*x; }
600 inline double cube(double x) { return x*x*x; }
601 
602 // sgn (sign in -1, 0, +1)
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; }
605 //long long - target type will have width of at least 64 bits. (since C++11)
606 inline int sgn(long long x) { return x?((x>0)?1:-1):0; }
607 
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; }
610 
611 // sgn0 (sign in -1, +1 only, useful for reals)
612 inline int sgn0(int x) { return (x>=0)?1:-1; }
613 inline int sgn0(long x) { return (x>=0)?1:-1; }
614 //long long - target type will have width of at least 64 bits. (since C++11)
615 inline int sgn0(long long x) { return (x>=0)?1:-1; }
616 
617 inline int sgn0(float x) { return (x>=0)?1:-1; }
618 inline int sgn0(double x) { return (x>=0)?1:-1; }
619 
620 // squared_magnitude
621 inline unsigned int squared_magnitude(char x) { return int(x)*int(x); }
622 inline unsigned int squared_magnitude(unsigned char x) { return int(x)*int(x); }
623 inline unsigned int squared_magnitude(int x) { return x*x; }
624 inline unsigned int squared_magnitude(unsigned int x) { return x*x; }
625 inline unsigned long squared_magnitude(long x) { return x*x; }
626 inline unsigned long squared_magnitude(unsigned long x) { return x*x; }
627 //long long - target type will have width of at least 64 bits. (since C++11)
628 inline unsigned long long squared_magnitude(long long x) { return x*x; }
629 inline unsigned long long squared_magnitude(unsigned long long x) { return x*x; }
630 
631 inline float squared_magnitude(float x) { return x*x; }
632 inline double squared_magnitude(double x) { return x*x; }
633 inline long double squared_magnitude(long double x) { return x*x; }
634 
635 
636 // truncated remainder
637 inline int remainder_truncated(int x, int y) { return x % y; }
638 inline unsigned int remainder_truncated(unsigned int x, unsigned int y) { return x % y; }
639 inline long remainder_truncated(long x, long y) { return x % y; }
640 inline unsigned long remainder_truncated(unsigned long x, unsigned long y) { return x % y; }
641 inline long long remainder_truncated(long long x, long long y) { return x % y; }
642 inline unsigned long long remainder_truncated(unsigned long long x, unsigned long long y) { return x % y; }
643 inline float remainder_truncated(float x, float y) { return fmod(x,y); }
644 inline double remainder_truncated(double x, double y) { return fmod(x,y); }
645 inline long double remainder_truncated(long double x, long double y) { return fmod(x,y); }
646 
647 // floored remainder
648 inline int remainder_floored(int x, int y) { return ((x % y) + y) % y; }
649 inline unsigned int remainder_floored(unsigned int x, unsigned int y) { return x % y; }
650 inline long remainder_floored(long x, long y) { return ((x % y) + y) % y; }
651 inline unsigned long remainder_floored(unsigned long x, unsigned long y) { return x % y; }
652 inline long long remainder_floored(long long x, long long y) { return ((x % y) + y) % y; }
653 inline unsigned long long remainder_floored(unsigned long long x, unsigned long long y) { return x % y; }
654 inline float remainder_floored(float x, float y) { return fmod(fmod(x,y)+y,y); }
655 inline double remainder_floored(double x, double y) { return fmod(fmod(x,y)+y,y); }
656 inline long double remainder_floored(long double x, long double y) { return fmod(fmod(x,y)+y,y); }
657 
658 } // end of namespace vnl_math
659 #endif // vnl_math_h_
double angle_0_to_2pi(double angle)
Convert an angle to [0, 2Pi) range.
Definition: vnl_math.cxx:29
int ceil(float x)
Definition: vnl_math.h:545
int rnd(float x)
Definition: vnl_math.h:379
double angle_minuspi_to_pi(double angle)
Convert an angle to [-Pi, Pi) range.
Definition: vnl_math.cxx:42
int remainder_floored(int x, int y)
Definition: vnl_math.h:648
bool isnan(TArg arg)
Definition: vnl_math.h:201
int remainder_truncated(int x, int y)
Definition: vnl_math.h:637
real numerical constants.
Definition: vnl_bignum.h:430
vnl_bignum squared_magnitude(vnl_bignum const &x)
Definition: vnl_bignum.h:433
VNL_EXPORT double angle(v const &, v const &)
bool isnan(vnl_bignum const &)
Definition: vnl_bignum.h:435
int sgn0(vnl_decnum x)
Definition: vnl_decnum.h:415
bool isfinite(vnl_bignum const &x)
Definition: vnl_bignum.h:436
VNL_EXPORT T vnl_huge_val(T)
Type-accessible infinities for use in templates.
vnl_decnum cube(vnl_decnum const &x)
Definition: vnl_decnum.h:408
vnl_decnum max(vnl_decnum const &x, vnl_decnum const &y)
Definition: vnl_decnum.h:412
int rnd_halfinttoeven(float x)
Definition: vnl_math.h:292
vnl_bignum abs(vnl_bignum const &x)
Definition: vnl_bignum.h:432
bool isinf(TArg arg)
Definition: vnl_math.h:199
vnl_decnum min(vnl_decnum const &x, vnl_decnum const &y)
Definition: vnl_decnum.h:413
int floor(float x)
Definition: vnl_math.h:458
int sgn(vnl_decnum x)
Definition: vnl_decnum.h:414
vnl_bignum sqr(vnl_bignum const &x)
Definition: vnl_bignum.h:434
bool isnormal(TArg arg)
Definition: vnl_math.h:205
bool isfinite(TArg arg)
Definition: vnl_math.h:203
int rnd_halfintup(float x)
Definition: vnl_math.h:349