From be1a785fd53dfde4951af80a3b7d65a0d215ab6d Mon Sep 17 00:00:00 2001 From: LABOURASSE Emmanuel <labourassee@gmail.com> Date: Wed, 19 Aug 2020 17:49:36 +0200 Subject: [PATCH] Some more feature for polynomials (power,compostition) --- src/analysis/Polynomial.hpp | 76 +++++++++++++++++++++++++++++++++++++ tests/CMakeLists.txt | 1 + tests/test_Polynomial.cpp | 38 +++++++++++++++++++ 3 files changed, 115 insertions(+) diff --git a/src/analysis/Polynomial.hpp b/src/analysis/Polynomial.hpp index 252db7b8d..f9929b0bd 100644 --- a/src/analysis/Polynomial.hpp +++ b/src/analysis/Polynomial.hpp @@ -83,6 +83,32 @@ class Polynomial return P; } + template <size_t M> + PUGS_INLINE constexpr Polynomial<N>& + operator=(const Polynomial<M>& Q) + { + coefficients() = zero; + for (size_t i = N + 1; i <= M; ++i) { + Assert(Q.coefficients()[i] == 0, "degree of polynomial to small in assignation"); + } + // static_assert(N >= M, "degree of polynomial to small in assignation"); + for (size_t i = 0; i <= std::min(M, N); ++i) { + coefficients()[i] = Q.coefficients()[i]; + } + return *this; + } + + template <size_t M> + PUGS_INLINE constexpr Polynomial<N>& + operator+=(const Polynomial<M>& Q) + { + static_assert(N >= M, "Polynomial degree to small in affectation addition"); + for (size_t i = 0; i <= M; ++i) { + coefficients()[i] += Q.coefficients()[i]; + } + return *this; + } + template <size_t M> PUGS_INLINE constexpr Polynomial<M + N> operator*(const Polynomial<M>& Q) const { @@ -104,6 +130,56 @@ class Polynomial return M; } + template <size_t M> + PUGS_INLINE constexpr Polynomial<M * N> + compose(const Polynomial<M>& Q) const + { + Polynomial<M * N> P; + P.coefficients() = zero; + Polynomial<M * N> R; + R.coefficients() = zero; + + for (size_t i = 0; i <= N; ++i) { + R = Q.template pow<N>(i) * coefficients()[i]; + P += R; // R; + } + return P; + } + + template <size_t M> + PUGS_INLINE constexpr Polynomial<M * N> + operator()(const Polynomial<M>& Q) const + { + Polynomial<M * N> P; + P.coefficients() = zero; + Polynomial<M * N> R; + R.coefficients() = zero; + + for (size_t i = 0; i <= N; ++i) { + R = Q.template pow<N>(i) * coefficients()[i]; + P += R; // R; + } + return P; + } + + template <size_t M> + PUGS_INLINE constexpr Polynomial<M * N> + pow(size_t power) const + { + Assert(power <= M, "You declared a polynomial of degree too small for return of the pow function"); + Polynomial<M * N> R; + R.coefficients() = zero; + if (power == 0) { + R.coefficients()[0] = 1; + } else { + R = *this; + for (size_t i = 1; i < power; ++i) { + R = R * *this; + } + } + return R; + } + PUGS_INLINE constexpr friend Polynomial<N> operator*(const double& lambda, const Polynomial<N> P) { diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt index 2dfd32344..59628d072 100644 --- a/tests/CMakeLists.txt +++ b/tests/CMakeLists.txt @@ -68,6 +68,7 @@ add_executable (unit_tests test_NameProcessor.cpp test_OStreamProcessor.cpp test_PCG.cpp + test_Polynomial.cpp test_PugsFunctionAdapter.cpp test_PugsAssert.cpp test_RevisionInfo.cpp diff --git a/tests/test_Polynomial.cpp b/tests/test_Polynomial.cpp index b5570d9de..1e5d6f83f 100644 --- a/tests/test_Polynomial.cpp +++ b/tests/test_Polynomial.cpp @@ -102,4 +102,42 @@ TEST_CASE("Polynomial", "[analysis]") Polynomial<0> R(0); REQUIRE(derivative(P2) == R); } + + SECTION("affectation") + { + Polynomial<2> Q({2, -3, 3}); + Polynomial<4> R({2, -3, 3, 0, 0}); + Polynomial<4> P({0, 1, 2, 3, 3}); + P = Q; + REQUIRE(P == R); + } + + SECTION("affectation addition") + { + Polynomial<2> Q({2, -3, 3}); + Polynomial<4> R({2, -2, 5, 3, 3}); + Polynomial<4> P({0, 1, 2, 3, 3}); + P += Q; + REQUIRE(P == R); + } + + SECTION("power") + { + Polynomial<2> P({2, -3, 3}); + Polynomial<4> R({4, -12, 21, -18, 9}); + Polynomial<1> Q({0, 2}); + Polynomial<2> S = Q.pow<2>(2); + REQUIRE(P.pow<2>(2) == R); + REQUIRE(S == Polynomial<2>({0, 0, 4})); + } + + SECTION("composition") + { + Polynomial<2> P({2, -3, 3}); + Polynomial<1> Q({0, 2}); + Polynomial<2> R({2, -1, 3}); + Polynomial<2> S({1, 2, 2}); + REQUIRE(P.compose(Q) == Polynomial<2>({2, -6, 12})); + REQUIRE(R(S) == Polynomial<4>({4, 10, 22, 24, 12})); + } } -- GitLab