halfFunction.h 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. //
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. // Copyright Contributors to the OpenEXR Project.
  4. //
  5. //---------------------------------------------------------------------------
  6. //
  7. // halfFunction<T> -- a class for fast evaluation
  8. // of half --> T functions
  9. //
  10. // The constructor for a halfFunction object,
  11. //
  12. // halfFunction (function,
  13. // domainMin, domainMax,
  14. // defaultValue,
  15. // posInfValue, negInfValue,
  16. // nanValue);
  17. //
  18. // evaluates the function for all finite half values in the interval
  19. // [domainMin, domainMax], and stores the results in a lookup table.
  20. // For finite half values that are not in [domainMin, domainMax], the
  21. // constructor stores defaultValue in the table. For positive infinity,
  22. // negative infinity and NANs, posInfValue, negInfValue and nanValue
  23. // are stored in the table.
  24. //
  25. // The tabulated function can then be evaluated quickly for arbitrary
  26. // half values by calling the the halfFunction object's operator()
  27. // method.
  28. //
  29. // Example:
  30. //
  31. // #include <math.h>
  32. // #include <halfFunction.h>
  33. //
  34. // halfFunction<half> hsin (sin);
  35. //
  36. // halfFunction<half> hsqrt (sqrt, // function
  37. // 0, HALF_MAX, // domain
  38. // half::qNan(), // sqrt(x) for x < 0
  39. // half::posInf(), // sqrt(+inf)
  40. // half::qNan(), // sqrt(-inf)
  41. // half::qNan()); // sqrt(nan)
  42. //
  43. // half x = hsin (1);
  44. // half y = hsqrt (3.5);
  45. //
  46. //---------------------------------------------------------------------------
  47. #ifndef _HALF_FUNCTION_H_
  48. #define _HALF_FUNCTION_H_
  49. /// @cond Doxygen_Suppress
  50. #include "half.h"
  51. #include "ImathConfig.h"
  52. #ifndef IMATH_HAVE_LARGE_STACK
  53. # include <string.h> // need this for memset
  54. #else
  55. #endif
  56. #include <float.h>
  57. template <class T> class halfFunction
  58. {
  59. public:
  60. //------------
  61. // Constructor
  62. //------------
  63. template <class Function>
  64. halfFunction (Function f,
  65. half domainMin = -HALF_MAX,
  66. half domainMax = HALF_MAX,
  67. T defaultValue = 0,
  68. T posInfValue = 0,
  69. T negInfValue = 0,
  70. T nanValue = 0);
  71. #ifndef IMATH_HAVE_LARGE_STACK
  72. ~halfFunction() { delete[] _lut; }
  73. halfFunction (const halfFunction&) = delete;
  74. halfFunction& operator= (const halfFunction&) = delete;
  75. halfFunction (halfFunction&&) = delete;
  76. halfFunction& operator= (halfFunction&&) = delete;
  77. #endif
  78. //-----------
  79. // Evaluation
  80. //-----------
  81. T operator() (half x) const;
  82. private:
  83. #ifdef IMATH_HAVE_LARGE_STACK
  84. T _lut[1 << 16];
  85. #else
  86. T* _lut;
  87. #endif
  88. };
  89. //---------------
  90. // Implementation
  91. //---------------
  92. template <class T>
  93. template <class Function>
  94. halfFunction<T>::halfFunction (Function f,
  95. half domainMin,
  96. half domainMax,
  97. T defaultValue,
  98. T posInfValue,
  99. T negInfValue,
  100. T nanValue)
  101. {
  102. #ifndef IMATH_HAVE_LARGE_STACK
  103. _lut = new T[1 << 16];
  104. #endif
  105. for (int i = 0; i < (1 << 16); i++)
  106. {
  107. half x;
  108. x.setBits (i);
  109. if (x.isNan())
  110. _lut[i] = nanValue;
  111. else if (x.isInfinity())
  112. _lut[i] = x.isNegative() ? negInfValue : posInfValue;
  113. else if (x < domainMin || x > domainMax)
  114. _lut[i] = defaultValue;
  115. else
  116. _lut[i] = f (x);
  117. }
  118. }
  119. template <class T>
  120. inline T
  121. halfFunction<T>::operator() (half x) const
  122. {
  123. return _lut[x.bits()];
  124. }
  125. /// @endcond
  126. #endif