OpenVDB  6.2.1
Math.h
Go to the documentation of this file.
1 //
3 // Copyright (c) DreamWorks Animation LLC
4 //
5 // All rights reserved. This software is distributed under the
6 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
7 //
8 // Redistributions of source code must retain the above copyright
9 // and license notice and the following restrictions and disclaimer.
10 //
11 // * Neither the name of DreamWorks Animation nor the names of
12 // its contributors may be used to endorse or promote products derived
13 // from this software without specific prior written permission.
14 //
15 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
16 // "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
17 // LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
18 // A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
19 // OWNER OR CONTRIBUTORS BE LIABLE FOR ANY INDIRECT, INCIDENTAL,
20 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
21 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
25 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 // IN NO EVENT SHALL THE COPYRIGHT HOLDERS' AND CONTRIBUTORS' AGGREGATE
27 // LIABILITY FOR ALL CLAIMS REGARDLESS OF THEIR BASIS EXCEED US$250.00.
28 //
30 //
34 
35 #ifndef OPENVDB_MATH_HAS_BEEN_INCLUDED
36 #define OPENVDB_MATH_HAS_BEEN_INCLUDED
37 
38 #include <openvdb/Platform.h>
39 #include <openvdb/version.h>
40 #include <boost/numeric/conversion/conversion_traits.hpp>
41 #include <algorithm> // for std::max()
42 #include <cassert>
43 #include <cmath> // for std::ceil(), std::fabs(), std::pow(), std::sqrt(), etc.
44 #include <cstdlib> // for abs(int)
45 #include <random>
46 #include <string>
47 #include <type_traits> // for std::is_arithmetic
48 
49 
50 // Compile pragmas
51 
52 // Intel(r) compiler fires remark #1572: floating-point equality and inequality
53 // comparisons are unrealiable when == or != is used with floating point operands.
54 #if defined(__INTEL_COMPILER)
55  #define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN \
56  _Pragma("warning (push)") \
57  _Pragma("warning (disable:1572)")
58  #define OPENVDB_NO_FP_EQUALITY_WARNING_END \
59  _Pragma("warning (pop)")
60 #elif defined(__clang__)
61  #define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN \
62  PRAGMA(clang diagnostic push) \
63  PRAGMA(clang diagnostic ignored "-Wfloat-equal")
64  #define OPENVDB_NO_FP_EQUALITY_WARNING_END \
65  PRAGMA(clang diagnostic pop)
66 #else
67  // For GCC, #pragma GCC diagnostic ignored "-Wfloat-equal"
68  // isn't working until gcc 4.2+,
69  // Trying
70  // #pragma GCC system_header
71  // creates other problems, most notably "warning: will never be executed"
72  // in from templates, unsure of how to work around.
73  // If necessary, could use integer based comparisons for equality
74  #define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN
75  #define OPENVDB_NO_FP_EQUALITY_WARNING_END
76 #endif
77 
78 namespace openvdb {
80 namespace OPENVDB_VERSION_NAME {
81 
86 template<typename T> inline T zeroVal() { return T(0); }
88 template<> inline std::string zeroVal<std::string>() { return ""; }
90 template<> inline bool zeroVal<bool>() { return false; }
91 
93 
94 inline std::string operator+(const std::string& s, bool) { return s; }
97 inline std::string operator+(const std::string& s, int) { return s; }
98 inline std::string operator+(const std::string& s, float) { return s; }
99 inline std::string operator+(const std::string& s, double) { return s; }
101 
102 
103 namespace math {
104 
108 template<typename T> inline T negative(const T& val) { return T(-val); }
110 template<> inline bool negative(const bool& val) { return !val; }
112 template<> inline std::string negative(const std::string& val) { return val; }
113 
114 
116 template<typename T> struct Tolerance { static T value() { return zeroVal<T>(); } };
118 template<> struct Tolerance<float> { static float value() { return 1e-8f; } };
119 template<> struct Tolerance<double> { static double value() { return 1e-15; } };
121 
123 template<typename T> struct Delta { static T value() { return zeroVal<T>(); } };
125 template<> struct Delta<float> { static float value() { return 1e-5f; } };
126 template<> struct Delta<double> { static double value() { return 1e-9; } };
128 
129 
130 // ==========> Random Values <==================
131 
134 template<typename FloatType = double, typename EngineType = std::mt19937>
135 class Rand01
136 {
137 private:
138  EngineType mEngine;
139  std::uniform_real_distribution<FloatType> mRand;
140 
141 public:
142  using ValueType = FloatType;
143 
146  Rand01(const EngineType& engine): mEngine(engine) {}
147 
150  Rand01(unsigned int seed): mEngine(static_cast<typename EngineType::result_type>(seed)) {}
151 
153  void setSeed(unsigned int seed)
154  {
155  mEngine.seed(static_cast<typename EngineType::result_type>(seed));
156  }
157 
159  const EngineType& engine() const { return mEngine; }
160 
162  FloatType operator()() { return mRand(mEngine); }
163 };
164 
166 
167 
170 template<typename IntType = int, typename EngineType = std::mt19937>
171 class RandInt
172 {
173 private:
174  using Distr = std::uniform_int_distribution<IntType>;
175  EngineType mEngine;
176  Distr mRand;
177 
178 public:
182  RandInt(const EngineType& engine, IntType imin, IntType imax):
183  mEngine(engine),
184  mRand(std::min(imin, imax), std::max(imin, imax))
185  {}
186 
190  RandInt(unsigned int seed, IntType imin, IntType imax):
191  mEngine(static_cast<typename EngineType::result_type>(seed)),
192  mRand(std::min(imin, imax), std::max(imin, imax))
193  {}
194 
196  void setRange(IntType imin, IntType imax)
197  {
198  mRand = Distr(std::min(imin, imax), std::max(imin, imax));
199  }
200 
202  void setSeed(unsigned int seed)
203  {
204  mEngine.seed(static_cast<typename EngineType::result_type>(seed));
205  }
206 
208  const EngineType& engine() const { return mEngine; }
209 
211  IntType operator()() { return mRand(mEngine); }
212 
215  IntType operator()(IntType imin, IntType imax)
216  {
217  const IntType lo = std::min(imin, imax), hi = std::max(imin, imax);
218  return mRand(mEngine, typename Distr::param_type(lo, hi));
219  }
220 };
221 
223 
224 
225 // ==========> Clamp <==================
226 
228 template<typename Type>
229 inline Type
230 Clamp(Type x, Type min, Type max)
231 {
232  assert( !(min>max) );
233  return x > min ? x < max ? x : max : min;
234 }
235 
236 
238 template<typename Type>
239 inline Type
240 Clamp01(Type x) { return x > Type(0) ? x < Type(1) ? x : Type(1) : Type(0); }
241 
242 
244 template<typename Type>
245 inline bool
246 ClampTest01(Type &x)
247 {
248  if (x >= Type(0) && x <= Type(1)) return false;
249  x = x < Type(0) ? Type(0) : Type(1);
250  return true;
251 }
252 
254 template<typename Type>
255 inline Type
257 {
258  return x > 0 ? x < 1 ? (3-2*x)*x*x : Type(1) : Type(0);
259 }
260 
263 template<typename Type>
264 inline Type
265 SmoothUnitStep(Type x, Type min, Type max)
266 {
267  assert(min < max);
268  return SmoothUnitStep((x-min)/(max-min));
269 }
270 
271 
272 // ==========> Absolute Value <==================
273 
274 
276 inline int32_t Abs(int32_t i) { return abs(i); }
278 inline int64_t Abs(int64_t i)
279 {
280 #ifdef _MSC_VER
281  return (i < int64_t(0) ? -i : i);
282 #else
283  return labs(i);
284 #endif
285 }
286 inline float Abs(float x) { return std::fabs(x); }
287 inline double Abs(double x) { return std::fabs(x); }
288 inline long double Abs(long double x) { return std::fabs(x); }
289 inline uint32_t Abs(uint32_t i) { return i; }
290 inline uint64_t Abs(uint64_t i) { return i; }
291 inline bool Abs(bool b) { return b; }
292 // On OSX size_t and uint64_t are different types
293 #if defined(__APPLE__) || defined(MACOSX)
294 inline size_t Abs(size_t i) { return i; }
295 #endif
296 
297 
298 
300 
301 
302 // ==========> Value Comparison <==================
303 
304 
306 template<typename Type>
307 inline bool
308 isZero(const Type& x)
309 {
311  return x == zeroVal<Type>();
313 }
314 
315 
318 template<typename Type>
319 inline bool
320 isApproxZero(const Type& x)
321 {
322  const Type tolerance = Type(zeroVal<Type>() + Tolerance<Type>::value());
323  return !(x > tolerance) && !(x < -tolerance);
324 }
325 
327 template<typename Type>
328 inline bool
329 isApproxZero(const Type& x, const Type& tolerance)
330 {
331  return !(x > tolerance) && !(x < -tolerance);
332 }
333 
334 
336 template<typename Type>
337 inline bool
338 isNegative(const Type& x) { return x < zeroVal<Type>(); }
339 
340 // Return false, since bool values are never less than zero.
341 template<> inline bool isNegative<bool>(const bool&) { return false; }
342 
343 
345 inline bool
346 isFinite(const float x) { return std::isfinite(x); }
347 
349 template<typename Type, typename std::enable_if<std::is_arithmetic<Type>::value, int>::type = 0>
350 inline bool
351 isFinite(const Type& x) { return std::isfinite(static_cast<double>(x)); }
352 
353 
355 inline bool
356 isInfinite(const float x) { return std::isinf(x); }
357 
359 template<typename Type, typename std::enable_if<std::is_arithmetic<Type>::value, int>::type = 0>
360 inline bool
361 isInfinite(const Type& x) { return std::isinf(static_cast<double>(x)); }
362 
363 
365 inline bool
366 isNan(const float x) { return std::isnan(x); }
367 
369 template<typename Type, typename std::enable_if<std::is_arithmetic<Type>::value, int>::type = 0>
370 inline bool
371 isNan(const Type& x) { return std::isnan(static_cast<double>(x)); }
372 
373 
376 template<typename Type>
377 inline bool
378 isApproxEqual(const Type& a, const Type& b)
379 {
380  const Type tolerance = Type(zeroVal<Type>() + Tolerance<Type>::value());
381  return !(Abs(a - b) > tolerance);
382 }
383 
384 
386 template<typename Type>
387 inline bool
388 isApproxEqual(const Type& a, const Type& b, const Type& tolerance)
389 {
390  return !(Abs(a - b) > tolerance);
391 }
392 
393 #define OPENVDB_EXACT_IS_APPROX_EQUAL(T) \
394  template<> inline bool isApproxEqual<T>(const T& a, const T& b) { return a == b; } \
395  template<> inline bool isApproxEqual<T>(const T& a, const T& b, const T&) { return a == b; } \
396 
397 
400 
401 
404 template<typename Type>
405 inline bool
406 isApproxLarger(const Type& a, const Type& b, const Type& tolerance)
407 {
408  return (b - a < tolerance);
409 }
410 
411 
413 template<typename T0, typename T1>
414 inline bool
415 isExactlyEqual(const T0& a, const T1& b)
416 {
418  return a == b;
420 }
421 
422 
423 template<typename Type>
424 inline bool
425 isRelOrApproxEqual(const Type& a, const Type& b, const Type& absTol, const Type& relTol)
426 {
427  // First check to see if we are inside the absolute tolerance
428  // Necessary for numbers close to 0
429  if (!(Abs(a - b) > absTol)) return true;
430 
431  // Next check to see if we are inside the relative tolerance
432  // to handle large numbers that aren't within the abs tolerance
433  // but could be the closest floating point representation
434  double relError;
435  if (Abs(b) > Abs(a)) {
436  relError = Abs((a - b) / b);
437  } else {
438  relError = Abs((a - b) / a);
439  }
440  return (relError <= relTol);
441 }
442 
443 template<>
444 inline bool
445 isRelOrApproxEqual(const bool& a, const bool& b, const bool&, const bool&)
446 {
447  return (a == b);
448 }
449 
450 
451 // Avoid strict aliasing issues by using type punning
452 // http://cellperformance.beyond3d.com/articles/2006/06/understanding-strict-aliasing.html
453 // Using "casting through a union(2)"
454 inline int32_t
455 floatToInt32(const float aFloatValue)
456 {
457  union FloatOrInt32 { float floatValue; int32_t int32Value; };
458  const FloatOrInt32* foi = reinterpret_cast<const FloatOrInt32*>(&aFloatValue);
459  return foi->int32Value;
460 }
461 
462 
463 inline int64_t
464 doubleToInt64(const double aDoubleValue)
465 {
466  union DoubleOrInt64 { double doubleValue; int64_t int64Value; };
467  const DoubleOrInt64* dol = reinterpret_cast<const DoubleOrInt64*>(&aDoubleValue);
468  return dol->int64Value;
469 }
470 
471 
472 // aUnitsInLastPlace is the allowed difference between the least significant digits
473 // of the numbers' floating point representation
474 // Please read the reference paper before trying to use isUlpsEqual
475 // http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
476 inline bool
477 isUlpsEqual(const double aLeft, const double aRight, const int64_t aUnitsInLastPlace)
478 {
479  int64_t longLeft = doubleToInt64(aLeft);
480  // Because of 2's complement, must restore lexicographical order
481  if (longLeft < 0) {
482  longLeft = INT64_C(0x8000000000000000) - longLeft;
483  }
484 
485  int64_t longRight = doubleToInt64(aRight);
486  // Because of 2's complement, must restore lexicographical order
487  if (longRight < 0) {
488  longRight = INT64_C(0x8000000000000000) - longRight;
489  }
490 
491  int64_t difference = labs(longLeft - longRight);
492  return (difference <= aUnitsInLastPlace);
493 }
494 
495 inline bool
496 isUlpsEqual(const float aLeft, const float aRight, const int32_t aUnitsInLastPlace)
497 {
498  int32_t intLeft = floatToInt32(aLeft);
499  // Because of 2's complement, must restore lexicographical order
500  if (intLeft < 0) {
501  intLeft = 0x80000000 - intLeft;
502  }
503 
504  int32_t intRight = floatToInt32(aRight);
505  // Because of 2's complement, must restore lexicographical order
506  if (intRight < 0) {
507  intRight = 0x80000000 - intRight;
508  }
509 
510  int32_t difference = abs(intLeft - intRight);
511  return (difference <= aUnitsInLastPlace);
512 }
513 
514 
516 
517 
518 // ==========> Pow <==================
519 
521 template<typename Type>
522 inline Type Pow2(Type x) { return x*x; }
523 
525 template<typename Type>
526 inline Type Pow3(Type x) { return x*x*x; }
527 
529 template<typename Type>
530 inline Type Pow4(Type x) { return Pow2(Pow2(x)); }
531 
533 template<typename Type>
534 Type
535 Pow(Type x, int n)
536 {
537  Type ans = 1;
538  if (n < 0) {
539  n = -n;
540  x = Type(1)/x;
541  }
542  while (n--) ans *= x;
543  return ans;
544 }
545 
547 inline float
549 Pow(float b, float e)
550 {
551  assert( b >= 0.0f && "Pow(float,float): base is negative" );
552  return powf(b,e);
553 }
554 
555 inline double
556 Pow(double b, double e)
557 {
558  assert( b >= 0.0 && "Pow(double,double): base is negative" );
559  return std::pow(b,e);
560 }
562 
563 
564 // ==========> Max <==================
565 
567 template<typename Type>
568 inline const Type&
569 Max(const Type& a, const Type& b)
570 {
571  return std::max(a,b);
572 }
573 
575 template<typename Type>
576 inline const Type&
577 Max(const Type& a, const Type& b, const Type& c)
578 {
579  return std::max(std::max(a,b), c);
580 }
581 
583 template<typename Type>
584 inline const Type&
585 Max(const Type& a, const Type& b, const Type& c, const Type& d)
586 {
587  return std::max(std::max(a,b), std::max(c,d));
588 }
589 
591 template<typename Type>
592 inline const Type&
593 Max(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e)
594 {
595  return std::max(std::max(a,b), Max(c,d,e));
596 }
597 
599 template<typename Type>
600 inline const Type&
601 Max(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e, const Type& f)
602 {
603  return std::max(Max(a,b,c), Max(d,e,f));
604 }
605 
607 template<typename Type>
608 inline const Type&
609 Max(const Type& a, const Type& b, const Type& c, const Type& d,
610  const Type& e, const Type& f, const Type& g)
611 {
612  return std::max(Max(a,b,c,d), Max(e,f,g));
613 }
614 
616 template<typename Type>
617 inline const Type&
618 Max(const Type& a, const Type& b, const Type& c, const Type& d,
619  const Type& e, const Type& f, const Type& g, const Type& h)
620 {
621  return std::max(Max(a,b,c,d), Max(e,f,g,h));
622 }
623 
624 
625 // ==========> Min <==================
626 
628 template<typename Type>
629 inline const Type&
630 Min(const Type& a, const Type& b) { return std::min(a, b); }
631 
633 template<typename Type>
634 inline const Type&
635 Min(const Type& a, const Type& b, const Type& c) { return std::min(std::min(a, b), c); }
636 
638 template<typename Type>
639 inline const Type&
640 Min(const Type& a, const Type& b, const Type& c, const Type& d)
641 {
642  return std::min(std::min(a, b), std::min(c, d));
643 }
644 
646 template<typename Type>
647 inline const Type&
648 Min(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e)
649 {
650  return std::min(std::min(a,b), Min(c,d,e));
651 }
652 
654 template<typename Type>
655 inline const Type&
656 Min(const Type& a, const Type& b, const Type& c, const Type& d, const Type& e, const Type& f)
657 {
658  return std::min(Min(a,b,c), Min(d,e,f));
659 }
660 
662 template<typename Type>
663 inline const Type&
664 Min(const Type& a, const Type& b, const Type& c, const Type& d,
665  const Type& e, const Type& f, const Type& g)
666 {
667  return std::min(Min(a,b,c,d), Min(e,f,g));
668 }
669 
671 template<typename Type>
672 inline const Type&
673 Min(const Type& a, const Type& b, const Type& c, const Type& d,
674  const Type& e, const Type& f, const Type& g, const Type& h)
675 {
676  return std::min(Min(a,b,c,d), Min(e,f,g,h));
677 }
678 
679 
680 // ============> Exp <==================
681 
683 template<typename Type>
684 inline Type Exp(const Type& x) { return std::exp(x); }
685 
686 // ============> Sin <==================
687 
689 inline float Sin(const float& x) { return std::sin(x); }
691 
692 inline double Sin(const double& x) { return std::sin(x); }
694 
695 // ============> Cos <==================
696 
698 inline float Cos(const float& x) { return std::cos(x); }
700 
701 inline double Cos(const double& x) { return std::cos(x); }
703 
704 
706 
707 
709 template <typename Type>
710 inline int Sign(const Type &x) { return (zeroVal<Type>() < x) - (x < zeroVal<Type>()); }
711 
712 
715 template <typename Type>
716 inline bool
717 SignChange(const Type& a, const Type& b)
718 {
719  return ( (a<zeroVal<Type>()) ^ (b<zeroVal<Type>()) );
720 }
721 
722 
725 template <typename Type>
726 inline bool
727 ZeroCrossing(const Type& a, const Type& b)
728 {
729  return a * b <= zeroVal<Type>();
730 }
731 
732 
734 inline float Sqrt(float x) { return std::sqrt(x); }
736 inline double Sqrt(double x) { return std::sqrt(x); }
737 inline long double Sqrt(long double x) { return std::sqrt(x); }
739 
740 
742 inline float Cbrt(float x) { return std::cbrt(x); }
744 inline double Cbrt(double x) { return std::cbrt(x); }
745 inline long double Cbrt(long double x) { return std::cbrt(x); }
747 
748 
750 inline int Mod(int x, int y) { return (x % y); }
752 inline float Mod(float x, float y) { return std::fmod(x, y); }
753 inline double Mod(double x, double y) { return std::fmod(x, y); }
754 inline long double Mod(long double x, long double y) { return std::fmod(x, y); }
755 template<typename Type> inline Type Remainder(Type x, Type y) { return Mod(x, y); }
757 
758 
760 inline float RoundUp(float x) { return std::ceil(x); }
762 inline double RoundUp(double x) { return std::ceil(x); }
763 inline long double RoundUp(long double x) { return std::ceil(x); }
765 template<typename Type>
767 inline Type
768 RoundUp(Type x, Type base)
769 {
770  Type remainder = Remainder(x, base);
771  return remainder ? x-remainder+base : x;
772 }
773 
774 
776 inline float RoundDown(float x) { return std::floor(x); }
778 inline double RoundDown(double x) { return std::floor(x); }
779 inline long double RoundDown(long double x) { return std::floor(x); }
781 template<typename Type>
783 inline Type
784 RoundDown(Type x, Type base)
785 {
786  Type remainder = Remainder(x, base);
787  return remainder ? x-remainder : x;
788 }
789 
790 
792 inline float Round(float x) { return RoundDown(x + 0.5f); }
794 inline double Round(double x) { return RoundDown(x + 0.5); }
795 inline long double Round(long double x) { return RoundDown(x + 0.5l); }
797 
798 
801 template<typename Type>
802 inline Type
803 EuclideanRemainder(Type x) { return x - RoundDown(x); }
804 
805 
807 template<typename Type>
808 inline Type
809 IntegerPart(Type x)
810 {
811  return (x > 0 ? RoundDown(x) : RoundUp(x));
812 }
813 
815 template<typename Type>
816 inline Type
817 FractionalPart(Type x) { return Mod(x,Type(1)); }
818 
819 
821 inline int Floor(float x) { return int(RoundDown(x)); }
823 inline int Floor(double x) { return int(RoundDown(x)); }
824 inline int Floor(long double x) { return int(RoundDown(x)); }
826 
827 
829 inline int Ceil(float x) { return int(RoundUp(x)); }
831 inline int Ceil(double x) { return int(RoundUp(x)); }
832 inline int Ceil(long double x) { return int(RoundUp(x)); }
834 
835 
837 template<typename Type>
838 inline Type Chop(Type x, Type delta) { return (Abs(x) < delta ? zeroVal<Type>() : x); }
839 
840 
842 template<typename Type>
843 inline Type
844 Truncate(Type x, unsigned int digits)
845 {
846  Type tenth = Pow(10,digits);
847  return RoundDown(x*tenth+0.5)/tenth;
848 }
849 
850 
852 
853 
856 template<typename T>
857 inline auto PrintCast(const T& val) -> typename std::enable_if<!std::is_same<T, int8_t>::value
858  && !std::is_same<T, uint8_t>::value, const T&>::type { return val; }
859 inline int32_t PrintCast(int8_t val) { return int32_t(val); }
860 inline uint32_t PrintCast(uint8_t val) { return uint32_t(val); }
861 
862 
864 
865 
867 template<typename Type>
868 inline Type
869 Inv(Type x)
870 {
871  assert(x);
872  return Type(1)/x;
873 }
874 
875 
876 enum Axis {
877  X_AXIS = 0,
878  Y_AXIS = 1,
879  Z_AXIS = 2
880 };
881 
882 // enum values are consistent with their historical mx analogs.
892 };
893 
894 
895 template <typename S, typename T>
896 struct promote {
897  using type = typename boost::numeric::conversion_traits<S, T>::supertype;
898 };
899 
900 
908 template<typename Vec3T>
909 size_t
910 MinIndex(const Vec3T& v)
911 {
912 #ifndef _MSC_VER // Visual C++ doesn't guarantee thread-safe initialization of local statics
913  static
914 #endif
915  const size_t hashTable[8] = { 2, 1, 9, 1, 2, 9, 0, 0 };//9 is a dummy value
916  const size_t hashKey =
917  ((v[0] < v[1]) << 2) + ((v[0] < v[2]) << 1) + (v[1] < v[2]);// ?*4+?*2+?*1
918  return hashTable[hashKey];
919 }
920 
921 
929 template<typename Vec3T>
930 size_t
931 MaxIndex(const Vec3T& v)
932 {
933 #ifndef _MSC_VER // Visual C++ doesn't guarantee thread-safe initialization of local statics
934  static
935 #endif
936  const size_t hashTable[8] = { 2, 1, 9, 1, 2, 9, 0, 0 };//9 is a dummy value
937  const size_t hashKey =
938  ((v[0] > v[1]) << 2) + ((v[0] > v[2]) << 1) + (v[1] > v[2]);// ?*4+?*2+?*1
939  return hashTable[hashKey];
940 }
941 
942 } // namespace math
943 } // namespace OPENVDB_VERSION_NAME
944 } // namespace openvdb
945 
946 #endif // OPENVDB_MATH_MATH_HAS_BEEN_INCLUDED
947 
948 // Copyright (c) DreamWorks Animation LLC
949 // All rights reserved. This software is distributed under the
950 // Mozilla Public License 2.0 ( http://www.mozilla.org/MPL/2.0/ )
Type SmoothUnitStep(Type x, Type min, Type max)
Return 0 if x < min, 1 if x > max or else (3 − 2 t) t², where t = (x − min)/(max − min)...
Definition: Math.h:265
bool isNegative< bool >(const bool &)
Definition: Math.h:341
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:415
Definition: Math.h:884
const Type & Max(const Type &a, const Type &b, const Type &c, const Type &d, const Type &e, const Type &f, const Type &g, const Type &h)
Return the maximum of eight values.
Definition: Math.h:618
RandInt(unsigned int seed, IntType imin, IntType imax)
Initialize the generator.
Definition: Math.h:190
Type IntegerPart(Type x)
Return the integer part of x.
Definition: Math.h:809
Definition: Math.h:887
bool isFinite(const Type &x)
Return true if x is finite.
Definition: Math.h:351
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:215
Definition: Math.h:889
Type Pow4(Type x)
Return x4.
Definition: Math.h:530
Definition: Math.h:891
bool isApproxZero(const Type &x, const Type &tolerance)
Return true if x is equal to zero to within the given tolerance.
Definition: Math.h:329
Type Chop(Type x, Type delta)
Return x if it is greater or equal in magnitude than delta. Otherwise, return zero.
Definition: Math.h:838
Delta for small floating-point offsets.
Definition: Math.h:124
bool Abs(bool b)
Return the absolute value of the given quantity.
Definition: Math.h:291
Rand01(unsigned int seed)
Initialize the generator.
Definition: Math.h:150
const std::enable_if<!VecTraits< T >::IsVec, T >::type & max(const T &a, const T &b)
Definition: Composite.h:133
const Type & Min(const Type &a, const Type &b, const Type &c, const Type &d, const Type &e, const Type &f, const Type &g, const Type &h)
Return the minimum of eight values.
Definition: Math.h:673
Type RoundUp(Type x, Type base)
Return x rounded up to the nearest multiple of base.
Definition: Math.h:768
bool isRelOrApproxEqual(const bool &a, const bool &b, const bool &, const bool &)
Definition: Math.h:445
static double value()
Definition: Math.h:126
Type Clamp(Type x, Type min, Type max)
Return x clamped to [min, max].
Definition: Math.h:230
int Floor(long double x)
Return the floor of x.
Definition: Math.h:824
double Sin(const double &x)
Return sin x.
Definition: Math.h:692
Definition: Coord.h:614
Type Exp(const Type &x)
Return ex.
Definition: Math.h:684
void setSeed(unsigned int seed)
Set the seed value for the random number generator.
Definition: Math.h:202
bool isUlpsEqual(const float aLeft, const float aRight, const int32_t aUnitsInLastPlace)
Definition: Math.h:496
RandInt(const EngineType &engine, IntType imin, IntType imax)
Initialize the generator.
Definition: Math.h:182
Type Inv(Type x)
Return the inverse of x.
Definition: Math.h:869
Type EuclideanRemainder(Type x)
Definition: Math.h:803
long double Round(long double x)
Return x rounded to the nearest integer.
Definition: Math.h:795
bool isApproxEqual(const Type &a, const Type &b, const Type &tolerance)
Return true if a is equal to b to within the given tolerance.
Definition: Math.h:388
Simple random integer generator.
Definition: Math.h:171
std::string negative(const std::string &val)
Return the "negation" of the given string.
Definition: Math.h:112
size_t MinIndex(const Vec3T &v)
Return the index [0,1,2] of the smallest value in a 3D vector.
Definition: Math.h:910
static double value()
Definition: Math.h:119
Type Truncate(Type x, unsigned int digits)
Return x truncated to the given number of decimal digits.
Definition: Math.h:844
Definition: Math.h:879
Type Pow3(Type x)
Return x3.
Definition: Math.h:526
#define OPENVDB_VERSION_NAME
The version namespace name for this library version.
Definition: version.h:128
Definition: Math.h:885
int Ceil(long double x)
Return the ceiling of x.
Definition: Math.h:832
std::string operator+(const std::string &s, double)
Needed to support the (zeroVal<ValueType>() + val) idiom when ValueType is std::string.
Definition: Math.h:99
uint32_t PrintCast(uint8_t val)
Definition: Math.h:860
int64_t doubleToInt64(const double aDoubleValue)
Definition: Math.h:464
void setRange(IntType imin, IntType imax)
Change the range over which integers are distributed to [imin, imax].
Definition: Math.h:196
Simple generator of random numbers over the range [0, 1)
Definition: Math.h:135
Type Pow2(Type x)
Return x2.
Definition: Math.h:522
int32_t floatToInt32(const float aFloatValue)
Definition: Math.h:455
Rand01(const EngineType &engine)
Initialize the generator.
Definition: Math.h:146
Definition: Math.h:888
bool isNegative(const Type &x)
Return true if x is less than zero.
Definition: Math.h:338
Definition: Exceptions.h:40
const EngineType & engine() const
Return a const reference to the random number generator.
Definition: Math.h:208
Definition: Math.h:890
Tolerance for floating-point comparison.
Definition: Math.h:117
Axis
Definition: Math.h:876
#define OPENVDB_NO_FP_EQUALITY_WARNING_END
Definition: Math.h:75
bool zeroVal< bool >()
Return the bool value that corresponds to zero.
Definition: Math.h:90
bool ClampTest01(Type &x)
Return true if x is outside [0,1].
Definition: Math.h:246
Definition: Math.h:878
long double Mod(long double x, long double y)
Return the remainder of x / y.
Definition: Math.h:754
Library and file format version numbers.
const EngineType & engine() const
Return a const reference to the random number generator.
Definition: Math.h:159
T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:86
long double Sqrt(long double x)
Return the square root of a floating-point value.
Definition: Math.h:737
Definition: Math.h:877
bool isNan(const Type &x)
Return true if x is a NaN (Not-A-Number) value.
Definition: Math.h:371
static float value()
Definition: Math.h:118
#define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN
Definition: Math.h:74
const std::enable_if<!VecTraits< T >::IsVec, T >::type & min(const T &a, const T &b)
Definition: Composite.h:129
Type FractionalPart(Type x)
Return the fractional part of x.
Definition: Math.h:817
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:727
int Sign(const Type &x)
Return the sign of the given value as an integer (either -1, 0 or 1).
Definition: Math.h:710
Type Remainder(Type x, Type y)
Return the remainder of x / y.
Definition: Math.h:755
double Pow(double b, double e)
Return be.
Definition: Math.h:556
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:406
IntType operator()()
Return a randomly-generated integer in the current range.
Definition: Math.h:211
bool isZero(const Type &x)
Return true if x is exactly equal to zero.
Definition: Math.h:308
bool SignChange(const Type &a, const Type &b)
Return true if a and b have different signs.
Definition: Math.h:717
Type Clamp01(Type x)
Return x clamped to [0, 1].
Definition: Math.h:240
Type RoundDown(Type x, Type base)
Return x rounded down to the nearest multiple of base.
Definition: Math.h:784
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:180
Definition: Math.h:896
typename boost::numeric::conversion_traits< S, T >::supertype type
Definition: Math.h:897
Definition: Math.h:886
RotationOrder
Definition: Math.h:883
double Cos(const double &x)
Return cos x.
Definition: Math.h:701
FloatType operator()()
Return a uniformly distributed random number in the range [0, 1).
Definition: Math.h:162
#define OPENVDB_EXACT_IS_APPROX_EQUAL(T)
Definition: Math.h:393
size_t MaxIndex(const Vec3T &v)
Return the index [0,1,2] of the largest value in a 3D vector.
Definition: Math.h:931
void setSeed(unsigned int seed)
Set the seed value for the random number generator.
Definition: Math.h:153
bool isInfinite(const Type &x)
Return true if x is an infinity value (either positive infinity or negative infinity).
Definition: Math.h:361
long double Cbrt(long double x)
Return the cube root of a floating-point value.
Definition: Math.h:745
static float value()
Definition: Math.h:125