HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Math.h
Go to the documentation of this file.
1 // Copyright Contributors to the OpenVDB Project
2 // SPDX-License-Identifier: MPL-2.0
3 //
4 /// @file Math.h
5 /// @brief General-purpose arithmetic and comparison routines, most of which
6 /// accept arbitrary value types (or at least arbitrary numeric value types)
7 
8 #ifndef OPENVDB_MATH_HAS_BEEN_INCLUDED
9 #define OPENVDB_MATH_HAS_BEEN_INCLUDED
10 
11 #include <openvdb/Platform.h>
12 #include <openvdb/version.h>
13 #include <hboost/numeric/conversion/conversion_traits.hpp>
14 #include <algorithm> // for std::max()
15 #include <cassert>
16 #include <cmath> // for std::ceil(), std::fabs(), std::pow(), std::sqrt(), etc.
17 #include <cstdlib> // for abs(int)
18 #include <random>
19 #include <string>
20 #include <type_traits> // for std::is_arithmetic
21 
22 
23 // Compile pragmas
24 
25 // Intel(r) compiler fires remark #1572: floating-point equality and inequality
26 // comparisons are unrealiable when == or != is used with floating point operands.
27 #if defined(__INTEL_COMPILER)
28  #define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN \
29  _Pragma("warning (push)") \
30  _Pragma("warning (disable:1572)")
31  #define OPENVDB_NO_FP_EQUALITY_WARNING_END \
32  _Pragma("warning (pop)")
33 #elif defined(__clang__)
34  #define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN \
35  PRAGMA(clang diagnostic push) \
36  PRAGMA(clang diagnostic ignored "-Wfloat-equal")
37  #define OPENVDB_NO_FP_EQUALITY_WARNING_END \
38  PRAGMA(clang diagnostic pop)
39 #else
40  // For GCC, #pragma GCC diagnostic ignored "-Wfloat-equal"
41  // isn't working until gcc 4.2+,
42  // Trying
43  // #pragma GCC system_header
44  // creates other problems, most notably "warning: will never be executed"
45  // in from templates, unsure of how to work around.
46  // If necessary, could use integer based comparisons for equality
47  #define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN
48  #define OPENVDB_NO_FP_EQUALITY_WARNING_END
49 #endif
50 
51 namespace openvdb {
53 namespace OPENVDB_VERSION_NAME {
54 
55 /// @brief Return the value of type T that corresponds to zero.
56 /// @note A zeroVal<T>() specialization must be defined for each @c ValueType T
57 /// that cannot be constructed using the form @c T(0). For example, @c std::string(0)
58 /// treats 0 as @c nullptr and throws a @c std::logic_error.
59 template<typename T> inline T zeroVal() { return T(0); }
60 /// Return the @c std::string value that corresponds to zero.
61 template<> inline std::string zeroVal<std::string>() { return ""; }
62 /// Return the @c bool value that corresponds to zero.
63 template<> inline bool zeroVal<bool>() { return false; }
64 
65 /// @todo These won't be needed if we eliminate StringGrids.
66 //@{
67 /// @brief Needed to support the <tt>(zeroVal<ValueType>() + val)</tt> idiom
68 /// when @c ValueType is @c std::string
69 inline std::string operator+(const std::string& s, bool) { return s; }
70 inline std::string operator+(const std::string& s, int) { return s; }
71 inline std::string operator+(const std::string& s, float) { return s; }
72 inline std::string operator+(const std::string& s, double) { return s; }
73 //@}
74 
75 
76 namespace math {
77 
78 
79 /// @brief Pi constant taken from Boost to match old behaviour
80 /// @note Available in C++20
81 template <typename T> inline constexpr T pi() { return 3.141592653589793238462643383279502884e+00; }
82 template <> inline constexpr float pi() { return 3.141592653589793238462643383279502884e+00F; }
83 template <> inline constexpr double pi() { return 3.141592653589793238462643383279502884e+00; }
84 template <> inline constexpr long double pi() { return 3.141592653589793238462643383279502884e+00L; }
85 
86 
87 /// @brief Return the unary negation of the given value.
88 /// @note A negative<T>() specialization must be defined for each ValueType T
89 /// for which unary negation is not defined.
90 template<typename T> inline T negative(const T& val)
91 {
92 // disable unary minus on unsigned warning
93 #if defined(_MSC_VER)
94 #pragma warning(push)
95 #pragma warning(disable:4146)
96 #endif
97  return T(-val);
98 #if defined(_MSC_VER)
99 #pragma warning(pop)
100 #endif
101 }
102 /// Return the negation of the given boolean.
103 template<> inline bool negative(const bool& val) { return !val; }
104 /// Return the "negation" of the given string.
105 template<> inline std::string negative(const std::string& val) { return val; }
106 
107 
108 //@{
109 /// Tolerance for floating-point comparison
110 template<typename T> struct Tolerance { static T value() { return zeroVal<T>(); } };
111 template<> struct Tolerance<float> { static float value() { return 1e-8f; } };
112 template<> struct Tolerance<double> { static double value() { return 1e-15; } };
113 //@}
114 
115 //@{
116 /// Delta for small floating-point offsets
117 template<typename T> struct Delta { static T value() { return zeroVal<T>(); } };
118 template<> struct Delta<float> { static float value() { return 1e-5f; } };
119 template<> struct Delta<double> { static double value() { return 1e-9; } };
120 //@}
121 
122 
123 // ==========> Random Values <==================
124 
125 /// @brief Simple generator of random numbers over the range [0, 1)
126 /// @details Thread-safe as long as each thread has its own Rand01 instance
127 template<typename FloatType = double, typename EngineType = std::mt19937>
128 class Rand01
129 {
130 private:
131  EngineType mEngine;
132  std::uniform_real_distribution<FloatType> mRand;
133 
134 public:
136 
137  /// @brief Initialize the generator.
138  /// @param engine random number generator
139  Rand01(const EngineType& engine): mEngine(engine) {}
140 
141  /// @brief Initialize the generator.
142  /// @param seed seed value for the random number generator
143  Rand01(unsigned int seed): mEngine(static_cast<typename EngineType::result_type>(seed)) {}
144 
145  /// Set the seed value for the random number generator
146  void setSeed(unsigned int seed)
147  {
148  mEngine.seed(static_cast<typename EngineType::result_type>(seed));
149  }
150 
151  /// Return a const reference to the random number generator.
152  const EngineType& engine() const { return mEngine; }
153 
154  /// Return a uniformly distributed random number in the range [0, 1).
155  FloatType operator()() { return mRand(mEngine); }
156 };
157 
159 
160 
161 /// @brief Simple random integer generator
162 /// @details Thread-safe as long as each thread has its own RandInt instance
163 template<typename IntType = int, typename EngineType = std::mt19937>
164 class RandInt
165 {
166 private:
167  using Distr = std::uniform_int_distribution<IntType>;
168  EngineType mEngine;
169  Distr mRand;
170 
171 public:
172  /// @brief Initialize the generator.
173  /// @param engine random number generator
174  /// @param imin,imax generate integers that are uniformly distributed over [imin, imax]
175  RandInt(const EngineType& engine, IntType imin, IntType imax):
176  mEngine(engine),
177  mRand(std::min(imin, imax), std::max(imin, imax))
178  {}
179 
180  /// @brief Initialize the generator.
181  /// @param seed seed value for the random number generator
182  /// @param imin,imax generate integers that are uniformly distributed over [imin, imax]
183  RandInt(unsigned int seed, IntType imin, IntType imax):
184  mEngine(static_cast<typename EngineType::result_type>(seed)),
185  mRand(std::min(imin, imax), std::max(imin, imax))
186  {}
187 
188  /// Change the range over which integers are distributed to [imin, imax].
189  void setRange(IntType imin, IntType imax)
190  {
191  mRand = Distr(std::min(imin, imax), std::max(imin, imax));
192  }
193 
194  /// Set the seed value for the random number generator
195  void setSeed(unsigned int seed)
196  {
197  mEngine.seed(static_cast<typename EngineType::result_type>(seed));
198  }
199 
200  /// Return a const reference to the random number generator.
201  const EngineType& engine() const { return mEngine; }
202 
203  /// Return a randomly-generated integer in the current range.
204  IntType operator()() { return mRand(mEngine); }
205 
206  /// @brief Return a randomly-generated integer in the new range [imin, imax],
207  /// without changing the current range.
208  IntType operator()(IntType imin, IntType imax)
209  {
210  const IntType lo = std::min(imin, imax), hi = std::max(imin, imax);
211  return mRand(mEngine, typename Distr::param_type(lo, hi));
212  }
213 };
214 
216 
217 
218 // ==========> Clamp <==================
219 
220 /// Return @a x clamped to [@a min, @a max]
221 template<typename Type>
222 inline Type
224 {
225  assert( !(min>max) );
226  return x > min ? x < max ? x : max : min;
227 }
228 
229 
230 /// Return @a x clamped to [0, 1]
231 template<typename Type>
232 inline Type
233 Clamp01(Type x) { return x > Type(0) ? x < Type(1) ? x : Type(1) : Type(0); }
234 
235 
236 /// Return @c true if @a x is outside [0,1]
237 template<typename Type>
238 inline bool
240 {
241  if (x >= Type(0) && x <= Type(1)) return false;
242  x = x < Type(0) ? Type(0) : Type(1);
243  return true;
244 }
245 
246 /// @brief Return 0 if @a x < @a 0, 1 if @a x > 1 or else (3 &minus; 2 @a x) @a x&sup2;.
247 template<typename Type>
248 inline Type
250 {
251  return x > 0 ? x < 1 ? (3-2*x)*x*x : Type(1) : Type(0);
252 }
253 
254 /// @brief Return 0 if @a x < @a min, 1 if @a x > @a max or else (3 &minus; 2 @a t) @a t&sup2;,
255 /// where @a t = (@a x &minus; @a min)/(@a max &minus; @a min).
256 template<typename Type>
257 inline Type
259 {
260  assert(min < max);
261  return SmoothUnitStep((x-min)/(max-min));
262 }
263 
264 
265 // ==========> Absolute Value <==================
266 
267 
268 //@{
269 /// Return the absolute value of the given quantity.
270 inline int32_t Abs(int32_t i) { return abs(i); }
271 inline int64_t Abs(int64_t i)
272 {
273 #ifdef _MSC_VER
274  return (i < int64_t(0) ? -i : i);
275 #else
276  return labs(i);
277 #endif
278 }
279 inline float Abs(float x) { return std::fabs(x); }
280 inline double Abs(double x) { return std::fabs(x); }
281 inline long double Abs(long double x) { return std::fabs(x); }
282 inline uint32_t Abs(uint32_t i) { return i; }
283 inline uint64_t Abs(uint64_t i) { return i; }
284 inline bool Abs(bool b) { return b; }
285 // On OSX size_t and uint64_t are different types
286 #if defined(__APPLE__) || defined(MACOSX)
287 inline size_t Abs(size_t i) { return i; }
288 #endif
289 //@}
290 
291 
292 ////////////////////////////////////////
293 
294 
295 // ==========> Value Comparison <==================
296 
297 
298 /// Return @c true if @a x is exactly equal to zero.
299 template<typename Type>
300 inline bool
301 isZero(const Type& x)
302 {
304  return x == zeroVal<Type>();
306 }
307 
308 
309 /// @brief Return @c true if @a x is equal to zero to within
310 /// the default floating-point comparison tolerance.
311 template<typename Type>
312 inline bool
314 {
315  const Type tolerance = Type(zeroVal<Type>() + Tolerance<Type>::value());
316  return !(x > tolerance) && !(x < -tolerance);
317 }
318 
319 /// Return @c true if @a x is equal to zero to within the given tolerance.
320 template<typename Type>
321 inline bool
322 isApproxZero(const Type& x, const Type& tolerance)
323 {
324  return !(x > tolerance) && !(x < -tolerance);
325 }
326 
327 
328 /// Return @c true if @a x is less than zero.
329 template<typename Type>
330 inline bool
331 isNegative(const Type& x) { return x < zeroVal<Type>(); }
332 
333 // Return false, since bool values are never less than zero.
334 template<> inline bool isNegative<bool>(const bool&) { return false; }
335 
336 
337 /// Return @c true if @a x is finite.
338 inline bool
339 isFinite(const float x) { return std::isfinite(x); }
340 
341 /// Return @c true if @a x is finite.
343 inline bool
344 isFinite(const Type& x) { return std::isfinite(static_cast<double>(x)); }
345 
346 
347 /// Return @c true if @a x is an infinity value (either positive infinity or negative infinity).
348 inline bool
349 isInfinite(const float x) { return std::isinf(x); }
350 
351 /// Return @c true if @a x is an infinity value (either positive infinity or negative infinity).
353 inline bool
354 isInfinite(const Type& x) { return std::isinf(static_cast<double>(x)); }
355 
356 
357 /// Return @c true if @a x is a NaN (Not-A-Number) value.
358 inline bool
359 isNan(const float x) { return std::isnan(x); }
360 
361 /// Return @c true if @a x is a NaN (Not-A-Number) value.
363 inline bool
364 isNan(const Type& x) { return std::isnan(static_cast<double>(x)); }
365 
366 
367 /// @brief Return @c true if @a a is equal to @a b to within
368 /// the default floating-point comparison tolerance.
369 template<typename Type>
370 inline bool
371 isApproxEqual(const Type& a, const Type& b)
372 {
373  const Type tolerance = Type(zeroVal<Type>() + Tolerance<Type>::value());
374  return !(Abs(a - b) > tolerance);
375 }
376 
377 
378 /// Return @c true if @a a is equal to @a b to within the given tolerance.
379 template<typename Type>
380 inline bool
381 isApproxEqual(const Type& a, const Type& b, const Type& tolerance)
382 {
383  return !(Abs(a - b) > tolerance);
384 }
385 
386 #define OPENVDB_EXACT_IS_APPROX_EQUAL(T) \
387  template<> inline bool isApproxEqual<T>(const T& a, const T& b) { return a == b; } \
388  template<> inline bool isApproxEqual<T>(const T& a, const T& b, const T&) { return a == b; } \
389  /**/
390 
393 
394 
395 /// @brief Return @c true if @a a is larger than @a b to within
396 /// the given tolerance, i.e., if @a b - @a a < @a tolerance.
397 template<typename Type>
398 inline bool
400 {
401  return (b - a < tolerance);
402 }
403 
404 
405 /// @brief Return @c true if @a a is exactly equal to @a b.
406 template<typename T0, typename T1>
407 inline bool
408 isExactlyEqual(const T0& a, const T1& b)
409 {
411  return a == b;
413 }
414 
415 
416 template<typename Type>
417 inline bool
418 isRelOrApproxEqual(const Type& a, const Type& b, const Type& absTol, const Type& relTol)
419 {
420  // First check to see if we are inside the absolute tolerance
421  // Necessary for numbers close to 0
422  if (!(Abs(a - b) > absTol)) return true;
423 
424  // Next check to see if we are inside the relative tolerance
425  // to handle large numbers that aren't within the abs tolerance
426  // but could be the closest floating point representation
427  double relError;
428  if (Abs(b) > Abs(a)) {
429  relError = Abs((a - b) / b);
430  } else {
431  relError = Abs((a - b) / a);
432  }
433  return (relError <= relTol);
434 }
435 
436 template<>
437 inline bool
438 isRelOrApproxEqual(const bool& a, const bool& b, const bool&, const bool&)
439 {
440  return (a == b);
441 }
442 
443 
444 // Avoid strict aliasing issues by using type punning
445 // http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
446 // Using "casting through a union(2)"
447 inline int32_t
448 floatToInt32(const float aFloatValue)
449 {
450  union FloatOrInt32 { float floatValue; int32_t int32Value; };
451  const FloatOrInt32* foi = reinterpret_cast<const FloatOrInt32*>(&aFloatValue);
452  return foi->int32Value;
453 }
454 
455 
456 inline int64_t
457 doubleToInt64(const double aDoubleValue)
458 {
459  union DoubleOrInt64 { double doubleValue; int64_t int64Value; };
460  const DoubleOrInt64* dol = reinterpret_cast<const DoubleOrInt64*>(&aDoubleValue);
461  return dol->int64Value;
462 }
463 
464 
465 // aUnitsInLastPlace is the allowed difference between the least significant digits
466 // of the numbers' floating point representation
467 // Please read the reference paper before trying to use isUlpsEqual
468 // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
469 inline bool
470 isUlpsEqual(const double aLeft, const double aRight, const int64_t aUnitsInLastPlace)
471 {
472  int64_t longLeft = doubleToInt64(aLeft);
473  // Because of 2's complement, must restore lexicographical order
474  if (longLeft < 0) {
475  longLeft = INT64_C(0x8000000000000000) - longLeft;
476  }
477 
478  int64_t longRight = doubleToInt64(aRight);
479  // Because of 2's complement, must restore lexicographical order
480  if (longRight < 0) {
481  longRight = INT64_C(0x8000000000000000) - longRight;
482  }
483 
484  int64_t difference = labs(longLeft - longRight);
485  return (difference <= aUnitsInLastPlace);
486 }
487 
488 inline bool
489 isUlpsEqual(const float aLeft, const float aRight, const int32_t aUnitsInLastPlace)
490 {
491  int32_t intLeft = floatToInt32(aLeft);
492  // Because of 2's complement, must restore lexicographical order
493  if (intLeft < 0) {
494  intLeft = 0x80000000 - intLeft;
495  }
496 
497  int32_t intRight = floatToInt32(aRight);
498  // Because of 2's complement, must restore lexicographical order
499  if (intRight < 0) {
500  intRight = 0x80000000 - intRight;
501  }
502 
503  int32_t difference = abs(intLeft - intRight);
504  return (difference <= aUnitsInLastPlace);
505 }
506 
507 
508 ////////////////////////////////////////
509 
510 
511 // ==========> Pow <==================
512 
513 /// Return @a x<sup>2</sup>.
514 template<typename Type>
515 inline Type Pow2(Type x) { return x*x; }
516 
517 /// Return @a x<sup>3</sup>.
518 template<typename Type>
519 inline Type Pow3(Type x) { return x*x*x; }
520 
521 /// Return @a x<sup>4</sup>.
522 template<typename Type>
523 inline Type Pow4(Type x) { return Pow2(Pow2(x)); }
524 
525 /// Return @a x<sup>@a n</sup>.
526 template<typename Type>
527 Type
528 Pow(Type x, int n)
529 {
530  Type ans = 1;
531  if (n < 0) {
532  n = -n;
533  x = Type(1)/x;
534  }
535  while (n--) ans *= x;
536  return ans;
537 }
538 
539 //@{
540 /// Return @a b<sup>@a e</sup>.
541 inline float
542 Pow(float b, float e)
543 {
544  assert( b >= 0.0f && "Pow(float,float): base is negative" );
545  return powf(b,e);
546 }
547 
548 inline double
549 Pow(double b, double e)
550 {
551  assert( b >= 0.0 && "Pow(double,double): base is negative" );
552  return std::pow(b,e);
553 }
554 //@}
555 
556 
557 // ==========> Max <==================
558 
559 /// Return the maximum of two values
560 template<typename Type>
561 inline const Type&
562 Max(const Type& a, const Type& b)
563 {
564  return std::max(a,b);
565 }
566 
567 /// Return the maximum of three values
568 template<typename Type>
569 inline const Type&
570 Max(const Type& a, const Type& b, const Type& c)
571 {
572  return std::max(std::max(a,b), c);
573 }
574 
575 /// Return the maximum of four values
576 template<typename Type>
577 inline const Type&
578 Max(const Type& a, const Type& b, const Type& c, const Type& d)
579 {
580  return std::max(std::max(a,b), std::max(c,d));
581 }
582 
583 /// Return the maximum of five values
584 template<typename Type>
585 inline const Type&
586 Max(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e)
587 {
588  return std::max(std::max(a,b), Max(c,d,e));
589 }
590 
591 /// Return the maximum of six values
592 template<typename Type>
593 inline const Type&
594 Max(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e, const Type& f)
595 {
596  return std::max(Max(a,b,c), Max(d,e,f));
597 }
598 
599 /// Return the maximum of seven values
600 template<typename Type>
601 inline const Type&
602 Max(const Type& a, const Type& b, const Type& c, const Type& d,
603  const Type& e, const Type& f, const Type& g)
604 {
605  return std::max(Max(a,b,c,d), Max(e,f,g));
606 }
607 
608 /// Return the maximum of eight values
609 template<typename Type>
610 inline const Type&
611 Max(const Type& a, const Type& b, const Type& c, const Type& d,
612  const Type& e, const Type& f, const Type& g, const Type& h)
613 {
614  return std::max(Max(a,b,c,d), Max(e,f,g,h));
615 }
616 
617 
618 // ==========> Min <==================
619 
620 /// Return the minimum of two values
621 template<typename Type>
622 inline const Type&
623 Min(const Type& a, const Type& b) { return std::min(a, b); }
624 
625 /// Return the minimum of three values
626 template<typename Type>
627 inline const Type&
628 Min(const Type& a, const Type& b, const Type& c) { return std::min(std::min(a, b), c); }
629 
630 /// Return the minimum of four values
631 template<typename Type>
632 inline const Type&
633 Min(const Type& a, const Type& b, const Type& c, const Type& d)
634 {
635  return std::min(std::min(a, b), std::min(c, d));
636 }
637 
638 /// Return the minimum of five values
639 template<typename Type>
640 inline const Type&
641 Min(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e)
642 {
643  return std::min(std::min(a,b), Min(c,d,e));
644 }
645 
646 /// Return the minimum of six values
647 template<typename Type>
648 inline const Type&
649 Min(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e, const Type& f)
650 {
651  return std::min(Min(a,b,c), Min(d,e,f));
652 }
653 
654 /// Return the minimum of seven values
655 template<typename Type>
656 inline const Type&
657 Min(const Type& a, const Type& b, const Type& c, const Type& d,
658  const Type& e, const Type& f, const Type& g)
659 {
660  return std::min(Min(a,b,c,d), Min(e,f,g));
661 }
662 
663 /// Return the minimum of eight values
664 template<typename Type>
665 inline const Type&
666 Min(const Type& a, const Type& b, const Type& c, const Type& d,
667  const Type& e, const Type& f, const Type& g, const Type& h)
668 {
669  return std::min(Min(a,b,c,d), Min(e,f,g,h));
670 }
671 
672 
673 // ============> Exp <==================
674 
675 /// Return @a e<sup>@a x</sup>.
676 template<typename Type>
677 inline Type Exp(const Type& x) { return std::exp(x); }
678 
679 // ============> Sin <==================
680 
681 //@{
682 /// Return sin @a x.
683 inline float Sin(const float& x) { return std::sin(x); }
684 
685 inline double Sin(const double& x) { return std::sin(x); }
686 //@}
687 
688 // ============> Cos <==================
689 
690 //@{
691 /// Return cos @a x.
692 inline float Cos(const float& x) { return std::cos(x); }
693 
694 inline double Cos(const double& x) { return std::cos(x); }
695 //@}
696 
697 
698 ////////////////////////////////////////
699 
700 
701 /// Return the sign of the given value as an integer (either -1, 0 or 1).
702 template <typename Type>
703 inline int Sign(const Type &x) { return (zeroVal<Type>() < x) - (x < zeroVal<Type>()); }
704 
705 
706 /// @brief Return @c true if @a a and @a b have different signs.
707 /// @note Zero is considered a positive number.
708 template <typename Type>
709 inline bool
710 SignChange(const Type& a, const Type& b)
711 {
712  return ( (a<zeroVal<Type>()) ^ (b<zeroVal<Type>()) );
713 }
714 
715 
716 /// @brief Return @c true if the interval [@a a, @a b] includes zero,
717 /// i.e., if either @a a or @a b is zero or if they have different signs.
718 template <typename Type>
719 inline bool
720 ZeroCrossing(const Type& a, const Type& b)
721 {
722  return a * b <= zeroVal<Type>();
723 }
724 
725 
726 //@{
727 /// Return the square root of a floating-point value.
728 inline float Sqrt(float x) { return std::sqrt(x); }
729 inline double Sqrt(double x) { return std::sqrt(x); }
730 inline long double Sqrt(long double x) { return std::sqrt(x); }
731 //@}
732 
733 
734 //@{
735 /// Return the cube root of a floating-point value.
736 inline float Cbrt(float x) { return std::cbrt(x); }
737 inline double Cbrt(double x) { return std::cbrt(x); }
738 inline long double Cbrt(long double x) { return std::cbrt(x); }
739 //@}
740 
741 
742 //@{
743 /// Return the remainder of @a x / @a y.
744 inline int Mod(int x, int y) { return (x % y); }
745 inline float Mod(float x, float y) { return std::fmod(x, y); }
746 inline double Mod(double x, double y) { return std::fmod(x, y); }
747 inline long double Mod(long double x, long double y) { return std::fmod(x, y); }
748 template<typename Type> inline Type Remainder(Type x, Type y) { return Mod(x, y); }
749 //@}
750 
751 
752 //@{
753 /// Return @a x rounded up to the nearest integer.
754 inline float RoundUp(float x) { return std::ceil(x); }
755 inline double RoundUp(double x) { return std::ceil(x); }
756 inline long double RoundUp(long double x) { return std::ceil(x); }
757 //@}
758 /// Return @a x rounded up to the nearest multiple of @a base.
759 template<typename Type>
760 inline Type
762 {
763  Type remainder = Remainder(x, base);
764  return remainder ? x-remainder+base : x;
765 }
766 
767 
768 //@{
769 /// Return @a x rounded down to the nearest integer.
770 inline float RoundDown(float x) { return std::floor(x); }
771 inline double RoundDown(double x) { return std::floor(x); }
772 inline long double RoundDown(long double x) { return std::floor(x); }
773 //@}
774 /// Return @a x rounded down to the nearest multiple of @a base.
775 template<typename Type>
776 inline Type
778 {
779  Type remainder = Remainder(x, base);
780  return remainder ? x-remainder : x;
781 }
782 
783 
784 //@{
785 /// Return @a x rounded to the nearest integer.
786 inline float Round(float x) { return RoundDown(x + 0.5f); }
787 inline double Round(double x) { return RoundDown(x + 0.5); }
788 inline long double Round(long double x) { return RoundDown(x + 0.5l); }
789 //@}
790 
791 
792 /// Return the euclidean remainder of @a x.
793 /// Note unlike % operator this will always return a positive result
794 template<typename Type>
795 inline Type
796 EuclideanRemainder(Type x) { return x - RoundDown(x); }
797 
798 
799 /// Return the integer part of @a x.
800 template<typename Type>
801 inline Type
803 {
804  return (x > 0 ? RoundDown(x) : RoundUp(x));
805 }
806 
807 /// Return the fractional part of @a x.
808 template<typename Type>
809 inline Type
810 FractionalPart(Type x) { return Mod(x,Type(1)); }
811 
812 
813 //@{
814 /// Return the floor of @a x.
815 inline int Floor(float x) { return int(RoundDown(x)); }
816 inline int Floor(double x) { return int(RoundDown(x)); }
817 inline int Floor(long double x) { return int(RoundDown(x)); }
818 //@}
819 
820 
821 //@{
822 /// Return the ceiling of @a x.
823 inline int Ceil(float x) { return int(RoundUp(x)); }
824 inline int Ceil(double x) { return int(RoundUp(x)); }
825 inline int Ceil(long double x) { return int(RoundUp(x)); }
826 //@}
827 
828 
829 /// Return @a x if it is greater or equal in magnitude than @a delta. Otherwise, return zero.
830 template<typename Type>
831 inline Type Chop(Type x, Type delta) { return (Abs(x) < delta ? zeroVal<Type>() : x); }
832 
833 
834 /// Return @a x truncated to the given number of decimal digits.
835 template<typename Type>
836 inline Type
837 Truncate(Type x, unsigned int digits)
838 {
839  Type tenth = Pow(10,digits);
840  return RoundDown(x*tenth+0.5)/tenth;
841 }
842 
843 
844 ////////////////////////////////////////
845 
846 
847 /// @brief 8-bit integer values print to std::ostreams as characters.
848 /// Cast them so that they print as integers instead.
849 template<typename T>
851  && !std::is_same<T, uint8_t>::value, const T&>::type { return val; }
852 inline int32_t PrintCast(int8_t val) { return int32_t(val); }
853 inline uint32_t PrintCast(uint8_t val) { return uint32_t(val); }
854 
855 
856 ////////////////////////////////////////
857 
858 
859 /// Return the inverse of @a x.
860 template<typename Type>
861 inline Type
863 {
864  assert(x);
865  return Type(1)/x;
866 }
867 
868 
869 enum Axis {
870  X_AXIS = 0,
871  Y_AXIS = 1,
872  Z_AXIS = 2
873 };
874 
875 // enum values are consistent with their historical mx analogs.
885 };
886 
887 
888 template <typename S, typename T>
889 struct promote {
890  using type = typename hboost::numeric::conversion_traits<S, T>::supertype;
891 };
892 
893 
894 /// @brief Return the index [0,1,2] of the smallest value in a 3D vector.
895 /// @note This methods assumes operator[] exists and avoids branching.
896 /// @details If two components of the input vector are equal and smaller than the
897 /// third component, the largest index of the two is always returned.
898 /// If all three vector components are equal the largest index, i.e. 2, is
899 /// returned. In other words the return value corresponds to the largest index
900 /// of the of the smallest vector components.
901 template<typename Vec3T>
902 size_t
903 MinIndex(const Vec3T& v)
904 {
905  static const size_t hashTable[8] = { 2, 1, 9, 1, 2, 9, 0, 0 };//9 is a dummy value
906  const size_t hashKey =
907  ((v[0] < v[1]) << 2) + ((v[0] < v[2]) << 1) + (v[1] < v[2]);// ?*4+?*2+?*1
908  return hashTable[hashKey];
909 }
910 
911 
912 /// @brief Return the index [0,1,2] of the largest value in a 3D vector.
913 /// @note This methods assumes operator[] exists and avoids branching.
914 /// @details If two components of the input vector are equal and larger than the
915 /// third component, the largest index of the two is always returned.
916 /// If all three vector components are equal the largest index, i.e. 2, is
917 /// returned. In other words the return value corresponds to the largest index
918 /// of the largest vector components.
919 template<typename Vec3T>
920 size_t
921 MaxIndex(const Vec3T& v)
922 {
923  static const size_t hashTable[8] = { 2, 1, 9, 1, 2, 9, 0, 0 };//9 is a dummy value
924  const size_t hashKey =
925  ((v[0] > v[1]) << 2) + ((v[0] > v[2]) << 1) + (v[1] > v[2]);// ?*4+?*2+?*1
926  return hashTable[hashKey];
927 }
928 
929 } // namespace math
930 } // namespace OPENVDB_VERSION_NAME
931 } // namespace openvdb
932 
933 #endif // OPENVDB_MATH_MATH_HAS_BEEN_INCLUDED
GLdouble s
Definition: glew.h:1390
void setSeed(unsigned int seed)
Set the seed value for the random number generator.
Definition: Math.h:146
vint4 max(const vint4 &a, const vint4 &b)
Definition: simd.h:4703
int32_t floatToInt32(const float aFloatValue)
Definition: Math.h:448
SYS_API double cos(double x)
Definition: SYS_FPUMath.h:69
SYS_API double fmod(double x, double y)
Definition: SYS_FPUMath.h:85
Type Inv(Type x)
Return the inverse of x.
Definition: Math.h:862
Type Truncate(Type x, unsigned int digits)
Return x truncated to the given number of decimal digits.
Definition: Math.h:837
int Ceil(float x)
Return the ceiling of x.
Definition: Math.h:823
Simple generator of random numbers over the range [0, 1)
Definition: Math.h:128
Type Pow(Type x, int n)
Return xn.
Definition: Math.h:528
Type IntegerPart(Type x)
Return the integer part of x.
Definition: Math.h:802
bool ZeroCrossing(const Type &a, const Type &b)
Return true if the interval [a, b] includes zero, i.e., if either a or b is zero or if they have diff...
Definition: Math.h:720
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:408
Type Pow2(Type x)
Return x2.
Definition: Math.h:515
T negative(const T &val)
Return the unary negation of the given value.
Definition: Math.h:90
size_t MaxIndex(const Vec3T &v)
Return the index [0,1,2] of the largest value in a 3D vector.
Definition: Math.h:921
GLuint const GLfloat * val
Definition: glew.h:2794
Type FractionalPart(Type x)
Return the fractional part of x.
Definition: Math.h:810
GLboolean GLboolean GLboolean GLboolean a
Definition: glew.h:9477
vfloat4 sqrt(const vfloat4 &a)
Definition: simd.h:7231
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:166
const EngineType & engine() const
Return a const reference to the random number generator.
Definition: Math.h:201
float Cos(const float &x)
Return cos x.
Definition: Math.h:692
SYS_API float powf(float x, float y)
GLdouble l
Definition: glew.h:9122
Rand01(unsigned int seed)
Initialize the generator.
Definition: Math.h:143
bool SignChange(const Type &a, const Type &b)
Return true if a and b have different signs.
Definition: Math.h:710
const GLdouble * v
Definition: glew.h:1391
float RoundDown(float x)
Return x rounded down to the nearest integer.
Definition: Math.h:770
RandInt(const EngineType &engine, IntType imin, IntType imax)
Initialize the generator.
Definition: Math.h:175
bool zeroVal< bool >()
Return the bool value that corresponds to zero.
Definition: Math.h:63
bool isNegative(const Type &x)
Return true if x is less than zero.
Definition: Math.h:331
int64_t doubleToInt64(const double aDoubleValue)
Definition: Math.h:457
Tolerance for floating-point comparison.
Definition: Math.h:110
float RoundUp(float x)
Return x rounded up to the nearest integer.
Definition: Math.h:754
float Cbrt(float x)
Return the cube root of a floating-point value.
Definition: Math.h:736
Simple random integer generator.
Definition: Math.h:164
typename hboost::numeric::conversion_traits< S, T >::supertype type
Definition: Math.h:890
ImageBuf OIIO_API pow(const ImageBuf &A, cspan< float > B, ROI roi={}, int nthreads=0)
bool isNegative< bool >(const bool &)
Definition: Math.h:334
size_t MinIndex(const Vec3T &v)
Return the index [0,1,2] of the smallest value in a 3D vector.
Definition: Math.h:903
IMATH_INTERNAL_NAMESPACE_HEADER_ENTER T abs(T a)
Definition: ImathFun.h:55
GLclampf f
Definition: glew.h:3499
GLint GLint GLint GLint GLint x
Definition: glew.h:1252
Coord Abs(const Coord &xyz)
Definition: Coord.h:515
GLint GLint GLint GLint GLint GLint y
Definition: glew.h:1252
float Round(float x)
Return x rounded to the nearest integer.
Definition: Math.h:786
bool isInfinite(const float x)
Return true if x is an infinity value (either positive infinity or negative infinity).
Definition: Math.h:349
Type Pow4(Type x)
Return x4.
Definition: Math.h:523
Delta for small floating-point offsets.
Definition: Math.h:117
float Sqrt(float x)
Return the square root of a floating-point value.
Definition: Math.h:728
GLsizei n
Definition: glew.h:4040
const GLfloat * c
Definition: glew.h:16296
bool isNan(const float x)
Return true if x is a NaN (Not-A-Number) value.
Definition: Math.h:359
Type Pow3(Type x)
Return x3.
Definition: Math.h:519
bool isRelOrApproxEqual(const Type &a, const Type &b, const Type &absTol, const Type &relTol)
Definition: Math.h:418
typedef int(WINAPI *PFNWGLRELEASEPBUFFERDCARBPROC)(HPBUFFERARB hPbuffer
#define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN
Definition: Math.h:47
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:8011
bool isUlpsEqual(const double aLeft, const double aRight, const int64_t aUnitsInLastPlace)
Definition: Math.h:470
T exp(const T &v)
Definition: simd.h:7377
bool isApproxZero(const Type &x)
Return true if x is equal to zero to within the default floating-point comparison tolerance...
Definition: Math.h:313
GLuint GLuint GLsizei GLenum type
Definition: glew.h:1253
bool isApproxEqual(const Type &a, const Type &b)
Return true if a is equal to b to within the default floating-point comparison tolerance.
Definition: Math.h:371
int floor(T x)
Definition: ImathFun.h:150
Type Clamp(Type x, Type min, Type max)
Return x clamped to [min, max].
Definition: Math.h:223
std::string operator+(const std::string &s, bool)
Needed to support the (zeroVal<ValueType>() + val) idiom when ValueType is std::string.
Definition: Math.h:69
#define OPENVDB_EXACT_IS_APPROX_EQUAL(T)
Definition: Math.h:386
GLdouble GLdouble GLdouble b
Definition: glew.h:9122
RandInt(unsigned int seed, IntType imin, IntType imax)
Initialize the generator.
Definition: Math.h:183
GLsizei const GLchar *const * string
Definition: glew.h:1844
int Sign(const Type &x)
Return the sign of the given value as an integer (either -1, 0 or 1).
Definition: Math.h:703
void setSeed(unsigned int seed)
Set the seed value for the random number generator.
Definition: Math.h:195
const Type & Min(const Type &a, const Type &b)
Return the minimum of two values.
Definition: Math.h:623
const EngineType & engine() const
Return a const reference to the random number generator.
Definition: Math.h:152
Type Chop(Type x, Type delta)
Return x if it is greater or equal in magnitude than delta. Otherwise, return zero.
Definition: Math.h:831
constexpr T pi()
Pi constant taken from Boost to match old behaviour.
Definition: Math.h:81
INT64 INT64 INT64 remainder
Definition: wglew.h:1182
int Floor(float x)
Return the floor of x.
Definition: Math.h:815
bool ClampTest01(Type &x)
Return true if x is outside [0,1].
Definition: Math.h:239
IntType operator()()
Return a randomly-generated integer in the current range.
Definition: Math.h:204
float Sin(const float &x)
Return sin x.
Definition: Math.h:683
#define const
Definition: zconf.h:214
int ceil(T x)
Definition: ImathFun.h:158
vint4 min(const vint4 &a, const vint4 &b)
Definition: simd.h:4694
T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:59
Rand01(const EngineType &engine)
Initialize the generator.
Definition: Math.h:139
Type SmoothUnitStep(Type x)
Return 0 if x < 0, 1 if x > 1 or else (3 − 2 x) x .
Definition: Math.h:249
void setRange(IntType imin, IntType imax)
Change the range over which integers are distributed to [imin, imax].
Definition: Math.h:189
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:112
Type Remainder(Type x, Type y)
Return the remainder of x / y.
Definition: Math.h:748
GLsizei const GLfloat * value
Definition: glew.h:1849
const Type & Max(const Type &a, const Type &b)
Return the maximum of two values.
Definition: Math.h:562
SYS_API double sin(double x)
Definition: SYS_FPUMath.h:71
int Mod(int x, int y)
Return the remainder of x / y.
Definition: Math.h:744
auto PrintCast(const T &val) -> typename std::enable_if<!std::is_same< T, int8_t >::value &&!std::is_same< T, uint8_t >::value, const T & >::type
8-bit integer values print to std::ostreams as characters. Cast them so that they print as integers i...
Definition: Math.h:850
bool isZero(const Type &x)
Return true if x is exactly equal to zero.
Definition: Math.h:301
bool isFinite(const float x)
Return true if x is finite.
Definition: Math.h:339
Type Exp(const Type &x)
Return ex.
Definition: Math.h:677
IntType operator()(IntType imin, IntType imax)
Return a randomly-generated integer in the new range [imin, imax], without changing the current range...
Definition: Math.h:208
GLboolean GLboolean g
Definition: glew.h:9477
FloatType operator()()
Return a uniformly distributed random number in the range [0, 1).
Definition: Math.h:155
Type Clamp01(Type x)
Return x clamped to [0, 1].
Definition: Math.h:233
#define OPENVDB_NO_FP_EQUALITY_WARNING_END
Definition: Math.h:48
bool isApproxLarger(const Type &a, const Type &b, const Type &tolerance)
Return true if a is larger than b to within the given tolerance, i.e., if b - a < tolerance...
Definition: Math.h:399