diff --git a/src/analysis/PolynomialBasis.hpp b/src/analysis/PolynomialBasis.hpp new file mode 100644 index 0000000000000000000000000000000000000000..c8e782b799a8b6baecbaf80af594d9d72ca6ee5a --- /dev/null +++ b/src/analysis/PolynomialBasis.hpp @@ -0,0 +1,105 @@ +#ifndef POLYNOMIALBASIS_HPP +#define POLYNOMIALBASIS_HPP + +#include <algebra/TinyVector.hpp> +#include <analysis/Polynomial.hpp> +#include <utils/Messenger.hpp> + +enum class BasisType +{ + canonical +}; + +template <size_t N> +class PolynomialBasis +{ + private: + static_assert((N >= 0), "Number of elements in the basis must be non-negative"); + TinyVector<N + 1, Polynomial<N>> m_elements; + BasisType m_basis_type; + PUGS_INLINE + constexpr PolynomialBasis<N>& + _buildCanonicalBasis() + { + for (size_t i = 0; i <= N; i++) { + TinyVector<N + 1> coefficients(zero); + coefficients[i] = 1; + elements()[i] = Polynomial<N>(coefficients); + } + return *this; + } + + public: + PUGS_INLINE + constexpr size_t + size() const + { + return N + 1; + } + + PUGS_INLINE + constexpr size_t + degree() const + { + return N; + } + + PUGS_INLINE + constexpr BasisType& + type() + { + return m_basis_type; + } + + PUGS_INLINE + std::string_view + displayType() + { + switch (m_basis_type) { + case BasisType::canonical: + return "canonical"; + default: + return "unknown basis type"; + } + } + + PUGS_INLINE + constexpr const TinyVector<N + 1, Polynomial<N>>& + elements() const + { + return m_elements; + } + + PUGS_INLINE + constexpr TinyVector<N + 1, Polynomial<N>>& + elements() + { + return m_elements; + } + + PUGS_INLINE + constexpr PolynomialBasis<N>& + build(BasisType basis_type) + { + type() = basis_type; + switch (basis_type) { + case BasisType::canonical: { + return _buildCanonicalBasis(); + break; + } + default: + throw UnexpectedError("unknown basis type"); + } + } + PUGS_INLINE constexpr PolynomialBasis(const TinyVector<N + 1, Polynomial<N>>& elements) noexcept + : m_elements{elements} + {} + + PUGS_INLINE + constexpr PolynomialBasis(TinyVector<N + 1, Polynomial<N>>&& elements) noexcept : m_elements{elements} {} + + PUGS_INLINE + constexpr PolynomialBasis() noexcept = default; + ~PolynomialBasis() = default; +}; +#endif // POLYNOMIAL_HPP diff --git a/tests/test_PolynomialBasis.cpp b/tests/test_PolynomialBasis.cpp new file mode 100644 index 0000000000000000000000000000000000000000..933797bb328386809133fe5c7d14c5cdb318a8c9 --- /dev/null +++ b/tests/test_PolynomialBasis.cpp @@ -0,0 +1,42 @@ +#include <catch2/catch.hpp> + +#include <Kokkos_Core.hpp> + +#include <utils/PugsAssert.hpp> +#include <utils/Types.hpp> + +#include <algebra/TinyMatrix.hpp> +#include <analysis/Polynomial.hpp> +#include <analysis/PolynomialBasis.hpp> + +// Instantiate to ensure full coverage is performed +template class Polynomial<0>; +template class Polynomial<1>; +template class Polynomial<2>; +template class PolynomialBasis<2>; + +// clazy:excludeall=non-pod-global-static + +TEST_CASE("PolynomialBasis", "[analysis]") +{ + SECTION("construction") + { + TinyVector<3, Polynomial<2>> elements; + REQUIRE_NOTHROW(PolynomialBasis<2>(elements)); + REQUIRE_NOTHROW(PolynomialBasis<2>()); + } + SECTION("size") + { + PolynomialBasis<2> B; + REQUIRE(B.size() == 3); + REQUIRE(B.degree() == 2); + } + SECTION("build") + { + PolynomialBasis<2> B; + REQUIRE(B.displayType() == "unknown basis type"); + B.build(BasisType::canonical); + REQUIRE(B.elements()[1] == Polynomial<2>{{0, 1, 0}}); + REQUIRE(B.elements()[2] == Polynomial<2>{{0, 0, 1}}); + } +}