Skip to content

Commit

Permalink
Add methods for computing Chebyshev polynomials (#528)
Browse files Browse the repository at this point in the history
* Add methods for computing Chebyshev polynomials

* Add documentation

* Apply clang-format

* size_t instead of int

---------

Co-authored-by: github-actions[bot] <github-actions[bot]@users.noreply.github.com>
  • Loading branch information
jatinchowdhury18 and github-actions[bot] authored Apr 23, 2024
1 parent ba945fa commit 9a2333b
Show file tree
Hide file tree
Showing 4 changed files with 85 additions and 0 deletions.
60 changes: 60 additions & 0 deletions modules/dsp/chowdsp_math/Math/chowdsp_ChebyshevPolynomials.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
#pragma once

namespace chowdsp
{
#ifndef DOXYGEN
namespace cheby_detail
{
template <typename T, size_t max_order = 32>
constexpr auto cheby0()
{
Polynomial<T, max_order, poly_order_ascending> poly {};
poly.coeffs[0] = static_cast<T> (1);
return poly;
}

template <typename T, size_t max_order = 32>
constexpr auto cheby1()
{
Polynomial<T, max_order, poly_order_ascending> poly {};
poly.coeffs[1] = static_cast<T> (1);
return poly;
}
} // namespace cheby_detail
#endif

/** Recursively computes a Chebyshev polynomial given two previous Chebyshev polynomials */
template <typename T, size_t max_order = 32>
constexpr auto chebyshev_polynomial_recurse (const Polynomial<T, max_order, poly_order_ascending>& cheby_n1,
const Polynomial<T, max_order, poly_order_ascending>& cheby_n2)
{
Polynomial<T, max_order, poly_order_ascending> cheby_n {};
cheby_n.coeffs[0] = -cheby_n2.coeffs[0];
for (size_t i = 1; i < max_order; ++i)
cheby_n.coeffs[i] = (T) 2 * cheby_n1.coeffs[i - 1] - cheby_n2.coeffs[i];
return cheby_n;
}

/** Computes a Chebyshev polynomial of a given order. */
template <typename T, size_t order, size_t max_order = 32>
constexpr auto chebyshev_polynomial()
{
if constexpr (order == 0)
return cheby_detail::cheby0<T, 32>();

if constexpr (order == 1)
return cheby_detail::cheby1<T, 32>();

auto cheby_n2 = cheby_detail::cheby0<T, 32>();
auto cheby_n1 = cheby_detail::cheby1<T, 32>();
auto cheby_n = Polynomial<T, max_order, poly_order_ascending> {};
for (size_t i = 2; i <= order; ++i)
{
cheby_n = chebyshev_polynomial_recurse<T, max_order> (cheby_n1, cheby_n2);
cheby_n2 = cheby_n1;
cheby_n1 = cheby_n;
}

return cheby_n;
}
} // namespace chowdsp
1 change: 1 addition & 0 deletions modules/dsp/chowdsp_math/chowdsp_math.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ JUCE_END_IGNORE_WARNINGS_GCC_LIKE
#include "Math/chowdsp_OtherMathOps.h"
#include "Math/chowdsp_MatrixOps.h"
#include "Math/chowdsp_Polynomials.h"
#include "Math/chowdsp_ChebyshevPolynomials.h"
#include "Math/chowdsp_Power.h"
#include "Math/chowdsp_RandomFloat.h"
#include "Math/chowdsp_JacobiElliptic.h"
Expand Down
1 change: 1 addition & 0 deletions tests/dsp_tests/chowdsp_math_test/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ target_sources(chowdsp_math_test
FloatVectorOperationsTest.cpp
MatrixOpsTest.cpp
PolynomialsTest.cpp
ChebyshevPolynomialTest.cpp
PowerTest.cpp
OtherMathOpsTest.cpp
JacobiEllipticTest.cpp
Expand Down
23 changes: 23 additions & 0 deletions tests/dsp_tests/chowdsp_math_test/ChebyshevPolynomialTest.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#include <CatchUtils.h>
#include <chowdsp_math/chowdsp_math.h>

static void check_poly (const chowdsp::Polynomial<float, 32, chowdsp::poly_order_ascending>& cheby_poly,
std::vector<float>&& actual)
{
size_t i = 0;
for (; i < actual.size(); ++i)
REQUIRE (cheby_poly.coeffs[i] == Catch::Approx { actual[i] }.margin (1.0e-6));
for (; i < cheby_poly.coeffs.size(); ++i)
REQUIRE (cheby_poly.coeffs[i] == Catch::Approx { 0.0f }.margin (1.0e-6));
}

TEST_CASE ("Chebyshev Polynomials Test", "[dsp][math]")
{
check_poly (chowdsp::chebyshev_polynomial<float, 2>(), { -1.0f, 0.0f, 2.0f });
check_poly (chowdsp::chebyshev_polynomial<float, 3>(), { 0.0f, -3.0f, 0.0f, 4.0f });
check_poly (chowdsp::chebyshev_polynomial<float, 4>(), { 1.0f, 0.0f, -8.0f, 0.0f, 8.0f });
check_poly (chowdsp::chebyshev_polynomial<float, 5>(), { 0.0f, 5.0f, 0.0f, -20.0f, 0.0f, 16.0f });
check_poly (chowdsp::chebyshev_polynomial<float, 6>(), { -1.0f, 0.0f, 18.0f, 0.0f, -48.0f, 0.0f, 32.0f });
check_poly (chowdsp::chebyshev_polynomial<float, 7>(), { 0.0f, -7.0f, 0.0f, 56.0f, 0.0f, -112.0f, 0.0f, 64.0f });
check_poly (chowdsp::chebyshev_polynomial<float, 8>(), { 1.0f, 0.0f, -32.0f, 0.0f, 160.0f, 0.0f, -256.0f, 0.0f, 128.0f });
}

0 comments on commit 9a2333b

Please sign in to comment.