The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
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.

136 lines
3.6KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2017 - ROLI Ltd.
  5. JUCE is an open source library subject to commercial or open-source
  6. licensing.
  7. By using JUCE, you agree to the terms of both the JUCE 5 End-User License
  8. Agreement and JUCE 5 Privacy Policy (both updated and effective as of the
  9. 27th April 2017).
  10. End User License Agreement: www.juce.com/juce-5-licence
  11. Privacy Policy: www.juce.com/juce-5-privacy-policy
  12. Or: You may also use this code under the terms of the GPL v3 (see
  13. www.gnu.org/licenses).
  14. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  15. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  16. DISCLAIMED.
  17. ==============================================================================
  18. */
  19. double SpecialFunctions::besselI0 (double x) noexcept
  20. {
  21. auto ax = std::abs (x);
  22. if (ax < 3.75)
  23. {
  24. auto y = x / 3.75;
  25. y *= y;
  26. return 1.0 + y * (3.5156229 + y * (3.0899424 + y * (1.2067492
  27. + y * (0.2659732 + y * (0.360768e-1 + y * 0.45813e-2)))));
  28. }
  29. auto y = 3.75 / ax;
  30. return (std::exp (ax) / std::sqrt (ax))
  31. * (0.39894228 + y * (0.1328592e-1 + y * (0.225319e-2 + y * (-0.157565e-2 + y * (0.916281e-2
  32. + y * (-0.2057706e-1 + y * (0.2635537e-1 + y * (-0.1647633e-1 + y * 0.392377e-2))))))));
  33. }
  34. void SpecialFunctions::ellipticIntegralK (double k, double& K, double& Kp) noexcept
  35. {
  36. constexpr int M = 4;
  37. K = double_Pi * 0.5;
  38. auto lastK = k;
  39. for (int i = 0; i < M; ++i)
  40. {
  41. lastK = std::pow (lastK / (1 + std::sqrt (1 - std::pow (lastK, 2.0))), 2.0);
  42. K *= 1 + lastK;
  43. }
  44. Kp = double_Pi * 0.5;
  45. auto last = std::sqrt (1 - k * k);
  46. for (int i = 0; i < M; ++i)
  47. {
  48. last = std::pow (last / (1.0 + std::sqrt (1.0 - std::pow (last, 2.0))), 2.0);
  49. Kp *= 1 + last;
  50. }
  51. }
  52. Complex<double> SpecialFunctions::cde (Complex<double> u, double k) noexcept
  53. {
  54. constexpr int M = 4;
  55. double ke[M + 1];
  56. double* kei = ke;
  57. *kei = k;
  58. for (int i = 0; i < M; ++i)
  59. {
  60. auto next = std::pow (*kei / (1.0 + std::sqrt (1.0 - std::pow (*kei, 2.0))), 2.0);
  61. *++kei = next;
  62. }
  63. std::complex<double> last = std::cos (0.5 * u * double_Pi);
  64. for (int i = M - 1; i >= 0; --i)
  65. last = (1.0 + ke[i + 1]) / (1.0 / last + ke[i + 1] * last);
  66. return last;
  67. }
  68. Complex<double> SpecialFunctions::sne (Complex<double> u, double k) noexcept
  69. {
  70. constexpr int M = 4;
  71. double ke[M + 1];
  72. double* kei = ke;
  73. *kei = k;
  74. for (int i = 0; i < M; ++i)
  75. {
  76. auto next = std::pow (*kei / (1 + std::sqrt (1 - std::pow (*kei, 2.0))), 2.0);
  77. *++kei = next;
  78. }
  79. std::complex<double> last = std::sin (0.5 * u * double_Pi);
  80. for (int i = M - 1; i >= 0; --i)
  81. last = (1.0 + ke[i + 1]) / (1.0 / last + ke[i + 1] * last);
  82. return last;
  83. }
  84. Complex<double> SpecialFunctions::asne (Complex<double> w, double k) noexcept
  85. {
  86. constexpr int M = 4;
  87. double ke[M + 1];
  88. double* kei = ke;
  89. *kei = k;
  90. for (int i = 0; i < M; ++i)
  91. {
  92. auto next = std::pow (*kei / (1.0 + std::sqrt (1.0 - std::pow (*kei, 2.0))), 2.0);
  93. *++kei = next;
  94. }
  95. std::complex<double> last = w;
  96. for (int i = 1; i <= M; ++i)
  97. last = 2.0 * last / ((1.0 + ke[i]) * (1.0 + std::sqrt (1.0 - std::pow (ke[i - 1] * last, 2.0))));
  98. return 2.0 / double_Pi * std::asin (last);
  99. }