You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

approx.hpp 1.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142
  1. #pragma once
  2. #include <dsp/common.hpp>
  3. namespace rack {
  4. namespace dsp {
  5. /*
  6. In this header, function names are divided into two or more parts, separated by "_".
  7. The functionality is the first part, and the approximation methods are the following parts.
  8. Glossary:
  9. https://en.wikipedia.org/wiki/Taylor_series
  10. https://en.wikipedia.org/wiki/Pad%C3%A9_approximant
  11. https://en.wikipedia.org/wiki/Horner%27s_method
  12. https://en.wikipedia.org/wiki/Estrin%27s_scheme
  13. */
  14. /** Returns 2^x, assuming that x >= 0.
  15. Maximum 0.00024% error.
  16. Roughly 7x faster than `std::pow(2, x)`.
  17. If negative powers are needed, you may use a lower bound and rescale.
  18. approxExp2(x + 20) / 1048576
  19. */
  20. template <typename T>
  21. T approxExp2_taylor5(T x) {
  22. int xi = x;
  23. x -= xi;
  24. T y = 1 << xi;
  25. // Fifth order expansion of 2^x around 0.4752 in Horner form.
  26. // The center is chosen so that the endpoints of [0, 1] have equal error, creating no discontinuity at integers.
  27. y *= T(0.9999976457798443) + x * (T(0.6931766804601935) + x * (T(0.2400729486415728) + x * (T(0.05592817518644387) + x * (T(0.008966320633544) + x * T(0.001853512473884202)))));
  28. return y;
  29. }
  30. } // namespace dsp
  31. } // namespace rack