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.

170 lines
5.3KB

  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. namespace juce
  20. {
  21. namespace dsp
  22. {
  23. /**
  24. A class representing a polynomial
  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. #if JUCE_COMPILER_SUPPORTS_INITIALIZER_LISTS || defined(DOXYGEN)
  57. /** Creates a new polynomial with coefficients by a C++11 initializer list.
  58. This function can be used in the following way:
  59. Polynomial<float> p ({0.5f, -0.3f, 0.2f});
  60. */
  61. template <typename TypeToCreateFrom>
  62. Polynomial (const std::initializer_list<TypeToCreateFrom>& items) : coeffs (items)
  63. {
  64. jassert (! coeffs.isEmpty());
  65. }
  66. #endif
  67. //==============================================================================
  68. /** Returns a single coefficient of the receiver for reading */
  69. FloatingType operator[] (int index) const noexcept { return coeffs.getUnchecked (index); }
  70. /** Returns a single coefficient of the receiver for modifying. */
  71. FloatingType& operator[] (int index) noexcept { return coeffs.getReference (index); }
  72. /** Evaluates the value of the polynomial at a single point x. */
  73. FloatingType operator() (FloatingType x) const noexcept
  74. {
  75. // Horner's method
  76. FloatingType y = 0;
  77. for (int i = coeffs.size(); --i >= 0;)
  78. y = (x * y) + coeffs.getUnchecked(i);
  79. return y;
  80. }
  81. /** Returns the order of the polynomial. */
  82. int getOrder() noexcept
  83. {
  84. return coeffs.size() - 1;
  85. }
  86. //==============================================================================
  87. /** Returns the polynomial with all its coefficients multiplied with a gain factor */
  88. Polynomial<FloatingType> withGain (double gain) const
  89. {
  90. auto result = *this;
  91. for (auto& c : result.coeffs)
  92. c *= gain;
  93. return result;
  94. }
  95. /** Returns the sum of this polynomial with another */
  96. Polynomial<FloatingType> getSumWith (const Polynomial<FloatingType>& other) const
  97. {
  98. if (coeffs.size() < other.coeffs.size())
  99. return other.getSumWith (*this);
  100. auto result = *this;
  101. for (int i = 0; i < other.coeffs.size(); ++i)
  102. result[i] += other[i];
  103. return result;
  104. }
  105. /** computes the product of two polynomials and return the result */
  106. Polynomial<FloatingType> getProductWith (const Polynomial<FloatingType>& other) const
  107. {
  108. Polynomial<FloatingType> result;
  109. result.coeffs.clearQuick();
  110. auto N1 = coeffs.size();
  111. auto N2 = other.coeffs.size();
  112. auto Nmax = jmax (N1, N2);
  113. auto N = N1 + N2 - 1;
  114. for (int i = 0; i < N; ++i)
  115. {
  116. FloatingType value = {};
  117. for (int j = 0; j < Nmax; ++j)
  118. if (j >= 0 && j < N1 && i - j >= 0 && i - j < N2)
  119. value = value + (*this)[j] * other[i - j];
  120. result.coeffs.add (value);
  121. }
  122. return result;
  123. }
  124. private:
  125. //==============================================================================
  126. Array<FloatingType> coeffs;
  127. JUCE_LEAK_DETECTOR (Polynomial)
  128. };
  129. } // namespace dsp
  130. } // namespace juce