35 #ifndef OPENVDB_MATH_HAS_BEEN_INCLUDED 36 #define OPENVDB_MATH_HAS_BEEN_INCLUDED 45 #include <boost/numeric/conversion/conversion_traits.hpp> 46 #include <boost/math/special_functions/cbrt.hpp> 47 #include <boost/math/special_functions/fpclassify.hpp> 48 #include <boost/random/mersenne_twister.hpp> 49 #include <boost/random/uniform_01.hpp> 50 #include <boost/random/uniform_int.hpp> 51 #include <boost/version.hpp> 58 #define PRAGMA(x) _Pragma(#x) 62 #if defined(__INTEL_COMPILER) 63 #define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN \ 64 _Pragma("warning (push)") \ 65 _Pragma("warning (disable:1572)") 66 #define OPENVDB_NO_FP_EQUALITY_WARNING_END \ 67 _Pragma("warning (pop)") 68 #elif defined(__clang__) 69 #define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN \ 70 PRAGMA(clang diagnostic push) \ 71 PRAGMA(clang diagnostic ignored "-Wfloat-equal") 72 #define OPENVDB_NO_FP_EQUALITY_WARNING_END \ 73 PRAGMA(clang diagnostic pop) 82 #define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN 83 #define OPENVDB_NO_FP_EQUALITY_WARNING_END 94 template<
typename T>
inline T
zeroVal() {
return T(0); }
96 template<>
inline std::string zeroVal<std::string>() {
return ""; }
102 inline std::string
operator+(
const std::string& s,
bool) {
return s; }
105 inline std::string
operator+(
const std::string& s,
int) {
return s; }
106 inline std::string
operator+(
const std::string& s,
float) {
return s; }
107 inline std::string
operator+(
const std::string& s,
double) {
return s; }
116 template<
typename T>
inline T
negative(
const T& val) {
return T(-val); }
118 template<>
inline bool negative(
const bool& val) {
return !val; }
120 template<>
inline std::string
negative(
const std::string& val) {
return val; }
124 template<
typename T>
struct Tolerance {
static T value() {
return zeroVal<T>(); } };
131 template<
typename T>
struct Delta {
static T value() {
return zeroVal<T>(); } };
133 template<>
struct Delta<float> {
static float value() {
return 1e-5f; } };
134 template<>
struct Delta<double> {
static double value() {
return 1e-9; } };
142 template<
typename FloatType =
double,
typename EngineType = boost::mt19937>
147 boost::uniform_01<FloatType> mRand;
154 Rand01(
const EngineType& engine): mEngine(engine) {}
158 Rand01(
unsigned int seed): mEngine(static_cast<typename EngineType::result_type>(seed)) {}
163 mEngine.seed(static_cast<typename EngineType::result_type>(seed));
167 const EngineType&
engine()
const {
return mEngine; }
178 template<
typename IntType =
int,
typename EngineType = boost::mt19937>
182 #if BOOST_VERSION >= 104700 183 typedef boost::random::uniform_int_distribution<IntType> Distr;
185 typedef boost::uniform_int<IntType> Distr;
194 RandInt(
const EngineType& engine, IntType imin, IntType imax):
196 mRand(std::
min(imin, imax), std::
max(imin, imax))
202 RandInt(
unsigned int seed, IntType imin, IntType imax):
203 mEngine(static_cast<typename EngineType::result_type>(seed)),
204 mRand(std::
min(imin, imax), std::
max(imin, imax))
216 mEngine.seed(static_cast<typename EngineType::result_type>(seed));
220 const EngineType&
engine()
const {
return mEngine; }
230 #if BOOST_VERSION >= 104700 231 return mRand(mEngine,
typename Distr::param_type(lo, hi));
233 return Distr(lo, hi)(mEngine);
244 template<
typename Type>
248 assert( !(min>max) );
249 return x > min ? x < max ? x : max :
min;
254 template<
typename Type>
256 Clamp01(Type x) {
return x > Type(0) ? x < Type(1) ? x : Type(1) : Type(0); }
260 template<
typename Type>
264 if (x >= Type(0) && x <= Type(1))
return false;
265 x = x < Type(0) ? Type(0) : Type(1);
270 template<
typename Type>
274 return x > 0 ? x < 1 ? (3-2*x)*x*x : Type(1) : Type(0);
279 template<
typename Type>
292 inline int32_t
Abs(int32_t i) {
return abs(i); }
294 inline int64_t
Abs(int64_t i)
297 return (i < int64_t(0) ? -i : i);
302 inline float Abs(
float x) {
return fabsf(x); }
303 inline double Abs(
double x) {
return fabs(x); }
304 inline long double Abs(
long double x) {
return fabsl(x); }
305 inline uint32_t
Abs(uint32_t i) {
return i; }
306 inline uint64_t
Abs(uint64_t i) {
return i; }
307 inline bool Abs(
bool b) {
return b; }
309 #if defined(__APPLE__) || defined(MACOSX) 310 inline size_t Abs(
size_t i) {
return i; }
322 template<
typename Type>
327 return x == zeroVal<Type>();
334 template<
typename Type>
339 return !(x > tolerance) && !(x < -tolerance);
343 template<
typename Type>
347 return !(x > tolerance) && !(x < -tolerance);
352 template<
typename Type>
361 template<
typename Type>
363 isFinite(
const Type& x) {
return boost::math::isfinite(x); }
368 template<
typename Type>
373 return !(
Abs(a - b) > tolerance);
378 template<
typename Type>
382 return !(
Abs(a - b) > tolerance);
385 #define OPENVDB_EXACT_IS_APPROX_EQUAL(T) \ 386 template<> inline bool isApproxEqual<T>(const T& a, const T& b) { return a == b; } \ 387 template<> inline bool isApproxEqual<T>(const T& a, const T& b, const T&) { return a == b; } \ 396 template<typename Type>
400 return (b - a < tolerance);
405 template<
typename T0,
typename T1>
415 template<
typename Type>
421 if (!(
Abs(a - b) > absTol))
return true;
428 relError =
Abs((a - b) / b);
430 relError =
Abs((a - b) / a);
432 return (relError <= relTol);
449 union FloatOrInt32 {
float floatValue; int32_t int32Value; };
450 const FloatOrInt32* foi =
reinterpret_cast<const FloatOrInt32*
>(&aFloatValue);
451 return foi->int32Value;
458 union DoubleOrInt64 {
double doubleValue; int64_t int64Value; };
459 const DoubleOrInt64* dol =
reinterpret_cast<const DoubleOrInt64*
>(&aDoubleValue);
460 return dol->int64Value;
469 isUlpsEqual(
const double aLeft,
const double aRight,
const int64_t aUnitsInLastPlace)
474 longLeft = INT64_C(0x8000000000000000) - longLeft;
480 longRight = INT64_C(0x8000000000000000) - longRight;
483 int64_t difference = labs(longLeft - longRight);
484 return (difference <= aUnitsInLastPlace);
488 isUlpsEqual(
const float aLeft,
const float aRight,
const int32_t aUnitsInLastPlace)
493 intLeft = 0x80000000 - intLeft;
499 intRight = 0x80000000 - intRight;
502 int32_t difference = abs(intLeft - intRight);
503 return (difference <= aUnitsInLastPlace);
513 template<
typename Type>
514 inline Type
Pow2(Type x) {
return x*x; }
517 template<
typename Type>
518 inline Type
Pow3(Type x) {
return x*x*x; }
521 template<
typename Type>
525 template<
typename Type>
534 while (n--) ans *= x;
543 assert( b >= 0.0f &&
"Pow(float,float): base is negative" );
550 assert( b >= 0.0 &&
"Pow(double,double): base is negative" );
559 template<
typename Type>
561 Max(
const Type& a,
const Type& b)
567 template<
typename Type>
569 Max(
const Type& a,
const Type& b,
const Type& c)
575 template<
typename Type>
577 Max(
const Type& a,
const Type& b,
const Type& c,
const Type& d)
583 template<
typename Type>
585 Max(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
const Type& e)
591 template<
typename Type>
593 Max(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
const Type& e,
const Type& f)
599 template<
typename Type>
601 Max(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
602 const Type& e,
const Type& f,
const Type& g)
608 template<
typename Type>
610 Max(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
611 const Type& e,
const Type& f,
const Type& g,
const Type& h)
620 template<
typename Type>
625 template<
typename Type>
630 template<
typename Type>
632 Min(
const Type& a,
const Type& b,
const Type& c,
const Type& d)
638 template<
typename Type>
640 Min(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
const Type& e)
646 template<
typename Type>
648 Min(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
const Type& e,
const Type& f)
654 template<
typename Type>
656 Min(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
657 const Type& e,
const Type& f,
const Type& g)
663 template<
typename Type>
665 Min(
const Type& a,
const Type& b,
const Type& c,
const Type& d,
666 const Type& e,
const Type& f,
const Type& g,
const Type& h)
675 template<
typename Type>
676 inline Type
Exp(
const Type& x) {
return std::exp(x); }
681 inline float Sin(
const float& x) {
return sinf(x); }
684 inline double Sin(
const double& x) {
return sin(x); }
690 inline float Cos(
const float& x) {
return cosf(x); }
693 inline double Cos(
const double& x) {
return cos(x); }
701 template <
typename Type>
702 inline int Sign(
const Type &x) {
return (zeroVal<Type>() < x) - (x < zeroVal<Type>()); }
707 template <
typename Type>
711 return ( (a<zeroVal<Type>()) ^ (b<zeroVal<Type>()) );
717 template <
typename Type>
721 return a * b <= zeroVal<Type>();
726 inline float Sqrt(
float x) {
return sqrtf(x); }
728 inline double Sqrt(
double x) {
return sqrt(x); }
729 inline long double Sqrt(
long double x) {
return sqrtl(x); }
734 inline float Cbrt(
float x) {
return boost::math::cbrt(x); }
736 inline double Cbrt(
double x) {
return boost::math::cbrt(x); }
737 inline long double Cbrt(
long double x) {
return boost::math::cbrt(x); }
742 inline int Mod(
int x,
int y) {
return (x % y); }
744 inline float Mod(
float x,
float y) {
return fmodf(x,y); }
745 inline double Mod(
double x,
double y) {
return fmod(x,y); }
746 inline long double Mod(
long double x,
long double y) {
return fmodl(x,y); }
747 template<
typename Type>
inline Type
Remainder(Type x, Type y) {
return Mod(x,y); }
752 inline float RoundUp(
float x) {
return ceilf(x); }
754 inline double RoundUp(
double x) {
return ceil(x); }
755 inline long double RoundUp(
long double x) {
return ceill(x); }
757 template<
typename Type>
763 return remainder ? x-remainder+base : x;
768 inline float RoundDown(
float x) {
return floorf(x); }
771 inline long double RoundDown(
long double x) {
return floorl(x); }
773 template<
typename Type>
779 return remainder ? x-remainder : x;
793 template<
typename Type>
799 template<
typename Type>
807 template<
typename Type>
821 inline int Ceil(
float x) {
return int(
RoundUp(x)); }
829 template<
typename Type>
830 inline Type
Chop(Type x, Type delta) {
return (
Abs(x) < delta ? zeroVal<Type>() : x); }
834 template<
typename Type>
838 Type tenth =
Pow(10,digits);
847 template<
typename Type>
875 template <
typename S,
typename T>
877 typedef typename boost::numeric::conversion_traits<S, T>::supertype
type;
888 template<
typename Vec3T>
892 #ifndef _MSC_VER // Visual C++ doesn't guarantee thread-safe initialization of local statics 895 const size_t hashTable[8] = { 2, 1, 9, 1, 2, 9, 0, 0 };
896 const size_t hashKey =
897 ((v[0] < v[1]) << 2) + ((v[0] < v[2]) << 1) + (v[1] < v[2]);
898 return hashTable[hashKey];
909 template<
typename Vec3T>
913 #ifndef _MSC_VER // Visual C++ doesn't guarantee thread-safe initialization of local statics 916 const size_t hashTable[8] = { 2, 1, 9, 1, 2, 9, 0, 0 };
917 const size_t hashKey =
918 ((v[0] > v[1]) << 2) + ((v[0] > v[2]) << 1) + (v[1] > v[2]);
919 return hashTable[hashKey];
926 #endif // OPENVDB_MATH_MATH_HAS_BEEN_INCLUDED double Cos(const double &x)
Return .
Definition: Math.h:693
bool isFinite(const Type &x)
Return true if x is finite.
Definition: Math.h:363
int64_t doubleToInt64(const double aDoubleValue)
Definition: Math.h:456
bool isNegative< bool >(const bool &)
Return false, since bool values are never less than zero.
Definition: Math.h:357
Type RoundUp(Type x, Type base)
Return x rounded up to the nearest multiple of base.
Definition: Math.h:760
Delta for small floating-point offsets.
Definition: Math.h:132
size_t MaxIndex(const Vec3T &v)
Return the index [0,1,2] of the largest value in a 3D vector.
Definition: Math.h:911
void setSeed(unsigned int seed)
Set the seed value for the random number generator.
Definition: Math.h:161
Simple generator of random numbers over the range [0, 1)
Definition: Math.h:143
long double Sqrt(long double x)
Return the square root of a floating-point value.
Definition: Math.h:729
int Floor(long double x)
Return the floor of x.
Definition: Math.h:816
bool isApproxZero(const Type &x, const Type &tolerance)
Return true if x is equal to zero to within the given tolerance.
Definition: Math.h:345
long double Cbrt(long double x)
Return the cube root of a floating-point value.
Definition: Math.h:737
size_t MinIndex(const Vec3T &v)
Return the index [0,1,2] of the smallest value in a 3D vector.
Definition: Math.h:890
double Pow(double b, double e)
Return .
Definition: Math.h:548
T zeroVal()
Return the value of type T that corresponds to zero.
Definition: Math.h:94
FloatType operator()()
Return a uniformly distributed random number in the range [0, 1).
Definition: Math.h:170
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:610
bool isUlpsEqual(const float aLeft, const float aRight, const int32_t aUnitsInLastPlace)
Definition: Math.h:488
static float value()
Definition: Math.h:126
Rand01(unsigned int seed)
Initialize the generator.
Definition: Math.h:158
static float value()
Definition: Math.h:133
void setSeed(unsigned int seed)
Set the seed value for the random number generator.
Definition: Math.h:214
Type EuclideanRemainder(Type x)
Definition: Math.h:795
bool isNegative(const Type &x)
Return true if x is less than zero.
Definition: Math.h:354
RotationOrder
Definition: Math.h:863
Type Pow4(Type x)
Return .
Definition: Math.h:522
int32_t floatToInt32(const float aFloatValue)
Definition: Math.h:447
std::string negative(const std::string &val)
Return the "negation" of the given string.
Definition: Math.h:120
RandInt< int, boost::mt19937 > RandomInt
Definition: Math.h:238
#define OPENVDB_VERSION_NAME
Definition: version.h:43
Type IntegerPart(Type x)
Return the integer part of x.
Definition: Math.h:801
static double value()
Definition: Math.h:134
void setRange(IntType imin, IntType imax)
Change the range over which integers are distributed to [imin, imax].
Definition: Math.h:208
Type Chop(Type x, Type delta)
Return x if it is greater or equal in magnitude than delta. Otherwise, return zero.
Definition: Math.h:830
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:398
Simple random integer generator.
Definition: Math.h:179
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:719
Type Pow3(Type x)
Return .
Definition: Math.h:518
IntType operator()()
Return a randomly-generated integer in the current range.
Definition: Math.h:223
Definition: Exceptions.h:39
Type Clamp(Type x, Type min, Type max)
Return x clamped to [min, max].
Definition: Math.h:246
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:227
int Sign(const Type &x)
Return the sign of the given value as an integer (either -1, 0 or 1).
Definition: Math.h:702
Rand01< double, boost::mt19937 > Random01
Definition: Math.h:173
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:665
long double Mod(long double x, long double y)
Return the remainder of x / y.
Definition: Math.h:746
#define OPENVDB_NO_FP_EQUALITY_WARNING_END
Definition: Math.h:83
FloatType ValueType
Definition: Math.h:150
Type Clamp01(Type x)
Return x clamped to [0, 1].
Definition: Math.h:256
int Ceil(long double x)
Return the ceiling of x.
Definition: Math.h:824
#define OPENVDB_NO_FP_EQUALITY_WARNING_BEGIN
Definition: Math.h:82
Type SmoothUnitStep(Type x, Type min, Type max)
Return 0 if x < min, 1 if x > max or else , where .
Definition: Math.h:281
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:380
bool isExactlyEqual(const T0 &a, const T1 &b)
Return true if a is exactly equal to b.
Definition: Math.h:407
std::string operator+(const std::string &s, double)
Needed to support the (zeroVal<ValueType>() + val) idiom when ValueType is std::string.
Definition: Math.h:107
const EngineType & engine() const
Return a const reference to the random number generator.
Definition: Math.h:220
static double value()
Definition: Math.h:127
bool zeroVal< bool >()
Return the bool value that corresponds to zero.
Definition: Math.h:98
bool isRelOrApproxEqual(const bool &a, const bool &b, const bool &, const bool &)
Definition: Math.h:437
bool Abs(bool b)
Return the absolute value of the given quantity.
Definition: Math.h:307
Axis
Definition: Math.h:856
Type Exp(const Type &x)
Return .
Definition: Math.h:676
RandInt(unsigned int seed, IntType imin, IntType imax)
Initialize the generator.
Definition: Math.h:202
#define OPENVDB_USE_VERSION_NAMESPACE
Definition: version.h:71
Type Inv(Type x)
Return the inverse of x.
Definition: Math.h:849
const EngineType & engine() const
Return a const reference to the random number generator.
Definition: Math.h:167
Rand01(const EngineType &engine)
Initialize the generator.
Definition: Math.h:154
Type Truncate(Type x, unsigned int digits)
Return x truncated to the given number of decimal digits.
Definition: Math.h:836
long double Round(long double x)
Return x rounded to the nearest integer.
Definition: Math.h:787
bool SignChange(const Type &a, const Type &b)
Return true if a and b have different signs.
Definition: Math.h:709
RandInt(const EngineType &engine, IntType imin, IntType imax)
Initialize the generator.
Definition: Math.h:194
bool isZero(const Type &x)
Return true if x is exactly equal to zero.
Definition: Math.h:324
double Sin(const double &x)
Return .
Definition: Math.h:684
#define OPENVDB_EXACT_IS_APPROX_EQUAL(T)
Definition: Math.h:385
Type Remainder(Type x, Type y)
Return the remainder of x / y.
Definition: Math.h:747
bool ClampTest01(Type &x)
Return true if x is outside [0,1].
Definition: Math.h:262
Type Pow2(Type x)
Return .
Definition: Math.h:514
Type RoundDown(Type x, Type base)
Return x rounded down to the nearest multiple of base.
Definition: Math.h:776
Tolerance for floating-point comparison.
Definition: Math.h:125
Type FractionalPart(Type x)
Return the fractional part of x.
Definition: Math.h:809