Hermes
numeric.h
Go to the documentation of this file.
1 
32 #ifndef HERMES_GEOMETRY_CUDA_NUMERIC_H
33 #define HERMES_GEOMETRY_CUDA_NUMERIC_H
34 
35 #include <hermes/common/debug.h>
36 #include <hermes/common/defs.h>
37 #include <algorithm>
38 #include <cmath>
39 #include <functional>
40 #include <vector>
41 #include <cstring>
42 
43 namespace hermes {
44 
45 // *********************************************************************************************************************
46 // Constants
47 // *********************************************************************************************************************
49 struct Constants {
50  // *******************************************************************************************************************
51  // STATIC FIELDS
52  // *******************************************************************************************************************
53  static constexpr real_t pi = 3.14159265358979323846;
54  static constexpr real_t two_pi = 6.28318530718;
55  static constexpr real_t inv_pi = 0.31830988618379067154;
56  static constexpr real_t inv_two_pi = 0.15915494309189533577;
57  static constexpr real_t inv_four_pi = 0.07957747154594766788;
58  static constexpr real_t pi_over_four = 0.78539816339;
59  static constexpr real_t pi_over_two = 1.57079632679;
60  static constexpr real_t machine_epsilon = std::numeric_limits<real_t>::epsilon() * .5;
61  static constexpr real_t real_infinity = std::numeric_limits<real_t>::max();
62  static constexpr f64 f64_one_minus_epsilon = 0x1.fffffffffffffp-1;
63  static constexpr f32 f32_one_minus_epsilon = 0x1.fffffep-1;
64 #ifdef HERMES_USE_DOUBLE_AS_DEFAULT
65  static constexpr real_t one_minus_epsilon = f64_one_minus_epsilon;
66 #else
67  static constexpr real_t one_minus_epsilon = f32_one_minus_epsilon;
68 #endif
69 };
70 
71 // *********************************************************************************************************************
72 // Numbers
73 // *********************************************************************************************************************
75 struct Numbers {
76  // limits
80  HERMES_DEVICE_CALLABLE static constexpr f64 lowest_f64() {
81  return -0x1.fffffffffffffp+1023;
82  }
86  HERMES_DEVICE_CALLABLE static constexpr f32 lowest_f32() {
87  return -0x1.fffffep+127;
88  }
92  template<typename T> HERMES_DEVICE_CALLABLE static constexpr T lowest() {
93  return T(lowest_f32());
94  }
98  return 0x1.fffffep+127;
99  }
103  return 0x1.fffffffffffffp+1023;
104  }
108  template<typename T> HERMES_DEVICE_CALLABLE static constexpr T greatest() {
109  return T(greatest_f32());
110  }
111  // queries
117  template<typename T> HERMES_DEVICE_CALLABLE static constexpr T min(const T &a, const T &b) {
118  if (a < b)
119  return a;
120  return b;
121  }
127  template<typename T> HERMES_DEVICE_CALLABLE static constexpr T max(const T &a, const T &b) {
128  if (a > b)
129  return a;
130  return b;
131  }
136  template<typename T>
137  HERMES_DEVICE_CALLABLE static inline constexpr T min(std::initializer_list<T> l) {
138  T m = *l.begin();
139  for (auto n : l)
140  if (m > n)
141  m = n;
142  return m;
143  }
148  template<typename T>
149  HERMES_DEVICE_CALLABLE static inline constexpr T max(std::initializer_list<T> l) {
150  T m = *l.begin();
151  for (auto n : l)
152  if (m < n)
153  m = n;
154  return m;
155  }
160  template<typename T>
162  u8 count = 0;
163  while (n) {
164  count++;
165  n >>= 4;
166  }
167  return count;
168  }
169  // rounding
175  template<typename T>
176  HERMES_DEVICE_CALLABLE static T clamp(const T &n, const T &l, const T &u) {
177  return fmaxf(l, fminf(n, u));
178  }
179  // functions
184  template<typename T> HERMES_DEVICE_CALLABLE static void swap(T &a, T &b) {
185  T tmp = a;
186  a = b;
187  b = tmp;
188  }
192  template<typename T> HERMES_DEVICE_CALLABLE static constexpr T sqr(T a) { return a * a; }
197  template<typename T> HERMES_DEVICE_CALLABLE static constexpr T cube(T a) { return a * a * a; }
202  template<typename T> HERMES_DEVICE_CALLABLE static int sign(T a) {
203  return a >= 0 ? 1 : -1;
204  }
209  template<typename T> HERMES_DEVICE_CALLABLE static constexpr T sqrt(T a) {
210 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
211  return sqrtf(a);
212 #else
213  return std::sqrt(a);
214 #endif
215  }
222  template<typename T> HERMES_DEVICE_CALLABLE static inline T FMA(T a, T b, T c) {
223  return a * b + c;
224  }
235  template<typename Ta, typename Tb, typename Tc, typename Td>
236  HERMES_DEVICE_CALLABLE static inline auto differenceOfProducts(Ta a, Tb b, Tc c, Td d) {
237  auto cd = c * d;
238  auto difference_of_products = FMA(a, b, -cd);
239  auto error = FMA(-c, d, cd);
240  return difference_of_products + error;
241  }
248  template<typename T, typename C>
249  HERMES_DEVICE_CALLABLE static inline constexpr T evaluatePolynomial(T t, C c) {
251  return c;
252  }
261  template<typename T, typename C, typename... Args>
262  HERMES_DEVICE_CALLABLE static inline constexpr T evaluatePolynomial(T t, C c, Args... cs) {
263  return FMA(t, evaluatePolynomial(t, cs...), c);
264  }
270  template<typename Predicate>
271  HERMES_DEVICE_CALLABLE static inline size_t findInterval(size_t sz, const Predicate &pred) {
272  using ssize_t = std::make_signed_t<size_t>;
273  ssize_t size = (ssize_t) sz - 2, first = 1;
274  while (size > 0) {
275  size_t half = (size_t) size >> 1, middle = first + half;
276  bool predResult = pred(middle);
277  first = predResult ? middle + 1 : first;
278  size = predResult ? size - (half + 1) : half;
279  }
280  return (size_t) clamp<ssize_t>((ssize_t) first - 1, 0, sz - 2);
281  }
282  // *******************************************************************************************************************
283  // BINARY
284  // *******************************************************************************************************************
285  // integer
290  n = (n ^ (n << 8)) & 0x00ff00ff;
291  n = (n ^ (n << 4)) & 0x0f0f0f0f;
292  n = (n ^ (n << 2)) & 0x33333333;
293  n = (n ^ (n << 1)) & 0x55555555;
294  return n;
295  }
300  n = (n ^ (n << 16)) & 0xff0000ff;
301  n = (n ^ (n << 8)) & 0x0300f00f;
302  n = (n ^ (n << 4)) & 0x030c30c3;
303  n = (n ^ (n << 2)) & 0x09249249;
304  return n;
305  }
312  return (separateBitsBy2(z) << 2) + (separateBitsBy2(y) << 1) +
313  separateBitsBy2(x);
314  }
320  return (separateBitsBy1(y) << 1) + separateBitsBy1(x);
321  }
322  // float
326  HERMES_DEVICE_CALLABLE static inline int floatExponent(f32 v) {
327  return (floatToBits(v) >> 23) - 127;
328  }
333  return floatToBits(v) & ((1 << 23) - 1);
334  }
338  HERMES_DEVICE_CALLABLE static inline uint32_t floatSignBit(f32 v) {
339  return floatToBits(v) & 0x80000000;
340  }
344  HERMES_DEVICE_CALLABLE static inline uint32_t floatToBits(f32 f) {
345 #if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ > 0))
346  return __float_as_uint(f);
347 #else
348  uint32_t ui(0);
349  std::memcpy(&ui, &f, sizeof(f32));
350  return ui;
351 #endif
352  }
356  HERMES_DEVICE_CALLABLE static inline f32 bitsToFloat(uint32_t ui) {
357 #if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ > 0))
358  return __uint_as_float(ui);
359 #else
360  f32 f(0.f);
361  std::memcpy(&f, &ui, sizeof(uint32_t));
362  return f;
363 #endif
364  }
368  HERMES_DEVICE_CALLABLE static inline uint64_t floatToBits(f64 d) {
369  uint64_t ui(0);
370 #if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ > 0))
371  memcpy(&ui, &d, sizeof(f64));
372 #else
373  std::memcpy(&ui, &d, sizeof(f64));
374 #endif
375  return ui;
376  }
380  HERMES_DEVICE_CALLABLE static inline f64 bitsToDouble(uint64_t ui) {
381  f64 d(0.f);
382 #if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ > 0))
383  memcpy(&d, &ui, sizeof(uint64_t));
384 #else
385  std::memcpy(&d, &ui, sizeof(uint64_t));
386 #endif
387  return d;
388  }
393 #if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ > 0))
394  if (isinf(v) && v > 0.)
395 #else
396  if (std::isinf(v) && v > 0.f)
397 #endif
398  return v;
399  if (v == -0.f)
400  v = 0.f;
401  uint32_t ui = floatToBits(v);
402  if (v >= 0)
403  ++ui;
404  else
405  --ui;
406  return bitsToFloat(ui);
407  }
412 #if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ > 0))
413  if (isinf(v) && v > 0.)
414 #else
415  if (std::isinf(v) && v > 0.f)
416 #endif
417  return v;
418  if (v == 0.f)
419  v = -0.f;
420  uint32_t ui = floatToBits(v);
421  if (v > 0)
422  --ui;
423  else
424  ++ui;
425  return bitsToFloat(ui);
426  }
431 #if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ > 0))
432  if (isinf(v) && v > 0.)
433 #else
434  if (std::isinf(v) && v > 0.)
435 #endif
436  return v;
437  if (v == -0.f)
438  v = 0.f;
439  uint64_t ui = floatToBits(v);
440  if (v >= 0)
441  ++ui;
442  else
443  --ui;
444  return bitsToDouble(ui);
445  }
450 #if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ > 0))
451  if (isinf(v) && v > 0.)
452 #else
453  if (std::isinf(v) && v > 0.)
454 #endif
455  return v;
456  if (v == 0.)
457  v = -0.f;
458  uint64_t ui = floatToBits(v);
459  if (v > 0)
460  --ui;
461  else
462  ++ui;
463  return bitsToDouble(ui);
464  }
465  // *******************************************************************************************************************
466  // INTEGER
467  // *******************************************************************************************************************
468  // limits
471  HERMES_DEVICE_CALLABLE static constexpr int lowest_int() { return -2147483647; }
474  HERMES_DEVICE_CALLABLE static constexpr int greatest_int() { return 2147483647; }
478  HERMES_DEVICE_CALLABLE static constexpr inline bool isPowerOf2(int v) { return (v & (v - 1)) == 0; }
483  HERMES_DEVICE_CALLABLE static inline int mod(int a, int b) {
484  int n = a / b;
485  a -= n * b;
486  if (a < 0)
487  a += b;
488  return a;
489  }
490  // rounding
494  HERMES_DEVICE_CALLABLE static inline int ceil2Int(float f) { return static_cast<int>(f + 0.5f); }
498  HERMES_DEVICE_CALLABLE static inline int floor2Int(float f) { return static_cast<int>(f); }
502  HERMES_DEVICE_CALLABLE static inline int round2Int(float f) { return f + .5f; }
503  // rounding
508  HERMES_DEVICE_CALLABLE static inline u8 countDigits(u64 t, u8 base = 10) {
509  u8 count{0};
510  while (t) {
511  count++;
512  t /= base;
513  }
514  return count;
515  }
516 
517  // *******************************************************************************************************************
518  // FLOATING POINT
519  // *******************************************************************************************************************
520  // rounding
525  if (x >= 0.)
526  return x - floor(x);
527  else
528  return x - ceil(x);
529  }
535 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
536 #ifdef HERMES_USE_DOUBLE_AS_DEFAULT
537  return __dmul_rd(a, b);
538 #else
539  return __fmul_rd(a, b);
540 #endif
541 #else
542  return nextFloatDown(a * b);
543 #endif
544  }
550 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
551 #ifdef HERMES_USE_DOUBLE_AS_DEFAULT
552  return __dmul_ru(a, b);
553 #else
554  return __fmul_ru(a, b);
555 #endif
556 #else
557  return nextFloatUp(a * b);
558 #endif
559  }
565 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
566 #ifdef HERMES_USE_DOUBLE_AS_DEFAULT
567  return __ddiv_rd(a, b);
568 #else
569  return __fdiv_rd(a, b);
570 #endif
571 #else
572  return nextFloatDown(a / b);
573 #endif
574  }
580 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
581 #ifdef HERMES_USE_DOUBLE_AS_DEFAULT
582  return __ddiv_ru(a, b);
583 #else
584  return __fdiv_ru(a, b);
585 #endif
586 #else
587  return nextFloatUp(a / b);
588 #endif
589  }
595 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
596 #ifdef HERMES_USE_DOUBLE_AS_DEFAULT
597  return __dadd_rd(a, b);
598 #else
599  return __fadd_rd(a, b);
600 #endif
601 #else
602  return nextFloatDown(a + b);
603 #endif
604  }
610 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
611 #ifdef HERMES_USE_DOUBLE_AS_DEFAULT
612  return __dadd_ru(a, b);
613 #else
614  return __fadd_ru(a, b);
615 #endif
616 #else
617  return nextFloatUp(a + b);
618 #endif
619  }
625 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
626 #ifdef HERMES_USE_DOUBLE_AS_DEFAULT
627  return __dsub_rd(a, b);
628 #else
629  return __fsub_rd(a, b);
630 #endif
631 #else
632  return nextFloatDown(a - b);
633 #endif
634  }
640 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
641 #ifdef HERMES_USE_DOUBLE_AS_DEFAULT
642  return __dsub_ru(a, b);
643 #else
644  return __fsub_ru(a, b);
645 #endif
646 #else
647  return nextFloatUp(a - b);
648 #endif
649  }
654 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
655 #ifdef HERMES_USE_DOUBLE_AS_DEFAULT
656  return __dsqrt_rd(a);
657 #else
658  return __fsqrt_rd(a);
659 #endif
660 #else
661  return max<real_t>(0, nextFloatDown(std::sqrt(a)));
662 #endif
663  }
668 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
669 #ifdef HERMES_USE_DOUBLE_AS_DEFAULT
670  return __dsqrt_ru(a);
671 #else
672  return __fsqrt_ru(a);
673 #endif
674 #else
675  return nextFloatUp(std::sqrt(a));
676 #endif
677  }
678  // functions
682  HERMES_DEVICE_CALLABLE static inline f32 log2(f32 x) {
683 #ifndef HERMES_DEVICE_ENABLED
684  static f32 invLog2 = 1.f / logf(2.f);
685 #else
686  f32 invLog2 = 1.f / logf(2.f);
687 #endif
688  return logf(x) * invLog2;
689  }
694  HERMES_CHECK_EXP(x >= -1e-3f)
695 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
696  return sqrtf(fmaxf(0.f, x));
697 #else
698  return std::sqrt(std::max(0.f, x));
699 #endif
700  }
705  template<int n>
706  HERMES_DEVICE_CALLABLE static inline constexpr real_t pow(real_t b) {
707  if constexpr (n < 0)
708  return 1 / pow<-n>(b);
709  float n2 = pow<n / 2>(b);
710  return n2 * n2 * pow<n & 1>(b);
711  }
716 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
717  return __expf(x);
718 #else
719  // Compute $x'$ such that $\roman{e}^x = 2^{x'}$
720  float xp = x * 1.442695041f;
721 
722  // Find integer and fractional components of $x'$
723  float fxp = std::floor(xp), f = xp - fxp;
724  int i = (int) fxp;
725 
726  // Evaluate polynomial approximation of $2^f$
727  float twoToF = evaluatePolynomial(f, 1.f, 0.695556856f, 0.226173572f, 0.0781455737f);
728 
729  // Scale $2^f$ by $2^i$ and return final result
730  int exponent = floatExponent(twoToF) + i;
731  if (exponent < -126)
732  return 0;
733  if (exponent > 127)
734  return Constants::real_infinity;
735  uint32_t bits = floatToBits(twoToF);
736  bits &= 0b10000000011111111111111111111111u;
737  bits |= (exponent + 127) << 23;
738  return bitsToFloat(bits);
739 #endif
740  }
741  // *******************************************************************************************************************
742  // ERROR
743  // *******************************************************************************************************************
747  HERMES_DEVICE_CALLABLE static constexpr real_t gamma(i32 n) {
748  return (n * Constants::machine_epsilon) / (1 - n * Constants::machine_epsilon);
749  }
750 };
753 template<> HERMES_DEVICE_CALLABLE inline constexpr f64 Numbers::lowest() {
754  return Numbers::lowest_f64();
755 }
758 template<> HERMES_DEVICE_CALLABLE inline constexpr f32 Numbers::lowest() {
759  return Numbers::lowest_f32();
760 }
764 template<>
765 HERMES_DEVICE_CALLABLE inline constexpr float Numbers::pow<1>(float v) {
767  return v;
768 }
772 template<>
773 HERMES_DEVICE_CALLABLE inline constexpr float Numbers::pow<0>(float v) {
775  return 1;
776 }
779 template<> HERMES_DEVICE_CALLABLE inline constexpr f32 Numbers::greatest() {
780  return greatest_f32();
781 }
784 template<> HERMES_DEVICE_CALLABLE inline constexpr f64 Numbers::greatest() {
785  return greatest_f64();
786 }
787 // *********************************************************************************************************************
788 // Trigonometry
789 // *********************************************************************************************************************
791 struct Trigonometry {
792  // *******************************************************************************************************************
793  // STATIC METHODS
794  // *******************************************************************************************************************
799  return a * 180.f / Constants::pi;
800  }
805  return a * Constants::pi / 180.f;
806  }
811  return std::acos(Numbers::clamp<f32>(x, -1, 1));
812  }
817  return std::asin(Numbers::clamp<f32>(x, -1, 1));
818  }
819 };
820 
821 // *********************************************************************************************************************
822 // Check
823 // *********************************************************************************************************************
825 struct Check {
826  // *******************************************************************************************************************
827  // STATIC METHODS
828  // *******************************************************************************************************************
833  template<typename T>
834  HERMES_DEVICE_CALLABLE static constexpr bool is_zero(T a) {
835 #if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ > 0))
836  return fabs(a) < 1e-8;
837 #else
838  return std::fabs(a) < 1e-8;
839 #endif
840  }
846  template<typename T>
847  HERMES_DEVICE_CALLABLE static constexpr bool is_equal(T a, T b) {
848  return fabs(a - b) < 1e-8;
849  }
856  template<typename T>
857  HERMES_DEVICE_CALLABLE static constexpr bool is_equal(T a, T b, T e) {
858  return fabs(a - b) < e;
859  }
866  template<typename T> static constexpr bool is_between(T x, T a, T b) {
867  return x > a && x < b;
868  }
875  template<typename T> static constexpr bool is_between_closed(T x, T a, T b) {
876  return x >= a && x <= b;
877  }
882  template<typename T>
883  HERMES_DEVICE_CALLABLE static inline typename std::enable_if_t<std::is_floating_point<T>::value, bool>
884  is_nan(T v) {
885 #if defined(__CUDA_ARCH__) && __CUDA_ARCH__ > 0
886  return isnan(v);
887 #else
888  return std::isnan(v);
889 #endif
890  }
891 
892 };
893 
894 namespace numeric {
895 
903 template<typename T>
904 HERMES_DEVICE_CALLABLE bool soveLinearSystem(const T A[2][2], const T B[2], T *x0, T *x1) {
905  T det = A[0][0] * A[1][1] - A[0][1] * A[1][0];
906  if (abs(det) < 1e-10f)
907  return false;
908  *x0 = (A[1][1] * B[0] - A[0][1] * B[1]) / det;
909  *x1 = (A[0][0] * B[1] - A[1][0] * B[0]) / det;
910 #if (defined(__CUDA_ARCH__) && (__CUDA_ARCH__ > 0))
911  if(isnan(*x0) || isnan(*x1))
912  return false;
913 #else
914  if (std::isnan(*x0) || std::isnan(*x1))
915  return false;
916 #endif
917  return true;
918 }
919 
920 }
921 //
922 //template<typename T>
923 //__device__ __host__ unsigned int mortonCode(const Point3 <T> &v) {
924 // return interleaveBits(v[0], v[1], v[2]);
925 //}
926 //
927 //template<typename T>
928 //__device__ __host__ unsigned int mortonCode(const Point2 <T> &v) {
929 // return interleaveBits(v[0], v[1]);
930 //}
931 
932 } // namespace hermes
933 
934 #endif
935 
Debug, logging and assertion macros.
Data type definitions.
uint64_t u64
64 bit size unsigned integer type
Definition: defs.h:89
#define HERMES_UNUSED_VARIABLE(x)
Specifies that variable is not used in this scope.
Definition: debug.h:62
float real_t
default floating point type
Definition: defs.h:75
#define HERMES_DEVICE_CALLABLE
Specifies that the function can be called from both host and device sides.
Definition: defs.h:45
uint32_t u32
32 bit size unsigned integer type
Definition: defs.h:88
uint8_t u8
8 bit size unsigned integer type
Definition: defs.h:86
double f64
64 bit size floating point type
Definition: defs.h:79
float f32
32 bit size floating point type
Definition: defs.h:78
#define HERMES_CHECK_EXP(expr)
Warns if expression is false.
Definition: debug.h:95
int32_t i32
32 bit size integer type
Definition: defs.h:83
@ error
logs into error stream
HERMES_DEVICE_CALLABLE Normal3< T > abs(const Normal3< T > &normal)
Computes absolute normal components.
Definition: normal.h:212
HERMES_DEVICE_CALLABLE bool soveLinearSystem(const T A[2][2], const T B[2], T *x0, T *x1)
Solves a linear system of 2 equations.
Definition: numeric.h:904
Number checks.
Definition: numeric.h:825
static constexpr HERMES_DEVICE_CALLABLE bool is_equal(T a, T b, T e)
Checks if two numbers are at most to a threshold apart.
Definition: numeric.h:857
static constexpr bool is_between(T x, T a, T b)
Checks if a number is in a open interval.
Definition: numeric.h:866
static constexpr bool is_between_closed(T x, T a, T b)
Checks if a number is in a closed interval.
Definition: numeric.h:875
static constexpr HERMES_DEVICE_CALLABLE bool is_zero(T a)
Checks if number is 0.
Definition: numeric.h:834
static HERMES_DEVICE_CALLABLE std::enable_if_t< std::is_floating_point< T >::value, bool > is_nan(T v)
Checks if number representation is nan
Definition: numeric.h:884
static constexpr HERMES_DEVICE_CALLABLE bool is_equal(T a, T b)
Checks if two numbers are at most 1e-8 apart.
Definition: numeric.h:847
Numeric constants.
Definition: numeric.h:49
Number functions.
Definition: numeric.h:75
static HERMES_DEVICE_CALLABLE f32 nextFloatUp(f32 v)
Computes the next greater representable floating-point value.
Definition: numeric.h:392
static HERMES_DEVICE_CALLABLE real_t addRoundDown(real_t a, real_t b)
Adds and rounds down to the next smaller float value.
Definition: numeric.h:594
static constexpr HERMES_DEVICE_CALLABLE T min(const T &a, const T &b)
Computes minimum between two numbers.
Definition: numeric.h:117
static HERMES_DEVICE_CALLABLE f64 nextDoubleUp(f64 v)
Computes the next greater representable floating-point value.
Definition: numeric.h:430
static HERMES_DEVICE_CALLABLE real_t subRoundUp(real_t a, real_t b)
Subtracts and rounds up to the next float value.
Definition: numeric.h:639
static HERMES_DEVICE_CALLABLE void swap(T &a, T &b)
Swaps values.
Definition: numeric.h:184
static constexpr HERMES_DEVICE_CALLABLE T evaluatePolynomial(T t, C c)
Solves polynomial.
Definition: numeric.h:249
static HERMES_DEVICE_CALLABLE real_t divRoundUp(real_t a, real_t b)
Divides and rounds up to the next float value.
Definition: numeric.h:579
static HERMES_DEVICE_CALLABLE int floatSignificand(f32 v)
Extracts significand bits.
Definition: numeric.h:332
static constexpr HERMES_DEVICE_CALLABLE f64 greatest_f32()
Gets greatest representable 32 bit floating point.
Definition: numeric.h:97
static constexpr HERMES_DEVICE_CALLABLE real_t pow(real_t b)
Computes b to the power of n.
Definition: numeric.h:706
static constexpr HERMES_DEVICE_CALLABLE T sqrt(T a)
Computes square root.
Definition: numeric.h:209
static HERMES_DEVICE_CALLABLE real_t divRoundDown(real_t a, real_t b)
Divides and rounds down to the next smaller float value.
Definition: numeric.h:564
static constexpr HERMES_DEVICE_CALLABLE real_t gamma(i32 n)
Computes conservative bounds in error.
Definition: numeric.h:747
static HERMES_DEVICE_CALLABLE auto differenceOfProducts(Ta a, Tb b, Tc c, Td d)
Computes difference of products.
Definition: numeric.h:236
static constexpr HERMES_DEVICE_CALLABLE T greatest()
Gets greatest representable floating point.
Definition: numeric.h:108
static HERMES_DEVICE_CALLABLE real_t fract(real_t x)
Extract decimal fraction from x.
Definition: numeric.h:524
static HERMES_DEVICE_CALLABLE uint64_t floatToBits(f64 d)
Interprets a f64-point value into a integer type.
Definition: numeric.h:368
static HERMES_DEVICE_CALLABLE f32 bitsToFloat(uint32_t ui)
Fills a f32 variable data.
Definition: numeric.h:356
static constexpr HERMES_DEVICE_CALLABLE T cube(T a)
Computes square.
Definition: numeric.h:197
static HERMES_DEVICE_CALLABLE T FMA(T a, T b, T c)
Computes a * b + c.
Definition: numeric.h:222
static HERMES_DEVICE_CALLABLE T clamp(const T &n, const T &l, const T &u)
Clamps value to closed interval.
Definition: numeric.h:176
static HERMES_DEVICE_CALLABLE int sign(T a)
Computes sign.
Definition: numeric.h:202
static HERMES_DEVICE_CALLABLE u8 countHexDigits(T n)
Counts hexadecimal digits.
Definition: numeric.h:161
static constexpr HERMES_DEVICE_CALLABLE T min(std::initializer_list< T > l)
Computes minimum value from input.
Definition: numeric.h:137
static HERMES_DEVICE_CALLABLE real_t fastExp(real_t x)
Computes fast exponential.
Definition: numeric.h:715
static HERMES_DEVICE_CALLABLE f64 bitsToDouble(uint64_t ui)
Fills a f64 variable data.
Definition: numeric.h:380
static HERMES_DEVICE_CALLABLE real_t mulRoundUp(real_t a, real_t b)
Multiplies and rounds up to the next float value.
Definition: numeric.h:549
static HERMES_DEVICE_CALLABLE int floatExponent(f32 v)
Extracts exponent from floating-point number.
Definition: numeric.h:326
static HERMES_DEVICE_CALLABLE u32 interleaveBits(u32 x, u32 y)
Interleaves bits of two integers.
Definition: numeric.h:319
static HERMES_DEVICE_CALLABLE f64 nextDoubleDown(f64 v)
Computes the next smaller representable floating-point value.
Definition: numeric.h:449
static constexpr HERMES_DEVICE_CALLABLE int lowest_int()
Gets minimum representable 32 bit signed integer.
Definition: numeric.h:471
static HERMES_DEVICE_CALLABLE u32 separateBitsBy2(u32 n)
Separate bits by 2 bit-spaces.
Definition: numeric.h:299
static constexpr HERMES_DEVICE_CALLABLE f32 lowest_f32()
Gets lowest representable 64 bit floating point.
Definition: numeric.h:86
static HERMES_DEVICE_CALLABLE real_t addRoundUp(real_t a, real_t b)
Adds and rounds up to the next float value.
Definition: numeric.h:609
static constexpr HERMES_DEVICE_CALLABLE f64 lowest_f64()
Gets lowest representable 64 bit floating point.
Definition: numeric.h:80
static constexpr HERMES_DEVICE_CALLABLE T max(std::initializer_list< T > l)
Computes maximum value from input.
Definition: numeric.h:149
static HERMES_DEVICE_CALLABLE u32 separateBitsBy1(u32 n)
Separate bits by 1 bit-space.
Definition: numeric.h:289
static constexpr HERMES_DEVICE_CALLABLE T sqr(T a)
Definition: numeric.h:192
static HERMES_DEVICE_CALLABLE int round2Int(float f)
rounds to closest integer
Definition: numeric.h:502
static HERMES_DEVICE_CALLABLE size_t findInterval(size_t sz, const Predicate &pred)
Bisect range based on predicate.
Definition: numeric.h:271
static HERMES_DEVICE_CALLABLE f32 log2(f32 x)
Computes base 2 log.
Definition: numeric.h:682
static constexpr HERMES_DEVICE_CALLABLE int greatest_int()
Gets maximum representable 32 bit signed integer.
Definition: numeric.h:474
static HERMES_DEVICE_CALLABLE int floor2Int(float f)
rounds down
Definition: numeric.h:498
static HERMES_DEVICE_CALLABLE uint32_t floatToBits(f32 f)
Interprets a floating-point value into a integer type.
Definition: numeric.h:344
static HERMES_DEVICE_CALLABLE u8 countDigits(u64 t, u8 base=10)
Computes number of digits.
Definition: numeric.h:508
static HERMES_DEVICE_CALLABLE int ceil2Int(float f)
rounds up
Definition: numeric.h:494
static constexpr HERMES_DEVICE_CALLABLE T lowest()
Gets lowest representable floating point.
Definition: numeric.h:92
static constexpr HERMES_DEVICE_CALLABLE f64 greatest_f64()
Gets greatest representable 64 bit floating point.
Definition: numeric.h:102
static HERMES_DEVICE_CALLABLE uint32_t floatSignBit(f32 v)
Extracts sign bit.
Definition: numeric.h:338
static constexpr HERMES_DEVICE_CALLABLE T max(const T &a, const T &b)
Computes maximum between two numbers.
Definition: numeric.h:127
static HERMES_DEVICE_CALLABLE f32 nextFloatDown(f32 v)
Computes the next smaller representable floating-point value.
Definition: numeric.h:411
static HERMES_DEVICE_CALLABLE real_t sqrtRoundDown(real_t a)
Computes square root rounded down to the next smaller float value.
Definition: numeric.h:653
static constexpr HERMES_DEVICE_CALLABLE T evaluatePolynomial(T t, C c, Args... cs)
Solves polynomial.
Definition: numeric.h:262
static HERMES_DEVICE_CALLABLE f32 safe_sqrt(f32 x)
Computes square root with clamped input.
Definition: numeric.h:693
static HERMES_DEVICE_CALLABLE int mod(int a, int b)
Computes modulus.
Definition: numeric.h:483
static HERMES_DEVICE_CALLABLE real_t mulRoundDown(real_t a, real_t b)
Multiplies and rounds down to the next smaller float value.
Definition: numeric.h:534
static HERMES_DEVICE_CALLABLE real_t sqrtRoundUp(real_t a)
Computes square root rounded up to the next float value.
Definition: numeric.h:667
static HERMES_DEVICE_CALLABLE u32 interleaveBits(u32 x, u32 y, u32 z)
Interleaves bits of three integers.
Definition: numeric.h:311
static HERMES_DEVICE_CALLABLE real_t subRoundDown(real_t a, real_t b)
Subtracts and rounds down to the next smaller float value.
Definition: numeric.h:624
static constexpr HERMES_DEVICE_CALLABLE bool isPowerOf2(int v)
Checks if integer is power of 2.
Definition: numeric.h:478
Trigonometric functions.
Definition: numeric.h:791
static HERMES_DEVICE_CALLABLE f32 safe_asin(f32 x)
Computes asin with clamped input.
Definition: numeric.h:816
static constexpr HERMES_DEVICE_CALLABLE real_t radians2degrees(real_t a)
Converts radians to degrees.
Definition: numeric.h:798
static constexpr HERMES_DEVICE_CALLABLE real_t degrees2radians(real_t a)
Converts degrees to radians.
Definition: numeric.h:804
static HERMES_DEVICE_CALLABLE f32 safe_acos(f32 x)
Computes acos with clamped input.
Definition: numeric.h:810