Exp2Estimate.h 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. // David Eberly, Geometric Tools, Redmond WA 98052
  2. // Copyright (c) 1998-2020
  3. // Distributed under the Boost Software License, Version 1.0.
  4. // https://www.boost.org/LICENSE_1_0.txt
  5. // https://www.geometrictools.com/License/Boost/LICENSE_1_0.txt
  6. // Version: 4.0.2019.08.13
  7. #pragma once
  8. #include <Mathematics/Math.h>
  9. // Minimax polynomial approximations to 2^x. The polynomial p(x) of
  10. // degree D minimizes the quantity maximum{|2^x - p(x)| : x in [0,1]}
  11. // over all polynomials of degree D.
  12. namespace WwiseGTE
  13. {
  14. template <typename Real>
  15. class Exp2Estimate
  16. {
  17. public:
  18. // The input constraint is x in [0,1]. For example,
  19. // float x; // in [0,1]
  20. // float result = Exp2Estimate<float>::Degree<3>(x);
  21. template <int D>
  22. inline static Real Degree(Real x)
  23. {
  24. return Evaluate(degree<D>(), x);
  25. }
  26. // The input x can be any real number. Range reduction is used to
  27. // generate a value y in [0,1], call Degree(y), and combine the output
  28. // with the proper exponent to obtain the approximation. For example,
  29. // float x; // x >= 0
  30. // float result = Exp2Estimate<float>::DegreeRR<3>(x);
  31. template <int D>
  32. inline static Real DegreeRR(Real x)
  33. {
  34. Real p = std::floor(x);
  35. Real y = x - p;
  36. Real poly = Degree<D>(y);
  37. Real result = std::ldexp(poly, (int)p);
  38. return result;
  39. }
  40. private:
  41. // Metaprogramming and private implementation to allow specialization
  42. // of a template member function.
  43. template <int D> struct degree {};
  44. inline static Real Evaluate(degree<1>, Real t)
  45. {
  46. Real poly;
  47. poly = (Real)GTE_C_EXP2_DEG1_C1;
  48. poly = (Real)GTE_C_EXP2_DEG1_C0 + poly * t;
  49. return poly;
  50. }
  51. inline static Real Evaluate(degree<2>, Real t)
  52. {
  53. Real poly;
  54. poly = (Real)GTE_C_EXP2_DEG2_C2;
  55. poly = (Real)GTE_C_EXP2_DEG2_C1 + poly * t;
  56. poly = (Real)GTE_C_EXP2_DEG2_C0 + poly * t;
  57. return poly;
  58. }
  59. inline static Real Evaluate(degree<3>, Real t)
  60. {
  61. Real poly;
  62. poly = (Real)GTE_C_EXP2_DEG3_C3;
  63. poly = (Real)GTE_C_EXP2_DEG3_C2 + poly * t;
  64. poly = (Real)GTE_C_EXP2_DEG3_C1 + poly * t;
  65. poly = (Real)GTE_C_EXP2_DEG3_C0 + poly * t;
  66. return poly;
  67. }
  68. inline static Real Evaluate(degree<4>, Real t)
  69. {
  70. Real poly;
  71. poly = (Real)GTE_C_EXP2_DEG4_C4;
  72. poly = (Real)GTE_C_EXP2_DEG4_C3 + poly * t;
  73. poly = (Real)GTE_C_EXP2_DEG4_C2 + poly * t;
  74. poly = (Real)GTE_C_EXP2_DEG4_C1 + poly * t;
  75. poly = (Real)GTE_C_EXP2_DEG4_C0 + poly * t;
  76. return poly;
  77. }
  78. inline static Real Evaluate(degree<5>, Real t)
  79. {
  80. Real poly;
  81. poly = (Real)GTE_C_EXP2_DEG5_C5;
  82. poly = (Real)GTE_C_EXP2_DEG5_C4 + poly * t;
  83. poly = (Real)GTE_C_EXP2_DEG5_C3 + poly * t;
  84. poly = (Real)GTE_C_EXP2_DEG5_C2 + poly * t;
  85. poly = (Real)GTE_C_EXP2_DEG5_C1 + poly * t;
  86. poly = (Real)GTE_C_EXP2_DEG5_C0 + poly * t;
  87. return poly;
  88. }
  89. inline static Real Evaluate(degree<6>, Real t)
  90. {
  91. Real poly;
  92. poly = (Real)GTE_C_EXP2_DEG6_C6;
  93. poly = (Real)GTE_C_EXP2_DEG6_C5 + poly * t;
  94. poly = (Real)GTE_C_EXP2_DEG6_C4 + poly * t;
  95. poly = (Real)GTE_C_EXP2_DEG6_C3 + poly * t;
  96. poly = (Real)GTE_C_EXP2_DEG6_C2 + poly * t;
  97. poly = (Real)GTE_C_EXP2_DEG6_C1 + poly * t;
  98. poly = (Real)GTE_C_EXP2_DEG6_C0 + poly * t;
  99. return poly;
  100. }
  101. inline static Real Evaluate(degree<7>, Real t)
  102. {
  103. Real poly;
  104. poly = (Real)GTE_C_EXP2_DEG7_C7;
  105. poly = (Real)GTE_C_EXP2_DEG7_C6 + poly * t;
  106. poly = (Real)GTE_C_EXP2_DEG7_C5 + poly * t;
  107. poly = (Real)GTE_C_EXP2_DEG7_C4 + poly * t;
  108. poly = (Real)GTE_C_EXP2_DEG7_C3 + poly * t;
  109. poly = (Real)GTE_C_EXP2_DEG7_C2 + poly * t;
  110. poly = (Real)GTE_C_EXP2_DEG7_C1 + poly * t;
  111. poly = (Real)GTE_C_EXP2_DEG7_C0 + poly * t;
  112. return poly;
  113. }
  114. };
  115. }