HDK
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
SYS_Math.h
Go to the documentation of this file.
1 /*
2  * PROPRIETARY INFORMATION. This software is proprietary to
3  * Side Effects Software Inc., and is not to be reproduced,
4  * transmitted, or disclosed in any way without written permission.
5  *
6  * NAME: SYS_Math.h (SYS Library, C++)
7  *
8  * COMMENTS: Houdini math interface.
9  * statements like: a = sin(x); b = sinf(y);
10  * we use: a = SYSsin(x); b = SYSsin(y);
11  *
12  * Functions defined here:
13  * SYSmin(a,b) - Returns the minimum of a or b
14  * SYSmin(a,b,c) - Returns the minimum of a, b or c
15  * SYSmin(a,b,c,d) - Returns minimum of a, b, c or d
16  * SYSargmin(a,b) - Returns index of minimum number
17  * SYSargmin(a,b,c) - Returns index of minimum number
18  * SYSargmin(a,b,c,d) - Returns index of minimum number
19  * SYSmax(a,b) - Returns the maximum of a or b
20  * SYSmax(a,b,c) - Returns the maximum of a, b or c
21  * SYSmax(a,b,c,d) - Returns maximum of a, b, c or d
22  * SYSsort(a, b) - Sorts so a < b
23  * SYSsort(a, b, c) - Sorts so a < b < c
24  * SYSargmax(a,b) - Returns index of largest number
25  * SYSargmax(a,b,c) - Returns index of largest number
26  * SYSargmax(a,b,c,d) - Returns index of largest number
27  * SYSabs(x) - Works for all types (including fpreal)
28  * SYSavg(a,b,c) - Return average value of 3 values
29  * SYSavg(a,b,c,d) - Return average value of 4 values
30  *
31  * SYSminmax(a,b,&min.&max) - Find min and max of 2 values
32  * SYSminmax(a,b,c,&min.&max) - Find min and max of 3 values
33  * SYSminmax(a,b,c,d,&min.&max) - Find min and max of 4 values
34  *
35  * SYSwrapmod(a, b) - Returns [0..b) interval for +ve b.
36  *
37  * SYSsignum(a) - Numerically robust Sign function:
38  * -1, if a is negative
39  * 1, if a is positive
40  * 0, otherwise:
41  *
42  * Comparison:
43  * SYSequalZero(a, [tol]) - Is a equal to zero
44  * SYSisEqual(a, b, tol) -
45  * SYSalmostEqual(a, b, ulps, tol) - Almost equal given units in last place
46  *
47  * Interpolation/Range:
48  * SYSclamp(a, min, max) - Clamp value between min and max
49  * SYSsmooth(min, max, a) - Ease-in ease-out curve
50  * SYSsmooth(min, max, a, roll) - Ease-in ease-out curve (with rolloff)
51  * SYSsmoother(min, max, a) - Ease-in ease-out curve (2nd order)
52  * SYSlerp(v1, v2, bias) - Linear interpolation
53  * SYSinvlerp(a, min, max) - Bias required to return a when
54  * lerping min and max.
55  * SYSfit(v, omin,omax, nmin,nmax) - Map v in (omin,omax) to (nmin,nmax),
56  * clamping to (nmin, nmax)
57  * SYSefit(v, omin,omax, nmin,nmax)- Map as in SYSfit() without clamping
58  * to (nmin,nmax). (ie, extrapolate)
59  *
60  * The bilerp function expects:
61  * u0v1--u1v1
62  * | |
63  * u0v0--u1v0
64  * Where u is horizontal and v is vertical in the diagram above.
65  * SYSbilerp(u0v0, u1v0, u0v1, u1v1, u, v)
66  *
67  * Standard math (single/double precision signatures):
68  * SYSsin(x)
69  * SYScos(x)
70  * SYStan(x)
71  * SYSsqrt(x)
72  * SYSlog(x)
73  * SYSfabs(x)
74  * SYStrunc(x)
75  * SYSfloor(x)
76  * SYSceil(x)
77  * SYScbrt(x) -- Use #include <SYS/SYS_MathCbrt.h>
78  * SYSlog10(x)
79  * SYSfmod(x,y)
80  * SYSpow(x,y)
81  * SYSsafepow(x, y)
82  * SYSatan(x)
83  * SYSatan(y,x) -- Note, SYSatan(y,x) is equivalent to SYSatan2(y,x)
84  * SYSatan2(y,x)
85  * SYShypot(x,y)
86  * SYSrecip(x)
87  * SYSsafediv(x,y) - Divide only if y != 0
88  * SYSsaferecip(x) - Recip only if x != 0
89  * SYSsafesqrt(x) - Compute sqrt only if x >= 0
90  * SYSsafefmod(x, y) - Mod only if y != 0
91  * SYSsincos(x,*out_sin, *out_cos)
92  *
93  * Random:
94  * SYSwang_inthash - 32-bit Integer hashing function
95  * SYSwang_inthash64 - 64-bit Integer hashing function
96  * SYSwang2_inthash - Newer 32-bit Integer hashing function
97  * SYSwang2_inthash64 - Newer 64-bit Integer hashing function
98  * SYSreal_hash - Generate a hash for a real number
99  * SYSreal_hashseed - Generate a hash for a real number
100  * SYSvector_hash - Generate a hash for a real vector
101  * SYSfastRandom - Really fast random number generator (0,1)
102  * SYSrandom - Fast random number (fewer artifacts) (0,1)
103  * SYSfastRandomZero - Really fast random number generator (-.5, .5)
104  * SYSrandomZero - Fast random number (fewer artifacts) (-.5, .5)
105  *
106  * Rounding:
107  * SYSroundDownToMultipleOf -
108  * SYSroundUpToMultipleOf -
109  * SYSroundAngle -
110  *
111  * Misc:
112  * SYSisNan - Is this a valid floating-point number?
113  * SYSisFinite - Is not a NAN or Infinity
114  * SYSisInf - Is an Infinity
115  * SYSisNormal - Is a normalized floating point number
116  * SYSisInt - Is the string an integer
117  * SYSisFloat - Is the string a float
118  * SYSisPrime - Is it a prime?
119  * SYSsameSign(a,b) - Do the non-zero numbers have the same sign?
120  * (Note: does not work if either number is zero)
121  * SYSmakePrime - Make it a prime
122  * SYSnextPrime - Next prime
123  * SYSsincosDeg - sin/cos from degrees, multiples of 90 are accurate
124  * SYSgetSinCosFromSlope - Compute sin/cos given a slope
125  * SYShexCharToInt - map '0'-'9,'a'-'z' to 0-15, or -1
126  * SYSintToHexChar - map 0-15 to '0'-'9,'a'-'z'
127  * SYSdivMod(n,d,q,r) - q = n/d; r = n%d; The compiler should make
128  * just one DIV or IDIV instruction.
129  *
130  * For information on almostEqual, please see:
131  * http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm
132  *
133  */
134 
135 #ifndef __SYS_Math__
136 #define __SYS_Math__
137 
138 #include "SYS_API.h"
139 #include "SYS_Types.h"
140 
141 /*
142  * System dependent includes
143  */
144 #if defined(LINUX)
145 # include "SYS_FastMath.h"
146 #endif
147 
148 #include <float.h>
149 #include <limits>
150 #include <math.h>
151 #include <stdio.h>
152 #include <stdlib.h>
153 
154 // We do not want to use the built-ins for srand48 or drand48 as they
155 // are not threadsafe. This version uses thread local storage to
156 // avoid that.
157 SYS_API void SYSsrand48(long seed);
158 SYS_API double SYSdrand48();
159 
160 #if !defined(SESI_ALLOW_DRAND48)
161 
162 // These macros are to aggressively prevent anyone from accidetnally
163 // using thread unsafe functions
164 #undef srand48
165 #undef drand48
166 #define srand48(X) static_assert(0, "Use SYSsrand48() instead")
167 #define drand48(X) 0; { static_assert(0, "Use SYSdrand48() instead"); }
168 
169 #endif
170 
171 // It would be useful to disable rand() and srand() as well, but
172 // they are used by std::rand :<
173 
174 template< typename F >
175 constexpr inline int
176 SYSsignum(const F a) noexcept
177 {
178  return int(F(0) < a) - int(a < F(0));
179 }
180 
181 // Determine whether f is not-a-number (NAN) for any floating point type f
182 template< typename F >
183 constexpr inline bool
184 SYSisNan(const F f)
185 {
186  return(f != f);
187 }
188 
189 template <>
190 inline bool
192 {
193  return f.isNan();
194 }
195 
196 #include <cmath>
197 
198 /// Check whether a number is finite. That is, not Nan and not infinity.
199 /// @see SYSisNan()
200 /// @{
201 inline bool SYSisFinite(fpreal64 f) { return std::isfinite(f); }
202 inline bool SYSisFinite(fpreal32 f) { return std::isfinite(f); }
203 inline bool SYSisFinite(fpreal16 f) { return f.isFinite(); }
204 constexpr inline bool SYSisFinite(int32 f) { return true; }
205 constexpr inline bool SYSisFinite(int64 f) { return true; }
206 /// @}
207 
208 /// Check whether a number is an infinity.
209 /// @{
210 inline bool SYSisInf(fpreal64 f) { return std::isinf(f); }
211 inline bool SYSisInf(fpreal32 f) { return std::isinf(f); }
212 inline bool SYSisInf(fpreal16 f) { return f.isInfinity(); }
213 constexpr inline bool SYSisInf(int32 f) { return false; }
214 constexpr inline bool SYSisInf(int64 f) { return false; }
215 /// @}
216 
217 /// SYSisNormal() checks whether the string represents a non-finite number
218 /// @{
219 inline bool SYSisNormal(fpreal64 f) { return std::isnormal(f); }
220 inline bool SYSisNormal(fpreal32 f) { return std::isnormal(f); }
221 inline bool SYSisNormal(fpreal16 f) { return f.isNormalized(); }
222 constexpr inline bool SYSisNormal(int32 f) { return true; }
223 constexpr inline bool SYSisNormal(int64 f) { return true; }
224 /// @}
225 
226 /// SYSisNan() checks whether the string represents a non-finite number
227 SYS_API bool SYSisNan(const char *number);
228 SYS_API bool SYSisInt(const char *str);
229 SYS_API bool SYSisFloat(const char *str);
234 SYS_API bool SYSisPrime(uint num);
235 SYS_API bool SYSisPrime(uint64 num);
238 
239 #if defined(__cplusplus)
240 
241 // NOTE:
242 // These have been carefully written so that in the case of equality
243 // we always return the first parameter. This is so that NANs in
244 // in the second parameter are suppressed.
245 #define h_min(a, b) (((a) > (b)) ? (b) : (a))
246 #define h_argmin(a, b) (((a) > (b)) ? 1 : 0)
247 #define h_max(a, b) (((a) < (b)) ? (b) : (a))
248 #define h_argmax(a, b) (((a) < (b)) ? 1 : 0)
249 // DO NOT CHANGE THE ABOVE WITHOUT READING THE COMMENT
250 #define h_abs(a) (((a) > 0) ? (a) : -(a))
251 #define h_sgn(a) (((a) > 0) ? 1 : (((a) < 0) ? -1 : 0))
252 
253 
254 static constexpr inline int16 SYSmin(int16 a, int16 b) { return h_min(a,b); }
255 static constexpr inline int16 SYSmax(int16 a, int16 b) { return h_max(a,b); }
256 static constexpr inline int16 SYSabs(int16 a) { return h_abs(a); }
257 static constexpr inline int16 SYSsgn(int16 a) { return h_sgn(a); }
258 static constexpr inline int SYSargmin(int16 a, int16 b) { return h_argmin(a,b);}
259 static constexpr inline int SYSargmax(int16 a, int16 b) { return h_argmax(a,b);}
260 static constexpr inline int32 SYSmin(int32 a, int32 b) { return h_min(a,b); }
261 static constexpr inline int32 SYSmax(int32 a, int32 b) { return h_max(a,b); }
262 static constexpr inline int32 SYSabs(int32 a) { return h_abs(a); }
263 static constexpr inline int32 SYSsgn(int32 a) { return h_sgn(a); }
264 static constexpr inline int SYSargmin(int32 a, int32 b) { return h_argmin(a,b);}
265 static constexpr inline int SYSargmax(int32 a, int32 b) { return h_argmax(a,b);}
266 static constexpr inline int64 SYSmin(int64 a, int64 b) { return h_min(a,b); }
267 static constexpr inline int64 SYSmax(int64 a, int64 b) { return h_max(a,b); }
268 static constexpr inline int64 SYSmin(int32 a, int64 b) { return h_min(a,b); }
269 static constexpr inline int64 SYSmax(int32 a, int64 b) { return h_max(a,b); }
270 static constexpr inline int64 SYSmin(int64 a, int32 b) { return h_min(a,b); }
271 static constexpr inline int64 SYSmax(int64 a, int32 b) { return h_max(a,b); }
272 static constexpr inline int64 SYSabs(int64 a) { return h_abs(a); }
273 static constexpr inline int64 SYSsgn(int64 a) { return h_sgn(a); }
274 static constexpr inline int SYSargmin(int64 a, int64 b) { return h_argmin(a,b);}
275 static constexpr inline int SYSargmax(int64 a, int64 b) { return h_argmax(a,b);}
276 static constexpr inline uint16 SYSmin(uint16 a, uint16 b) { return h_min(a,b); }
277 static constexpr inline uint16 SYSmax(uint16 a, uint16 b) { return h_max(a,b); }
278 static constexpr inline int SYSargmin(uint16 a, uint16 b) { return h_argmin(a,b);}
279 static constexpr inline int SYSargmax(uint16 a, uint16 b) { return h_argmax(a,b);}
280 static constexpr inline uint32 SYSmin(uint32 a, uint32 b) { return h_min(a,b); }
281 static constexpr inline uint32 SYSmax(uint32 a, uint32 b) { return h_max(a,b); }
282 static constexpr inline int SYSargmin(uint32 a, uint32 b) { return h_argmin(a,b);}
283 static constexpr inline int SYSargmax(uint32 a, uint32 b) { return h_argmax(a,b);}
284 static constexpr inline uint64 SYSmin(uint64 a, uint64 b) { return h_min(a,b); }
285 static constexpr inline uint64 SYSmax(uint64 a, uint64 b) { return h_max(a,b); }
286 static constexpr inline int SYSargmin(uint64 a, uint64 b) { return h_argmin(a,b);}
287 static constexpr inline int SYSargmax(uint64 a, uint64 b) { return h_argmax(a,b);}
288 static inline fpreal16 SYSmin(fpreal16 a, fpreal16 b) { return h_min(a,b); }
289 static inline fpreal16 SYSmax(fpreal16 a, fpreal16 b) { return h_max(a,b); }
290 static inline fpreal16 SYSsgn(fpreal16 a) { return h_sgn(a); }
291 static inline int SYSargmin(fpreal16 a, fpreal16 b){ return h_argmin(a,b);}
292 static inline int SYSargmax(fpreal16 a, fpreal16 b){ return h_argmax(a,b);}
293 static constexpr inline fpreal32 SYSmin(fpreal32 a, fpreal32 b) { return h_min(a,b); }
294 static constexpr inline fpreal32 SYSmax(fpreal32 a, fpreal32 b) { return h_max(a,b); }
295 static constexpr inline fpreal32 SYSsgn(fpreal32 a) { return h_sgn(a); }
296 static constexpr inline int SYSargmin(fpreal32 a, fpreal32 b){ return h_argmin(a,b);}
297 static constexpr inline int SYSargmax(fpreal32 a, fpreal32 b){ return h_argmax(a,b);}
298 static constexpr inline fpreal64 SYSmin(fpreal64 a, fpreal64 b) { return h_min(a,b); }
299 static constexpr inline fpreal64 SYSmax(fpreal64 a, fpreal64 b) { return h_max(a,b); }
300 static constexpr inline fpreal64 SYSsgn(fpreal64 a) { return h_sgn(a); }
301 static constexpr inline int SYSargmin(fpreal64 a, fpreal64 b){ return h_argmin(a,b);}
302 static constexpr inline int SYSargmax(fpreal64 a, fpreal64 b){ return h_argmax(a,b);}
303 
304 // Some systems have size_t as a seperate type from uint. Some don't.
305 #if defined(MBSD)
306 static constexpr inline size_t SYSmin(size_t a, size_t b) { return h_min(a,b); }
307 static constexpr inline size_t SYSmax(size_t a, size_t b) { return h_max(a,b); }
308 static constexpr inline int SYSargmin(size_t a, size_t b) { return h_argmin(a,b);}
309 static constexpr inline int SYSargmax(size_t a, size_t b) { return h_argmax(a,b);}
310 static constexpr inline size_t SYSmin(long a, long b) { return h_min(a,b); }
311 static constexpr inline size_t SYSmax(long a, long b) { return h_max(a,b); }
312 static constexpr inline int SYSargmin(long a, long b) { return h_argmin(a,b);}
313 static constexpr inline int SYSargmax(long a, long b) { return h_argmax(a,b);}
314 #endif
315 
316 #undef h_min
317 #undef h_max
318 #undef h_abs
319 #undef h_sgn
320 
321 #define h_clamp(val, min, max, tol) \
322  ((val <= min+tol) ? min : ((val >= max-tol) ? max : val))
323 
324  static constexpr inline int
325  SYSclamp(int v, int min, int max)
326  { return h_clamp(v, min, max, 0); }
327 
328  static constexpr inline uint
330  { return h_clamp(v, min, max, 0); }
331 
332  static constexpr inline int64
334  { return h_clamp(v, min, max, CONST_INT64(0)); }
335 
336  static constexpr inline uint64
337  SYSclamp(uint64 v, uint64 min, uint64 max)
338  { return h_clamp(v, min, max, CONST_UINT64(0)); }
339 
340  static constexpr inline fpreal32
341  SYSclamp(fpreal32 v, fpreal32 min, fpreal32 max, fpreal32 tol=(fpreal32)0)
342  { return h_clamp(v, min, max, tol); }
343 
344  static constexpr inline fpreal64
345  SYSclamp(fpreal64 v, fpreal64 min, fpreal64 max, fpreal64 tol=(fpreal64)0)
346  { return h_clamp(v, min, max, tol); }
347 
348 #undef h_clamp
349 
350 // clamp float to [0, 1]
351 static constexpr inline float SYSclamp01(float v)
352  { return SYSclamp(v, 0.f, 1.f); }
353 static constexpr inline double SYSclamp01(double v)
354  { return SYSclamp(v, 0.0, 1.0); }
355 
356 // clamp float to [0, 1)
357 static constexpr inline float SYSclamp01_excl1(float v)
358  { return SYSclamp(v, 0.f, 1.f - FLT_EPSILON/FLT_RADIX); }
359 static constexpr inline double SYSclamp01_excl1(double v)
360  { return SYSclamp(v, 0.0, 1.0 - DBL_EPSILON/FLT_RADIX); }
361 
362 /// This converts from one integer type to another by clamping
363 /// the range, instead of the usual wrapping.
364 template<typename OUTTYPE,typename INTYPE>
365 constexpr OUTTYPE SYSclampInt(INTYPE value)
366 {
367  value = SYSclamp(value, (INTYPE)std::numeric_limits<OUTTYPE>::min(),
369  return OUTTYPE(value);
370 }
371 
372 // Wrapper for libm math function calls
373 #if defined(LINUX)
374 # define SYS_MF(X) SYS_FastMath::X
375 #else
376 # define SYS_MF(X) ::X
377 #endif
378 
379 #define SYS_UNARY(func) \
380  static inline fpreal64 SYS##func(fpreal64 arg) \
381  { return SYS_MF(func)(arg); } \
382  static inline fpreal32 SYS##func(fpreal32 arg) \
383  { return SYS_MF(func##f)(arg); } \
384  static inline fpreal64 SYS##func(int64 arg) \
385  { return SYS_MF(func)((fpreal64)arg); } \
386  static inline fpreal64 SYS##func(int32 arg) \
387  { return SYS_MF(func)((fpreal64)arg); } \
388  /* end macro */
389 #define SYS_BINARY(func) \
390  static inline fpreal64 SYS##func(fpreal64 a, fpreal64 b) \
391  { return SYS_MF(func)(a,b); } \
392  static inline fpreal32 SYS##func(fpreal32 a, fpreal32 b) \
393  { return SYS_MF(func##f)(a, b); } \
394  /* end macro */
395 
396 #if defined(WIN32)
397 #define hypotf(x,y) hypot((x),(y))
398 #endif
399 
400  SYS_UNARY(sin)
401  SYS_UNARY(cos)
402  SYS_UNARY(tan)
403  SYS_UNARY(sinh)
404  SYS_UNARY(cosh)
405  SYS_UNARY(tanh)
406  SYS_UNARY(sqrt)
407  SYS_UNARY(trunc)
408  SYS_UNARY(exp)
409  SYS_BINARY(fmod)
410  SYS_BINARY(pow)
411  SYS_BINARY(atan2)
412  SYS_BINARY(hypot)
413  SYS_BINARY(copysign)
414 
415 
416 #define SYS_UNARY_PI(func) \
417  static inline fpreal64 SYS##func##pi(fpreal64 arg) \
418  { return SYS##func( SYSfmod(arg, 2.0) * M_PI ); } \
419  static inline fpreal32 SYS##func##pi(fpreal32 arg) \
420  { return SYS##func( SYSfmod(arg, 2.0f) * M_PI ); } \
421  static inline fpreal64 SYS##func##pi(int64 arg) \
422  { return SYS##func( (arg % 2) * M_PI ); } \
423  static inline fpreal32 SYS##func##pi(int32 arg) \
424  { return SYS##func( (arg % 2) * M_PI ); } \
425 /**/
426  SYS_UNARY_PI(sin)
427  SYS_UNARY_PI(cos)
428  SYS_UNARY_PI(tan)
429 #undef SYS_UNARY_PI
430 
431  static constexpr inline fpreal32 SYSsafediv(fpreal32 x, fpreal32 y)
432  { return x/(y != 0 ? y : SYS_Types<fpreal32>::infinity()); }
433  static constexpr inline fpreal64 SYSsafediv(fpreal64 x, fpreal64 y)
434  { return x/(y != 0 ? y : SYS_Types<fpreal64>::infinity()); }
435  static constexpr inline fpreal32 SYSsafesqrt(fpreal32 x)
436  { return x > 0 ? SYSsqrt(x) : 0; }
437  static constexpr inline fpreal64 SYSsafesqrt(fpreal64 x)
438  { return x > 0 ? SYSsqrt(x) : 0; }
439  static constexpr inline fpreal32 SYSsafefmod(fpreal32 x, fpreal32 y)
440  { return y != 0 ? SYSfmod(x, y) : 0; }
441  static constexpr inline fpreal64 SYSsafefmod(fpreal64 x, fpreal64 y)
442  { return y != 0 ? SYSfmod(x, y) : 0; }
443 
444 #if defined(LINUX)
445  static inline void SYSsincos(fpreal32 x, fpreal32 *s, fpreal32 *c)
446  { SYS_MF(sincosf)(x,s,c); }
447  static inline void SYSsincos(fpreal64 x, fpreal64 *s, fpreal64 *c)
448  { SYS_MF(sincos)(x,s,c); }
449  static inline void SYSsincos(fpreal32 x, fpreal16 *s, fpreal16 *c)
450  {
451  fpreal32 s32, c32;
452  SYS_MF(sincosf)(x,&s32,&c32);
453  *s = (fpreal16)s32;
454  *c = (fpreal16)c32;
455  }
456 #elif defined(MBSD)
457  static inline void SYSsincos(fpreal32 x, fpreal32 *s, fpreal32 *c)
458  { __sincosf(x,s,c); }
459  static inline void SYSsincos(fpreal64 x, fpreal64 *s, fpreal64 *c)
460  { __sincos(x,s,c); }
461  static inline void SYSsincos(fpreal32 x, fpreal16 *s, fpreal16 *c)
462  {
463  fpreal32 s32, c32;
464  __sincosf(x,&s32,&c32);
465  *s = (fpreal16)s32;
466  *c = (fpreal16)c32;
467  }
468 #else
469  static inline void SYSsincos(fpreal32 x, fpreal32 *s, fpreal32 *c)
470  { *s = SYSsin(x); *c = SYScos(x); }
471  static inline void SYSsincos(fpreal64 x, fpreal64 *s, fpreal64 *c)
472  { *s = SYSsin(x); *c = SYScos(x); }
473  static inline void SYSsincos(fpreal32 x, fpreal16 *s, fpreal16 *c)
474  { *s = (fpreal16)SYSsin(x); *c = (fpreal16)SYScos(x); }
475 #endif
476 
477 #if 0
478 #include <xmmintrin.h>
479  /// Computes 1/sqrt(x) to about 11.4 bits of accuracy
480  static inline fpreal32 SYSrsqrt11(fpreal32 x)
481  {
482 #if defined(WIN32) || defined(LINUX) || defined(MBSD)
483  union {
484  fpreal32 val;
485  __m128 vec;
486  };
487  val = x;
488  vec = _mm_rsqrt_ss(vec);
489  return val;
490 #else
491  return 1.0f/SYSsqrt(x);
492 #endif
493  }
494 
495  /// Computes 1/sqrt(x) to about 22.2 bits of accuracy
496  static inline fpreal32 SYSrsqrt22(fpreal32 x)
497  {
498 #if defined(WIN32) || defined(LINUX) || defined(MBSD)
499  fpreal32 approximate = SYSrsqrt11(x);
500  // -(((1+e)/sqrt(x))^2 * x - 3) * ((1+e)/sqrt(x)) / 2
501  // -(-1 + e + (e^2)/2) * ((1+e)/sqrt(x))
502  // -(-1 + e + (e^2)/2 - e + e^2 + (e^3)/2) / sqrt(x)
503  // (1 - 3(e^2)/2 - (e^3)/2) / sqrt(x);
504  fpreal32 result = (approximate*approximate*x - 3)*approximate*-0.5f;
505 #else
506  fpreal32 result = 1.0f/SYSsqrt(x);
507 #endif
508  return result;
509  }
510 #endif
511 
512  static inline fpreal32 SYSlog(fpreal32 v) { return v <= 0 ? 0 : SYS_MF(logf)(v); }
513  static inline fpreal64 SYSlog(fpreal64 v) { return v <= 0 ? 0 : SYS_MF(log)(v); }
514  static inline fpreal32 SYSlog10(fpreal32 v) { return v <= 0 ? 0 : SYS_MF(log10f)(v); }
515  static inline fpreal64 SYSlog10(fpreal64 v) { return v <= 0 ? 0 : SYS_MF(log10)(v); }
516 
517 #if defined(WIN32)
518  static inline fpreal32 SYSexpm1(fpreal32 x) { return SYSexp(x) - 1; }
519  static inline fpreal64 SYSexpm1(fpreal64 x) { return SYSexp(x) - 1; }
520  static inline fpreal32 SYSlog1p(fpreal32 x) { return SYSlog(x+1); }
521  static inline fpreal64 SYSlog1p(fpreal64 x) { return SYSlog(x+1); }
522 #else
523  SYS_UNARY(expm1)
524  SYS_UNARY(log1p)
525 #endif
526 
527  // integer log2 (incorrect for 0, gives -1)
528  static inline int32 SYSlog2Int(uint32 x)
529  {
530  // branchless integer log2, http://guihaire.com/code/?p=414
531  if (x == 0)
532  return -1;
533  uint32 r = (x > 0xFFFFu) << 4; x >>= r;
534  uint32 shift = (x > 0xFFu ) << 3; x >>= shift; r |= shift;
535  shift = (x > 0xFu ) << 2; x >>= shift; r |= shift;
536  shift = (x > 0x3u ) << 1;
537  return r | shift | (x >> (shift+1));
538  }
539 
540 #undef SYS_UNARY
541 #undef SYS_BINARY
542 #undef hypotf
543 
544 static inline fpreal32 SYSabs(fpreal32 a) { return SYS_MF(fabsf)(a); }
545 static inline fpreal64 SYSabs(fpreal64 a) { return SYS_MF(fabs)(a); }
546 static inline fpreal32 SYSfabs(fpreal32 a) { return SYS_MF(fabsf)(a); }
547 static inline fpreal64 SYSfabs(fpreal64 a) { return SYS_MF(fabs)(a); }
548 
549 #include "SYS_Floor.h"
550 
551 static inline fpreal32 SYSasin(fpreal32 a)
552  { return SYS_MF(asinf)(SYSclamp(a, (fpreal32)-1, (fpreal32)1)); }
553 static inline fpreal32 SYSacos(fpreal32 a)
554  { return SYS_MF(acosf)(SYSclamp(a, (fpreal32)-1, (fpreal32)1)); }
555 static inline fpreal32 SYSatan(fpreal32 a)
556  { return SYS_MF(atanf)(a); }
557 static inline fpreal32 SYSatan(fpreal32 y, fpreal32 x)
558  { return SYS_MF(atan2f)(y, x); }
559 static inline fpreal64 SYSasin(fpreal64 a)
560  { return SYS_MF(asin) (SYSclamp(a, (fpreal64)-1, (fpreal64)1)); }
561 static inline fpreal64 SYSacos(fpreal64 a)
562  { return SYS_MF(acos) (SYSclamp(a, (fpreal64)-1, (fpreal64)1)); }
563 static inline fpreal64 SYSatan(fpreal64 a)
564  { return SYS_MF(atan) (a); }
565 static inline fpreal64 SYSatan(fpreal64 y, fpreal64 x)
566  { return SYS_MF(atan2)(y, x); }
567 
568 static inline fpreal32 SYSsafepow(fpreal32 x, fpreal32 y)
569  { return x > 0 ? SYSpow(x, y) : x < 0 ? SYSpow(x, SYSrint(y)) : y == 0 ? 1 : 0; }
570 static inline fpreal64 SYSsafepow(fpreal64 x, fpreal64 y)
571  { return x > 0 ? SYSpow(x, y) : x < 0 ? SYSpow(x, SYSrint(y)) : y == 0 ? 1 : 0; }
572 
573 static constexpr inline fpreal32 SYSrecip(fpreal32 a) { return 1 / a; }
574 static constexpr inline fpreal64 SYSrecip(fpreal64 a) { return 1 / a; }
575 static constexpr inline fpreal32 SYSrecip(int32 a) { return 1 / (fpreal32)a; }
576 static constexpr inline fpreal64 SYSrecip(int64 a) { return 1 / (fpreal64)a; }
577 static constexpr inline fpreal32 SYSsaferecip(fpreal32 a)
578  { return SYSsafediv( (fpreal32)1, a ); }
579 static constexpr inline fpreal64 SYSsaferecip(fpreal64 a)
580  { return SYSsafediv( (fpreal64)1, a ); }
581 static constexpr inline fpreal32 SYSsaferecip(int32 a)
582  { return SYSsafediv( (fpreal32)1, (fpreal32)a ); }
583 static constexpr inline fpreal64 SYSsaferecip(int64 a)
584  { return SYSsafediv( (fpreal64)1, (fpreal64)a ); }
585 
586 static constexpr inline fpreal32 SYSdegToRad(fpreal32 a) { return a*(fpreal32)(M_PI/180.0); }
587 static constexpr inline fpreal64 SYSdegToRad(fpreal64 a) { return a*(fpreal64)(M_PI/180.0); }
588 static constexpr inline fpreal64 SYSdegToRad(int32 a) { return a*(fpreal64)(M_PI/180.0); }
589 static constexpr inline fpreal64 SYSdegToRad(int64 a) { return a*(fpreal64)(M_PI/180.0); }
590 
591 static constexpr inline fpreal32 SYSradToDeg(fpreal32 a) { return a*(fpreal32)(180.0/M_PI); }
592 static constexpr inline fpreal64 SYSradToDeg(fpreal64 a) { return a*(fpreal64)(180.0/M_PI); }
593 static constexpr inline fpreal64 SYSradToDeg(int32 a) { return a*(fpreal32)(180.0/M_PI); }
594 static constexpr inline fpreal64 SYSradToDeg(int64 a) { return a*(fpreal64)(180.0/M_PI); }
595 
596 static constexpr inline fpreal32 SYSpow2(fpreal32 a) { return a*a; }
597 static constexpr inline fpreal64 SYSpow2(fpreal64 a) { return a*a; }
598 static constexpr inline fpreal32 SYSpow3(fpreal32 a) { return a*a*a; }
599 static constexpr inline fpreal64 SYSpow3(fpreal64 a) { return a*a*a; }
600 static constexpr inline fpreal32 SYSpow4(fpreal32 a) { return SYSpow2(SYSpow2(a)); }
601 static constexpr inline fpreal64 SYSpow4(fpreal64 a) { return SYSpow2(SYSpow2(a)); }
602 static constexpr inline fpreal32 SYSpow5(fpreal32 a) { return SYSpow4(a) * a; }
603 static constexpr inline fpreal64 SYSpow5(fpreal64 a) { return SYSpow4(a) * a; }
604 
605 #define h_compare(func, code) \
606  static inline bool func(fpreal32 a, fpreal32 b, \
607  fpreal32 tol=SYS_FTOLERANCE) \
608  { return code; } \
609  static inline bool func(fpreal64 a, fpreal64 b, \
610  fpreal64 tol=SYS_FTOLERANCE_D) \
611  { return code; }
612 #define h_compare_ce(func, code) \
613  static constexpr inline bool func(fpreal32 a, fpreal32 b, \
614  fpreal32 tol=SYS_FTOLERANCE) \
615  { return code; } \
616  static constexpr inline bool func(fpreal64 a, fpreal64 b, \
617  fpreal64 tol=SYS_FTOLERANCE_D) \
618  { return code; }
619 
620  static constexpr inline bool
622  { return a >= -tol && a <= tol; }
623 
624  static constexpr inline bool
626  { return a >= -tol && a <= tol; }
627 
628  static constexpr inline bool
630  { return a >= -tol && a <= tol; }
631 
632  static constexpr inline bool
634  { return a >= -tol && a <= tol; }
635 
636  h_compare(SYSisEqual, SYSabs(a-b)<=tol)
637  h_compare_ce(SYSisGreater, (a-b) > tol)
638  h_compare_ce(SYSisGreaterOrEqual, (a-b) >= -tol)
639  h_compare_ce(SYSisLess, (a-b) < -tol)
640  h_compare_ce(SYSisLessOrEqual, (a-b) <= tol)
641 #undef h_compare
642 #undef h_compare_ce
643 
644 constexpr inline bool SYSisEqual(int32 a, int32 b) { return a == b; }
645 constexpr inline bool SYSisEqual(int64 a, int64 b) { return a == b; }
646 constexpr inline bool SYSisGreater(int32 a, int32 b) { return a > b; }
647 constexpr inline bool SYSisGreater(int64 a, int64 b) { return a > b; }
648 constexpr inline bool SYSisGreaterOrEqual(int32 a, int32 b) { return a >= b; }
649 constexpr inline bool SYSisGreaterOrEqual(int64 a, int64 b) { return a >= b; }
650 constexpr inline bool SYSisLess(int32 a, int32 b) { return a < b; }
651 constexpr inline bool SYSisLess(int64 a, int64 b) { return a < b; }
652 constexpr inline bool SYSisLessOrEqual(int32 a, int32 b) { return a <= b; }
653 constexpr inline bool SYSisLessOrEqual(int64 a, int64 b) { return a <= b; }
654 
655 static inline bool
656 SYSalmostEqual(fpreal32 a, fpreal32 b, int ulps=50, fpreal32 tol = 1e-6)
657 {
658  // check if they are absolutely close together (only possible near zero)
659  if (SYSfabs(a - b) <= tol)
660  return true;
661 
662  // we keep the following check in to allow points that are within 1e-15 of
663  // zero to be "equal" for backwards compatibility (so 6e-16 and -6e-16 are
664  // "equal" even though they may not be within 1e-15, for example):
665  // If both double-precision floats are very close to zero, we consider them
666  // equal.
667  if((SYSabs(a) < 1e-6) && (SYSabs(b) < 1e-6))
668  return true;
669 
670  // if they have different signs they are not equal (since they must be at
671  // least tol distance apart by this point, there is no trickiness with +-0)
672  if ((a < 0) != (b < 0))
673  return false;
674 
675  SYS_FPRealUnionF ai, bi;
676  ai.fval = a;
677  bi.fval = b;
678 
679  // find the difference in ulps
680  // We're very careful to avoid signed integer overflow here.
681  if ((ai.uval > bi.uval ? ai.uval - bi.uval : bi.uval - ai.uval) <= ulps)
682  return true;
683 
684  return false;
685 }
686 
687 // adapted from AlmostEqualUlpsAndAbs from:
688 // https://randomascii.wordpress.com/2012/02/25/comparing-floating-point-numbers-2012-edition/
689 static inline bool
690 SYSalmostEqual(fpreal64 a, fpreal64 b, int64 ulps, fpreal64 tol = 1e-15)
691 {
692  // check if they are absolutely close together (only possible near zero)
693  if (SYSfabs(a - b) <= tol)
694  return true;
695 
696  // we keep the following check in to allow points that are within 1e-15 of
697  // zero to be "equal" for backwards compatibility (so 6e-16 and -6e-16 are
698  // "equal" even though they may not be within 1e-15, for example):
699  // If both double-precision floats are very close to zero, we consider them
700  // equal.
701  if((SYSabs(a) < 1e-15) && (SYSabs(b) < 1e-15))
702  return true;
703 
704  // if they have different signs they are not equal (since they must be at
705  // least tol distance apart by this point, there is no trickiness with +-0)
706  if ((a < 0) != (b < 0))
707  return false;
708 
709  SYS_FPRealUnionD ai, bi;
710  ai.fval = a;
711  bi.fval = b;
712 
713  // find the difference in ulps
714  // We're very careful to avoid signed integer overflow here.
715  if ((ai.uval > bi.uval ? ai.uval - bi.uval : bi.uval - ai.uval) <= ulps)
716  return true;
717 
718  return false;
719 }
720 
721 static inline bool
722 SYSalmostEqual(fpreal64 a, fpreal64 b, int32 ulps=50, fpreal64 tol = 1e-15)
723 {
724  return SYSalmostEqual(a, b, (int64)ulps, tol);
725 }
726 
727 static inline bool SYSisInteger(fpreal32 val)
728  { return SYSisEqual(val, SYSfloor(val)) || SYSisEqual(val, SYSceil(val)); }
729 static inline bool SYSisInteger(fpreal64 val)
730  { return SYSisEqual(val, SYSfloor(val)) || SYSisEqual(val, SYSceil(val)); }
731 
732 #define h_max3(type) \
733  static constexpr inline type \
734  SYSmax(type v0, type v1, type v2) { \
735  return SYSmax(v2, SYSmax(v0, v1)); \
736  }
737 #define h_max4(type) \
738  static constexpr inline type \
739  SYSmax(type v0, type v1, type v2, type v3) { \
740  return SYSmax(SYSmax(v0, v1), SYSmax(v2, v3)); \
741  }
742 #define h_argmax3(type) \
743  static constexpr inline int \
744  SYSargmax(type v0, type v1, type v2) { \
745  return v2 > SYSmax(v0, v1) ? 2 : SYSargmax(v0, v1); \
746  }
747 #define h_argmax4(type) \
748  static constexpr inline int \
749  SYSargmax(type v0, type v1, type v2, type v3) { \
750  return SYSmax(v0, v1) < SYSmax(v2, v3) ? \
751  (SYSargmax(v2, v3) + 2) : SYSargmax(v0, v1); \
752  }
753 #define h_min3(type) \
754  static constexpr inline type \
755  SYSmin(type v0, type v1, type v2) { \
756  return SYSmin(v2, SYSmin(v0, v1)); \
757  }
758 #define h_min4(type) \
759  static constexpr inline type \
760  SYSmin(type v0, type v1, type v2, type v3) { \
761  return SYSmin(SYSmin(v0, v1), SYSmin(v2, v3)); \
762  }
763 #define h_argmin3(type) \
764  static constexpr inline int \
765  SYSargmin(type v0, type v1, type v2) { \
766  return v2 < SYSmin(v0, v1) ? 2 : SYSargmin(v0, v1); \
767  }
768 #define h_argmin4(type) \
769  static constexpr inline int \
770  SYSargmin(type v0, type v1, type v2, type v3) { \
771  return SYSmin(v0, v1) > SYSmin(v2, v3) ? \
772  (SYSargmin(v2, v3) + 2) : SYSargmin(v0, v1); \
773  }
774 
775 
776 #define h_max(type) h_min3(type) h_min4(type) h_max3(type) h_max4(type) \
777  h_argmin3(type) h_argmin4(type) \
778  h_argmax3(type) h_argmax4(type)
779 
780 #define h_avg3(type) \
781  static constexpr inline type \
782  SYSavg(type v0, type v1, type v2) { \
783  return (v0+v1+v2) * ((type)(1.0/3.0)); \
784  }
785 #define h_avg4(type) \
786  static constexpr inline type \
787  SYSavg(type v0, type v1, type v2, type v3) { \
788  return (v0+v1+v2+v3) * ((type)0.25); \
789  }
790 
791 #define h_avg(type) h_avg3(type) h_avg4(type)
792 
793 h_max(int8)
794 h_max(uint8)
795 h_max(int16)
796 h_max(uint16)
797 h_max(int32)
798 h_max(uint32)
799 h_max(int64)
800 h_max(uint64)
801 h_max(fpreal32) h_avg(fpreal32)
802 h_max(fpreal64) h_avg(fpreal64)
803 
804 static constexpr inline int32
805 SYSavg(int32 a, int32 b, int32 c)
806 { return (a + b + c + 1) / 3; }
807 static constexpr inline int32
808 SYSavg(int32 a, int32 b, int32 c, int32 d)
809 { return (a + b + c + d + 2) / 4; }
810 
811 static constexpr inline int64
812 SYSavg(int64 a, int64 b, int64 c)
813 { return (a + b + c + 1) / 3; }
814 static constexpr inline int64
815 SYSavg(int64 a, int64 b, int64 c, int64 d)
816 { return (a + b + c + d + 2) / 4; }
817 
818 // Some systems have size_t as a seperate type from uint. Some don't.
819 #if defined(MBSD)
820 h_max(size_t)
821 #endif
822 
823 #undef h_min3
824 #undef h_min4
825 #undef h_max3
826 #undef h_max4
827 #undef h_argmin3
828 #undef h_argmin4
829 #undef h_argmax3
830 #undef h_argmax4
831 #undef h_avg3
832 #undef h_avg4
833 #undef h_max
834 #undef h_avg
835 
836 /// @{
837 /// Linear interpolation between v0 and v1.
838 static constexpr inline fpreal32
840 {
841  return v1 + (v2 - v1)*t;
842 }
843 
844 static constexpr inline fpreal64
846 {
847  return v1 + (v2 - v1)*t;
848 }
849 /// @}
850 
851 /// @{
852 /// Bilinear interpolation over a quadrilateral: @code
853 /// (u=0,v=1) u0v1 u1v1 (u=1,v=1)
854 /// +--------+
855 /// | |
856 /// | |
857 /// +--------+
858 /// (u=0,v=0) u0v0 u1v0 (u=1,v=0)
859 /// @endcode
860 static constexpr inline fpreal32
861 SYSbilerp(fpreal32 u0v0, fpreal32 u1v0, fpreal32 u0v1, fpreal32 u1v1,
862  fpreal32 u, fpreal32 v)
863 {
864  return SYSlerp(SYSlerp(u0v0, u0v1, v), SYSlerp(u1v0, u1v1, v), u);
865 }
866 
867 static constexpr inline fpreal64
868 SYSbilerp(fpreal64 u0v0, fpreal64 u1v0, fpreal64 u0v1, fpreal64 u1v1,
869  fpreal64 u, fpreal64 v)
870 {
871  return SYSlerp(SYSlerp(u0v0, u0v1, v), SYSlerp(u1v0, u1v1, v), u);
872 }
873 /// @}
874 
875 /// @{
876 /// Barycentric coordinates do interpolation over the triangle specified by the
877 /// three vertices (v0, v1, v2): @code
878 /// | (u=0,v=1) |
879 /// | v2 |
880 /// | / \ |
881 /// | / \ |
882 /// | / \ |
883 /// | (u=0,v=0) v0------v1 (u=1,v=0) |
884 /// @endcode
885 static constexpr inline fpreal32
887 {
888  return v0*(1-u-v) + v1*u + v2*v;
889 }
890 
891 static constexpr inline fpreal64
893 {
894  return v0*(1-u-v) + v1*u + v2*v;
895 }
896 /// @}
897 
898 /// @{
899 /// Wrap mod is like mod, but returns [0..b) interval thereby
900 /// usually giving a more useful result.
901 /// This is always defined as safe!
902 /// @}
903 static constexpr inline fpreal32
904 SYSwrapmod(fpreal32 a, fpreal32 b)
905 {
906  fpreal32 r = SYSsafefmod(a, b);
907  return ((a < 0) ^ (b < 0) && r != 0.0f) ? r+b : r;
908 }
909 
910 static constexpr inline fpreal64
911 SYSwrapmod(fpreal64 a, fpreal64 b)
912 {
913  fpreal64 r = SYSsafefmod(a, b);
914  return ((a < 0) ^ (b < 0) && r != 0.0) ? r+b : r;
915 }
916 
917 static constexpr inline int32
918 SYSwrapmod(int32 a, int32 b)
919 {
920  if (b == 0)
921  return 0;
922  int32 r = a % b;
923  return ((a < 0) ^ (b < 0) && r) ? r+b : r;
924 }
925 
926 static constexpr inline int64
927 SYSwrapmod(int64 a, int64 b)
928 {
929  if (b == 0)
930  return 0;
931  int64 r = a % b;
932  return ((a < 0) ^ (b < 0) && r) ? r+b : r;
933 }
934 
935 static constexpr inline fpreal32
936 SYSsmooth(fpreal32 min, fpreal32 max, fpreal32 val)
937 {
938  if (val <= min) return 0;
939  if (val >= max) return 1;
940  fpreal32 t = max - min;
941  if (SYSequalZero(t, (fpreal32)1e-8)) return (fpreal32).5;
942  t = (val - min) / t;
943  return t*t*((fpreal32)3.0 - (fpreal32)2.0*t);
944 }
945 
946 static constexpr inline fpreal64
947 SYSsmooth(fpreal64 min, fpreal64 max, fpreal64 val)
948 {
949  if (val <= min) return 0;
950  if (val >= max) return 1;
951  fpreal64 t = max - min;
952  if (SYSequalZero(t, (fpreal64)1e-18)) return (fpreal64).5;
953  t = (val - min) / t;
954  return t*t*((fpreal64)3.0 - (fpreal64)2.0*t);
955 }
956 
957 static constexpr inline fpreal32
958 SYSsmooth(fpreal32 min, fpreal32 max, fpreal32 value, fpreal32 roll)
959 {
960  if (roll > 0)
961  {
962  fpreal32 f = SYSsmooth(min, max, value);
963  return roll < (fpreal32)1 ? (fpreal32)1-SYSpow((fpreal32)1-f,
964  (fpreal32)1/roll) : SYSpow(f, roll);
965  }
966  return (fpreal32)1;
967 }
968 
969 static constexpr inline fpreal64
970 SYSsmooth(fpreal64 min, fpreal64 max, fpreal64 value, fpreal64 roll)
971 {
972  if (roll > 0)
973  {
974  fpreal64 f = SYSsmooth(min, max, value);
975  return roll < (fpreal64)1 ? (fpreal64)1-SYSpow((fpreal64)1-f,
976  (fpreal64)1/roll) : SYSpow(f, roll);
977  }
978  return (fpreal64)1;
979 }
980 
981 static constexpr inline fpreal32
982 SYSsmoother(fpreal32 min, fpreal32 max, fpreal32 val)
983 {
984  if (val <= min) return 0;
985  if (val >= max) return 1;
986  fpreal32 t = max - min;
987  if (SYSequalZero(t, (fpreal32)1e-8)) return (fpreal32).5;
988  t = (val - min) / t;
989  return t*t*t*(t * ((fpreal32)6.0 * t - (fpreal32)15.0) + (fpreal32)10.0);
990 }
991 
992 static constexpr inline fpreal64
993 SYSsmoother(fpreal64 min, fpreal64 max, fpreal64 val)
994 {
995  if (val <= min) return 0;
996  if (val >= max) return 1;
997  fpreal64 t = max - min;
998  if (SYSequalZero(t, (fpreal64)1e-18)) return (fpreal64).5;
999  t = (val - min) / t;
1000  return t*t*t*(t * ((fpreal64)6.0 * t - (fpreal64)15.0) + (fpreal64)10.0);
1001 }
1002 
1003 static constexpr inline fpreal32
1004 SYSfit(fpreal32 val, fpreal32 omin, fpreal32 omax, fpreal32 nmin, fpreal32 nmax)
1005 {
1006  fpreal32 d = omax - omin;
1007  fpreal32 tmp = (d == 0) ? 0.5f * (nmin+nmax) : SYSlerp(nmin, nmax, (val-omin)/d);
1008  return (d >= 0) ? (val < omin ? nmin : (val > omax ? nmax : tmp))
1009  : (val < omax ? nmax : (val > omin ? nmin : tmp));
1010 }
1011 
1012 static constexpr inline fpreal64
1013 SYSfit(fpreal64 val, fpreal64 omin, fpreal64 omax, fpreal64 nmin, fpreal64 nmax)
1014 {
1015  fpreal64 d = omax - omin;
1016  fpreal64 tmp = (d == 0) ? 0.5 * (nmin+nmax) : SYSlerp(nmin, nmax, (val-omin)/d);
1017  return (d >= 0) ? (val < omin ? nmin : (val > omax ? nmax : tmp))
1018  : (val < omax ? nmax : (val > omin ? nmin : tmp));
1019 }
1020 
1021 /// SYSefit() will not clamp the values to the range
1022 static constexpr inline fpreal32
1023 SYSefit(fpreal32 v, fpreal32 omin, fpreal32 omax, fpreal32 nmin, fpreal32 nmax)
1024 {
1025  fpreal32 d = omax - omin;
1026  return (d == 0) ? 0.5f * (nmin+nmax) : SYSlerp(nmin, nmax, (v-omin)/d);
1027 }
1028 
1029 static constexpr inline fpreal64
1030 SYSefit(fpreal64 v, fpreal64 omin, fpreal64 omax, fpreal64 nmin, fpreal64 nmax)
1031 {
1032  fpreal64 d = omax - omin;
1033  return (d == 0) ? 0.5 * (nmin+nmax) : SYSlerp(nmin, nmax, (v-omin)/d);
1034 }
1035 
1036 static constexpr inline fpreal32
1037 SYSfit01(fpreal32 val, fpreal32 nmin, fpreal32 nmax)
1038 {
1039  if (val < 0) return nmin;
1040  if (val > 1) return nmax;
1041  return SYSlerp(nmin, nmax, val);
1042 }
1043 
1044 static constexpr inline fpreal64
1045 SYSfit01(fpreal64 val, fpreal64 nmin, fpreal64 nmax)
1046 {
1047  if (val < 0) return nmin;
1048  if (val > 1) return nmax;
1049  return SYSlerp(nmin, nmax, val);
1050 }
1051 
1052 /// SYSinvlerp() will produce the bias needed for lerp, but avoid
1053 /// zeros. Essentially built on efit.
1054 static constexpr inline fpreal32
1055 SYSinvlerp(fpreal32 v, fpreal32 omin, fpreal32 omax)
1056 {
1057  return SYSefit(v, omin, omax, 0.0f, 1.0f);
1058 }
1059 
1060 static constexpr inline fpreal64
1061 SYSinvlerp(fpreal64 v, fpreal64 omin, fpreal64 omax)
1062 {
1063  return SYSefit(v, omin, omax, 0.0, 1.0);
1064 }
1065 
1066 // Linear hat function over kernel width dx.
1067 static inline fpreal32
1068 SYShat(fpreal32 x, fpreal32 dx)
1069 {
1070  const fpreal32 ax = SYSabs(x);
1071  return (ax > dx ? 0 : 1 - ax / dx);
1072 }
1073 
1074 static inline fpreal64
1075 SYShat(fpreal64 x, fpreal64 dx)
1076 {
1077  const fpreal64 ax = SYSabs(x);
1078  return (ax > dx ? 0 : 1 - ax / dx);
1079 }
1080 
1081 // Derivative of the linear hat function over kernel width dx.
1082 static constexpr inline fpreal32
1083 SYSdhat(fpreal32 x, fpreal32 dx)
1084 {
1085  return (x < -dx || x > dx ? 0 : -SYSsgn(x) / dx);
1086 }
1087 
1088 static constexpr inline fpreal64
1089 SYSdhat(fpreal64 x, fpreal64 dx)
1090 {
1091  return (x < -dx || x > dx ? 0 : -SYSsgn(x) / dx);
1092 }
1093 
1094 
1095 // For integer types.
1096 template<typename T>
1097 constexpr inline T
1098 SYSroundDownToMultipleOf(T val, T multiple)
1099 {
1100  // Only handle multiples of 2 and up.
1101  if (multiple <= 1)
1102  return val;
1103 
1104  int rem = val % multiple;
1105  if (rem == 0)
1106  return val;
1107 
1108  if (val < 0)
1109  return val - multiple - rem;
1110  else
1111  return val - rem;
1112 }
1113 
1114 template<>
1115 inline fpreal32
1116 SYSroundDownToMultipleOf<fpreal32>(fpreal32 val, fpreal32 multiple)
1117 {
1118  if (SYSequalZero(multiple))
1119  return val;
1120  fpreal32 modulus = SYSfmod(val, multiple);
1121  if (SYSequalZero(modulus) || SYSequalZero(modulus-multiple))
1122  return val;
1123  fpreal32 retval = val - modulus;
1124  if( val < (fpreal32)0 && modulus!=(fpreal32)0 )
1125  retval -= multiple;
1126  return retval;
1127 }
1128 
1129 template<>
1130 inline fpreal64
1131 SYSroundDownToMultipleOf<fpreal64>(fpreal64 val, fpreal64 multiple)
1132 {
1133  if (SYSequalZero(multiple))
1134  return val;
1135  fpreal64 modulus = SYSfmod(val, multiple);
1136  if (SYSequalZero(modulus) || SYSequalZero(modulus-multiple))
1137  return val;
1138  fpreal64 retval = val - modulus;
1139  if( val < (fpreal64)0 && modulus!=(fpreal64)0 )
1140  retval -= multiple;
1141  return retval;
1142 }
1143 
1144 template<typename T>
1145 constexpr inline T
1146 SYSroundUpToMultipleOf(T val, T multiple)
1147 {
1148  // Only handle multiples of 2 and up.
1149  if (multiple <= 1)
1150  return val;
1151 
1152  int rem = val % multiple;
1153  if (rem == 0)
1154  return val;
1155 
1156  if (val < 0)
1157  return val - rem;
1158  else
1159  return val + multiple - rem;
1160 }
1161 
1162 template<>
1163 inline fpreal32
1164 SYSroundUpToMultipleOf<fpreal32>(fpreal32 val, fpreal32 multiple)
1165 {
1166  fpreal32 modulus;
1167  if (SYSequalZero(multiple))
1168  return val;
1169  modulus = SYSfmod(val, multiple);
1170  if (SYSequalZero(modulus) || SYSequalZero(modulus-multiple))
1171  return val;
1172  if (val > (fpreal32)0)
1173  val += multiple;
1174  return val - modulus;
1175 }
1176 
1177 template<>
1178 inline fpreal64
1179 SYSroundUpToMultipleOf<fpreal64>(fpreal64 val, fpreal64 multiple)
1180 {
1181  fpreal64 modulus;
1182  if (SYSequalZero(multiple))
1183  return val;
1184  modulus = SYSfmod(val, multiple);
1185  if (SYSequalZero(modulus) || SYSequalZero(modulus-multiple))
1186  return val;
1187  if (val > (fpreal64)0)
1188  val += multiple;
1189  return val - modulus;
1190 }
1191 
1192 inline constexpr uint32
1193 SYSroundUpPow2(uint32 val)
1194 {
1195  // From http://graphics.stanford.edu/~seander/bithacks.html#RoundUpPowerOf2
1196  uint32 v = val;
1197 
1198  v--;
1199  v |= v >> 1;
1200  v |= v >> 2;
1201  v |= v >> 4;
1202  v |= v >> 8;
1203  v |= v >> 16;
1204  v++;
1205 
1206  return v;
1207 }
1208 
1209 static constexpr inline uint32
1210 SYSwang_inthash(uint32 key)
1211 {
1212  // From http://www.concentric.net/~Ttwang/tech/inthash.htm
1213  key += ~(key << 16);
1214  key ^= (key >> 5);
1215  key += (key << 3);
1216  key ^= (key >> 13);
1217  key += ~(key << 9);
1218  key ^= (key >> 17);
1219  return key;
1220 }
1221 
1222 
1223 static constexpr inline uint32
1224 SYSmultiplicative_inthash(uint32 key)
1225 {
1226  // Multiply by the golden mean of 2^32 (Knuth's multiplicative method) to
1227  // get a uniformly distributed hash value. Do a google search for
1228  // 2654435761 for more information.
1229  return key * 2654435761u;
1230 }
1231 
1232 static constexpr inline uint64
1233 SYSmultiplicative_inthash64(uint64 key)
1234 {
1235  // Same as the 32-bit version above, but using the golden mean of 2^64.
1236  return key * 11400714819323198485llu;
1237 }
1238 
1239 static constexpr inline uint64
1240 SYSwang_inthash64(uint64 key)
1241 {
1242  // From http://www.concentric.net/~Ttwang/tech/inthash.htm
1243  key += ~(key << 32ULL);
1244  key ^= (key >> 22);
1245  key += ~(key << 13);
1246  key ^= (key >> 8);
1247  key += (key << 3);
1248  key ^= (key >> 15);
1249  key += ~(key << 27);
1250  key ^= (key >> 31);
1251  return key;
1252 }
1253 
1254 static constexpr inline uint32
1255 SYSsharpe_inthash(uint32 key)
1256 {
1257  // Based on https://github.com/skeeto/hash-prospector, but with
1258  // modifications such that:
1259  // - bias value of 0.1406800449
1260  // - minimum cycle of 17 (the original algorithm had f(0) == 0)
1261  // - improved dieharder results
1262  key ^= (key >> 16);
1263  key *= 0xdbfb352dU;
1264  key ^= ~(key >> 15);
1265  key *= 0x6c2ca68bU;
1266  key ^= (key >> 16);
1267  return key;
1268 }
1269 
1270 static constexpr inline uint32
1271 SYSwang2_inthash(uint32 key)
1272 {
1273  // From http://www.concentric.net/~Ttwang/tech/inthash.htm
1274  // Updated integer hashing (2007)
1275  constexpr uint c2=0x27d4eb2d; // a prime or an odd constant
1276  key = (key ^ 61) ^ (key >> 16);
1277  key = key + (key << 3);
1278  key = key ^ (key >> 4);
1279  key = key * c2;
1280  key = key ^ (key >> 15);
1281  return key;
1282 }
1283 
1284 static constexpr inline uint64
1285 SYSwang2_inthash(uint64 key)
1286 {
1287  // From http://www.concentric.net/~Ttwang/tech/inthash.htm
1288  // Updated integer hashing (2007)
1289  key = (~key) + (key << 21); // key = (key<<21) - key - 1;
1290  key = key ^ (key >> 24);
1291  key = (key + (key << 3)) + (key << 8); // key * 265
1292  key = key ^ (key >> 14);
1293  key = (key + (key << 2)) + (key << 4); // key * 21
1294  key = key ^ (key >> 28);
1295  key = key + (key << 31);
1296  return key;
1297 }
1298 
1299 static inline uint
1300 SYSreal_hash(fpreal16 a, int lowmask=0x3)
1301 {
1302  return SYSwang_inthash(a.bits() & (~lowmask));
1303 }
1304 
1305 static inline uint
1306 SYSreal_hashseed(fpreal16 a, uint seed, int lowmask=0x3)
1307 {
1308  return SYSwang_inthash(seed + (a.bits() & (~lowmask)));
1309 }
1310 
1311 static inline uint
1312 SYSreal_hash(fpreal32 a, int lowmask=0xf)
1313 {
1314  SYS_FPRealUnionF ai;
1315  ai.fval = a;
1316  return SYSwang_inthash(ai.uval & (~lowmask));
1317 }
1318 
1319 static inline uint
1320 SYSreal_hashseed(fpreal32 a, uint seed, int lowmask=0xf)
1321 {
1322  SYS_FPRealUnionF ai;
1323  ai.fval = a;
1324  return SYSwang_inthash(seed + (ai.uval & (~lowmask)));
1325 }
1326 
1327 static inline uint
1328 SYSreal_hash(fpreal64 a, int lowmask=0xf)
1329 {
1330  SYS_FPRealUnionD ai;
1331  ai.fval = a;
1332  return SYSwang_inthash64(ai.uval & (~lowmask));
1333 }
1334 
1335 static inline uint
1336 SYSreal_hashseed(fpreal64 a, uint seed, int64 lowmask=0xf)
1337 {
1338  SYS_FPRealUnionD ai;
1339  ai.fval = a;
1340  return SYSwang_inthash64(seed + (ai.uval & (~lowmask)));
1341 }
1342 
1343 static constexpr inline uint
1344 SYSvector_hash(const int32 *vector, int size)
1345 {
1346  uint hash = 0;
1347  for (int i = 0; i < size; ++i)
1348  hash = SYSwang_inthash(hash + vector[i]);
1349  return hash;
1350 }
1351 
1352 static constexpr inline uint
1353 SYSvector_hash(const int64 *vector, int size)
1354 {
1355  uint hash = 0;
1356  for (int i = 0; i < size; ++i)
1357  hash = (uint)SYSwang_inthash64(hash + vector[i]);
1358  return hash;
1359 }
1360 
1361 static inline uint
1362 SYSvector_hash(const fpreal16 *vector, int size)
1363 {
1364  uint hash = 0;
1365  for (int i = 0; i < size; ++i)
1366  hash = SYSreal_hashseed(vector[i], hash);
1367  return hash;
1368 }
1369 
1370 static inline uint
1371 SYSvector_hash(const fpreal32 *vector, int size)
1372 {
1373  uint hash = 0;
1374  for (int i = 0; i < size; ++i)
1375  hash = SYSreal_hashseed(vector[i], hash);
1376  return hash;
1377 }
1378 
1379 static inline uint
1380 SYSvector_hash(const fpreal64 *vector, int size)
1381 {
1382  uint hash = 0;
1383  for (int i = 0; i < size; ++i)
1384  hash = SYSreal_hashseed(vector[i], hash);
1385  return hash;
1386 }
1387 
1388 // Spatial hashing function for 3-vectors
1389 // Reference:
1390 // "Optimized Spatial Hashing for Collision Detection of Deformable Objects"
1391 //
1392 template<class P>
1393 static inline size_t
1394 SYSvector3_hash(const P &vector)
1395 {
1396  static constexpr size_t p1 = 73856093;
1397  static constexpr size_t p2 = 19349663;
1398  static constexpr size_t p3 = 83492791;
1399 
1400  return size_t(vector.x()*p1) ^ size_t(vector.y()*p2) ^ size_t(vector.z()*p3);
1401 }
1402 
1403 // Convert a uniform random bit pattern to a random float in the range [0, 1)
1404 inline static fpreal32
1405 SYShashToFloat01(uint hash)
1406 {
1407  SYS_FPRealUnionF tmp;
1408  tmp.uval = 0x3f800000 | (0x007fffff & hash);
1409  return tmp.fval-1.0F;
1410 }
1411 
1412 // Generate a random number in range [0, 1)
1413 static inline fpreal32
1414 SYSfastRandom(uint &seed)
1415 {
1416  seed = seed*1664525 + 1013904223;
1417  return SYShashToFloat01(seed);
1418 }
1419 
1420 inline static fpreal32
1421 SYSrandom(uint &seed)
1422 {
1423  seed = seed*1664525 + 1013904223;
1424  return SYShashToFloat01(SYSwang_inthash(seed));
1425 }
1426 
1427 static constexpr uint
1428 SYSfastRandomInt(uint &seed)
1429 {
1430  seed = seed*1664525 + 1013904223;
1431  return SYSwang_inthash(seed);
1432 }
1433 
1434 inline static fpreal32
1435 SYSfastRandomZero(uint &seed)
1436 {
1437  return SYSfastRandom(seed) - 0.5F;
1438 }
1439 
1440 inline static fpreal32
1441 SYSrandomZero(uint &seed)
1442 {
1443  return SYSrandom(seed) - 0.5F;
1444 }
1445 
1446 template <typename T>
1447 static constexpr inline void
1448 SYSminmax(T v0, T v1, T v2, T v3, T &min, T &max)
1449 {
1450  min = SYSmin(v0, v1, v2, v3);
1451  max = SYSmax(v0, v1, v2, v3);
1452 }
1453 
1454 template <typename T>
1455 static constexpr inline void
1456 SYSminmax(T v0, T v1, T v2, T &min, T &max)
1457 {
1458  min = SYSmin(v0, v1, v2);
1459  max = SYSmax(v0, v1, v2);
1460 }
1461 
1462 template <typename T>
1463 static constexpr inline void
1464 SYSminmax(T v0, T v1, T &min, T &max)
1465 {
1466  min = SYSmin(v0, v1);
1467  max = SYSmax(v0, v1);
1468 }
1469 
1470 SYS_API void SYSsincosDeg(fpreal64 degrees, fpreal64 *s, fpreal64 *c);
1471 SYS_API void SYSsincosDeg(fpreal32 degrees, fpreal32 *s, fpreal32 *c);
1472 
1473 inline static void
1474 SYSgetSinCosFromSlope(fpreal32 slope, fpreal32 &sintheta, fpreal32 &costheta)
1475 {
1476  fpreal32 one_over_m;
1477  sintheta = slope / SYSsqrt(slope*slope + (fpreal32)1);
1478  if ((slope = SYSabs(slope)) > (fpreal32)1)
1479  {
1480  one_over_m = (fpreal32)1 / slope;
1481  costheta = one_over_m / SYSsqrt(one_over_m*one_over_m + 1);
1482  }
1483  else
1484  costheta = SYSsqrt((fpreal32)1 - sintheta*sintheta);
1485 }
1486 
1487 inline static void
1488 SYSgetSinCosFromSlope(fpreal64 slope, fpreal64 &sintheta, fpreal64 &costheta)
1489 {
1490  fpreal64 one_over_m;
1491  sintheta = slope / SYSsqrt(slope*slope + (fpreal64)1);
1492  if ((slope = SYSabs(slope)) > (fpreal64)1)
1493  {
1494  one_over_m = (fpreal64)1 / slope;
1495  costheta = one_over_m / SYSsqrt(one_over_m*one_over_m + 1);
1496  }
1497  else
1498  costheta = SYSsqrt((fpreal64)1 - sintheta*sintheta);
1499 }
1500 
1501 inline constexpr static bool
1502 SYSsameSign( fpreal32 v0, fpreal32 v1 )
1503 {
1504  return (v0*v1)>0;
1505 }
1506 
1507 inline constexpr static bool
1508 SYSsameSign( fpreal64 v0, fpreal64 v1 )
1509 {
1510  return (v0*v1)>0;
1511 }
1512 
1513 inline constexpr static bool
1514 SYSsameSign( int32 v0, int32 v1 )
1515 {
1516  return (v0 ^ v1) >= 0;
1517 }
1518 
1519 inline constexpr static bool
1520 SYSsameSign( int64 v0, int64 v1 )
1521 {
1522  return (v0 ^ v1) >= 0;
1523 }
1524 
1525 static inline uint
1526 SYSnextPrime(uint num)
1527 {
1528  return SYSmakePrime(num+1);
1529 }
1530 
1531 static constexpr inline int
1532 SYShexCharToInt(char c)
1533 {
1534  // Given a hexidecimal character, return it's corresponding value between
1535  // 0 and 15, or -1 if it's not a hexidecimal character.
1536  if (c >= '0' && c <= '9')
1537  return c - '0';
1538  if (c >= 'a' && c <= 'f')
1539  return c - 'a' + 10;
1540  if (c >= 'A' && c <= 'F')
1541  return c - 'A' + 10;
1542  return -1;
1543 }
1544 
1545 static constexpr inline char
1546 SYSintToHexChar(int value)
1547 {
1548  // The value must be from 0-15 for this function to return a valid result.
1549  return value < 10 ? '0' + value : 'a' + value - 10;
1550 }
1551 
1552 SYS_API void SYSsort(int &a, int &b);
1553 SYS_API void SYSsort(int &a, int &b, int &c);
1554 SYS_API void SYSsort(int64 &a, int64 &b);
1555 SYS_API void SYSsort(int64 &a, int64 &b, int64 &c);
1556 SYS_API void SYSsort(float &a, float &b);
1557 SYS_API void SYSsort(float &a, float &b, float &c);
1558 SYS_API void SYSsort(double &a, double &b);
1559 SYS_API void SYSsort(double &a, double &b, double &c);
1560 
1561 // Compute both integer division and integer modulus
1562 // They are compiled into a single instruction
1563 static constexpr inline void
1564 SYSdivMod(int numerator, int denominator, int &quotient, int &remainder)
1565 {
1566  quotient = numerator / denominator;
1567  remainder = numerator % denominator;
1568 }
1569 
1570 static constexpr inline void
1571 SYSdivMod(int64 numerator, int64 denominator, int64 &quotient, int64 &remainder)
1572 {
1573  quotient = numerator / denominator;
1574  remainder = numerator % denominator;
1575 }
1576 
1577 // Include permutations of fpreal32/fpreal64
1578 #include "SYS_MathPermute.h"
1579 #include "SYS_MathRestrictive.h"
1580 
1581 #else /* cplusplus */
1582 #define SYSmax(a,b) ((a) > (b) ? (a) : (b))
1583 #define SYSmin(a,b) ((a) < (b) ? (a) : (b))
1584 #define SYSabs(a) ((a) < 0 ? (a) : -(a))
1585 #endif
1586 
1587 #endif
bool SYSisNormal(fpreal64 f)
Definition: SYS_Math.h:219
SYS_API float acosf(float x)
#define SYSmax(a, b)
Definition: SYS_Math.h:1582
SYS_API double cos(double x)
typedef int(APIENTRYP RE_PFNGLXSWAPINTERVALSGIPROC)(int)
unsigned short uint16
Definition: SYS_Types.h:38
SYS_API double fmod(double x, double y)
SYS_API double atan2(double y, double x)
UT_Vector3T< T > SYSrecip(const UT_Vector3T< T > &v)
Definition: UT_Vector3.h:1083
SYS_API double expm1(double x)
int int32
Definition: SYS_Types.h:39
const GLdouble * v
Definition: glcorearb.h:837
#define M_PI
Definition: fmath.h:98
SYS_API void SYSsrand48(long seed)
GLsizei const GLfloat * value
Definition: glcorearb.h:824
bool SYSisFinite(fpreal64 f)
Definition: SYS_Math.h:201
bool SYSisInf(fpreal64 f)
Definition: SYS_Math.h:210
#define CONST_INT64(x)
Definition: SYS_Types.h:321
bool SYSisInteger(const UT_Vector2T< T > &v1)
Componentwise integer test.
Definition: UT_Vector2.h:93
vfloat4 sqrt(const vfloat4 &a)
Definition: simd.h:7694
OIIO_HOSTDEVICE void sincos(float x, float *sine, float *cosine)
Definition: fmath.h:711
constexpr bool SYSisNan(const F f)
Definition: SYS_Math.h:184
GLboolean GLboolean GLboolean GLboolean a
Definition: glcorearb.h:1222
GLdouble s
Definition: glad.h:3009
#define SYSabs(a)
Definition: SYS_Math.h:1584
SYS_API float atan2f(float y, float x)
ImageBuf OIIO_API min(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
UT_Matrix2T< T > SYSbilerp(const UT_Matrix2T< T > &u0v0, const UT_Matrix2T< T > &u1v0, const UT_Matrix2T< T > &u0v1, const UT_Matrix2T< T > &u1v1, S u, S v)
Bilinear interpolation.
Definition: UT_Matrix2.h:72
GLint y
Definition: glcorearb.h:103
**But if you need a result
Definition: thread.h:622
#define SYS_FTOLERANCE_D
Definition: SYS_Types.h:209
GLfloat GLfloat GLfloat v2
Definition: glcorearb.h:818
UT_Matrix2T< T > SYSlerp(const UT_Matrix2T< T > &v1, const UT_Matrix2T< T > &v2, S t)
Definition: UT_Matrix2.h:675
unsigned long long uint64
Definition: SYS_Types.h:117
GLfloat GLfloat GLfloat GLfloat v3
Definition: glcorearb.h:819
SYS_API double log10(double x)
UT_Matrix2T< T > SYSbarycentric(const UT_Matrix2T< T > &v0, const UT_Matrix2T< T > &v1, const UT_Matrix2T< T > &v2, S u, S v)
Barycentric interpolation.
Definition: UT_Matrix2.h:79
float fpreal32
Definition: SYS_Types.h:200
SYS_API float log10f(float x)
double fpreal64
Definition: SYS_Types.h:201
ImageBuf OIIO_API pow(const ImageBuf &A, cspan< float > B, ROI roi={}, int nthreads=0)
unsigned char uint8
Definition: SYS_Types.h:36
GLfloat f
Definition: glcorearb.h:1926
SYS_API double asin(double x)
IMATH_HOSTDEVICE constexpr int trunc(T x) IMATH_NOEXCEPT
Definition: ImathFun.h:126
SYS_API double sinh(double x)
SYS_API double copysign(double x, double y)
SYS_API float atanf(float x)
SYS_API fpreal32 SYSroundAngle(fpreal32 base, fpreal32 source)
UT_Vector3T< T > SYSclamp(const UT_Vector3T< T > &v, const UT_Vector3T< T > &min, const UT_Vector3T< T > &max)
Definition: UT_Vector3.h:1057
GLsizei GLsizei GLchar * source
Definition: glcorearb.h:803
SYS_API double cosh(double x)
SYS_API bool SYSisPrime(uint num)
SYS_API void sincosf(float x, float *s, float *c)
constexpr int SYSsignum(const F a) noexcept
Definition: SYS_Math.h:176
bool isFinite() const
Definition: fpreal16.h:671
long long int64
Definition: SYS_Types.h:116
SYS_API double SYSdrand48()
SYS_API fpreal32 SYSfloor(fpreal32 val)
UT_Vector2T< T > SYSinvlerp(const UT_Vector2T< T > &a, const UT_Vector2T< T > &v1, const UT_Vector2T< T > &v2)
Componentwise inverse linear interpolation.
Definition: UT_Vector2.h:690
SYS_API float logf(float x)
SYS_API double acos(double x)
signed char int8
Definition: SYS_Types.h:35
SYS_API bool SYSisInt(const char *str)
SYS_API double hypot(double x, double y)
GLboolean GLboolean GLboolean b
Definition: glcorearb.h:1222
GLint GLenum GLint x
Definition: glcorearb.h:409
bool isInfinity() const
Definition: fpreal16.h:712
fpreal32 SYSrint(fpreal32 val)
Definition: SYS_Floor.h:163
GLdouble t
Definition: glad.h:2397
SYS_API double log1p(double x)
GLfloat v0
Definition: glcorearb.h:816
SYS_API double tanh(double x)
bool SYSequalZero(const UT_Vector3T< T > &v)
Definition: UT_Vector3.h:1069
SYS_API uint SYSmakePrime(uint num)
GLsizeiptr size
Definition: glcorearb.h:664
SYS_API double tan(double x)
short int16
Definition: SYS_Types.h:37
SYS_API double atan(double x)
GLfloat GLfloat v1
Definition: glcorearb.h:817
GLuint GLfloat * val
Definition: glcorearb.h:1608
ImageBuf OIIO_API max(Image_or_Const A, Image_or_Const B, ROI roi={}, int nthreads=0)
bool isNan() const
Definition: fpreal16.h:703
unsigned int uint32
Definition: SYS_Types.h:40
SYS_API float asinf(float x)
#define SYS_FTOLERANCE
Definition: SYS_Types.h:208
#define SYS_API
Definition: SYS_API.h:11
#define CONST_UINT64(x)
Definition: SYS_Types.h:322
GLboolean r
Definition: glcorearb.h:1222
unsigned short bits() const
Definition: fpreal16.h:764
OIIO_FORCEINLINE T log(const T &v)
Definition: simd.h:7905
bool SYSisEqual(const UT_Vector2T< T > &a, const UT_Vector2T< T > &b, S tol=SYS_FTOLERANCE)
Componentwise equality.
Definition: UT_Vector2.h:674
#define SYSmin(a, b)
Definition: SYS_Math.h:1583
SYS_API bool SYSisFloat(const char *str)
unsigned int uint
Definition: SYS_Types.h:45
SYS_API double sin(double x)
SYS_API fpreal32 SYSceil(fpreal32 val)
bool isNormalized() const
Definition: fpreal16.h:679
OIIO_FORCEINLINE OIIO_HOSTDEVICE T degrees(T rad)
Convert radians to degrees.
Definition: fmath.h:681