Audio plugin host https://kx.studio/carla
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.

169 lines
5.2KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library.
  4. Copyright (c) 2022 - Raw Material Software Limited
  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 7 End-User License
  8. Agreement and JUCE Privacy Policy.
  9. End User License Agreement: www.juce.com/juce-7-licence
  10. Privacy Policy: www.juce.com/juce-privacy-policy
  11. Or: You may also use this code under the terms of the GPL v3 (see
  12. www.gnu.org/licenses).
  13. JUCE IS PROVIDED "AS IS" WITHOUT ANY WARRANTY, AND ALL WARRANTIES, WHETHER
  14. EXPRESSED OR IMPLIED, INCLUDING MERCHANTABILITY AND FITNESS FOR PURPOSE, ARE
  15. DISCLAIMED.
  16. ==============================================================================
  17. */
  18. namespace juce
  19. {
  20. namespace dsp
  21. {
  22. /**
  23. A class representing a polynomial
  24. @tags{DSP}
  25. */
  26. template <typename FloatingType>
  27. class Polynomial
  28. {
  29. public:
  30. //==============================================================================
  31. /** Creates a new polynomial which will always evaluate to zero. */
  32. Polynomial()
  33. {
  34. coeffs.add (0);
  35. }
  36. /** Creates a new polynomial with given coefficients.
  37. @param numCoefficients The number of coefficients stored in coefficients.
  38. This is also the order of the returned polynomial.
  39. @param coefficients The coefficients which will be used by the newly
  40. created polynomial. The Polynomial class will keep
  41. a private copy of the coefficients.
  42. */
  43. Polynomial (const FloatingType* coefficients, int numCoefficients)
  44. : coeffs (coefficients, numCoefficients)
  45. {
  46. jassert (! coeffs.isEmpty());
  47. }
  48. /** Creates a copy of another polynomial. */
  49. Polynomial (const Polynomial&) = default;
  50. /** Creates a copy of another polynomial. */
  51. Polynomial (Polynomial&&) = default;
  52. /** Creates a copy of another polynomial. */
  53. Polynomial& operator= (const Polynomial&) = default;
  54. /** Creates a copy of another polynomial. */
  55. Polynomial& operator= (Polynomial&&) = default;
  56. /** Creates a new polynomial with coefficients by a C++11 initializer list.
  57. This function can be used in the following way:
  58. Polynomial<float> p ({0.5f, -0.3f, 0.2f});
  59. */
  60. template <typename... Values>
  61. Polynomial (Values... items) : coeffs (items...)
  62. {
  63. jassert (! coeffs.isEmpty());
  64. }
  65. //==============================================================================
  66. /** Returns a single coefficient of the receiver for reading */
  67. FloatingType operator[] (int index) const noexcept { return coeffs.getUnchecked (index); }
  68. /** Returns a single coefficient of the receiver for modifying. */
  69. FloatingType& operator[] (int index) noexcept { return coeffs.getReference (index); }
  70. /** Evaluates the value of the polynomial at a single point x. */
  71. FloatingType operator() (FloatingType x) const noexcept
  72. {
  73. // Horner's method
  74. FloatingType y (0);
  75. for (int i = coeffs.size(); --i >= 0;)
  76. y = (x * y) + coeffs.getUnchecked(i);
  77. return y;
  78. }
  79. /** Returns the order of the polynomial. */
  80. int getOrder() noexcept
  81. {
  82. return coeffs.size() - 1;
  83. }
  84. //==============================================================================
  85. /** Returns the polynomial with all its coefficients multiplied with a gain factor */
  86. Polynomial<FloatingType> withGain (double gain) const
  87. {
  88. auto result = *this;
  89. for (auto& c : result.coeffs)
  90. c *= gain;
  91. return result;
  92. }
  93. /** Returns the sum of this polynomial with another */
  94. Polynomial<FloatingType> getSumWith (const Polynomial<FloatingType>& other) const
  95. {
  96. if (coeffs.size() < other.coeffs.size())
  97. return other.getSumWith (*this);
  98. auto result = *this;
  99. for (int i = 0; i < other.coeffs.size(); ++i)
  100. result[i] += other[i];
  101. return result;
  102. }
  103. /** computes the product of two polynomials and return the result */
  104. Polynomial<FloatingType> getProductWith (const Polynomial<FloatingType>& other) const
  105. {
  106. Polynomial<FloatingType> result;
  107. result.coeffs.clearQuick();
  108. auto N1 = coeffs.size();
  109. auto N2 = other.coeffs.size();
  110. auto Nmax = jmax (N1, N2);
  111. auto N = N1 + N2 - 1;
  112. for (int i = 0; i < N; ++i)
  113. {
  114. FloatingType value (0);
  115. for (int j = 0; j < Nmax; ++j)
  116. if (j >= 0 && j < N1 && i - j >= 0 && i - j < N2)
  117. value = value + (*this)[j] * other[i - j];
  118. result.coeffs.add (value);
  119. }
  120. return result;
  121. }
  122. private:
  123. //==============================================================================
  124. Array<FloatingType> coeffs;
  125. JUCE_LEAK_DETECTOR (Polynomial)
  126. };
  127. } // namespace dsp
  128. } // namespace juce