From 1e3a33b0e7678289e6e86b2f552b751b6263ca91 Mon Sep 17 00:00:00 2001 From: Tobias Hienzsch Date: Sat, 10 Feb 2024 03:11:06 +0100 Subject: [PATCH] Add StaticLookupTable --- CMakeLists.txt | 1 + lib/grit/math/static_lookup_table.hpp | 56 ++++++++++++++++++++++ lib/grit/math/static_lookup_table_test.cpp | 20 ++++++++ 3 files changed, 77 insertions(+) create mode 100644 lib/grit/math/static_lookup_table.hpp create mode 100644 lib/grit/math/static_lookup_table_test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 30a566f..f77b705 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -56,5 +56,6 @@ if(NOT CMAKE_CROSSCOMPILING) "lib/grit/fft/fft_test.cpp" "lib/grit/math/ilog2_test.cpp" "lib/grit/math/ipow_test.cpp" + "lib/grit/math/static_lookup_table_test.cpp" ) endif() diff --git a/lib/grit/math/static_lookup_table.hpp b/lib/grit/math/static_lookup_table.hpp new file mode 100644 index 0000000..46dba4f --- /dev/null +++ b/lib/grit/math/static_lookup_table.hpp @@ -0,0 +1,56 @@ +#pragma once + +#include + +#include +#include +#include + +namespace grit { + +template +struct StaticLookupTable +{ + constexpr StaticLookupTable() = default; + + template FunctionToApproximate> + requires(etl::same_as, Float>) + explicit constexpr StaticLookupTable(FunctionToApproximate func) + { + initialize(func); + } + + template FunctionToApproximate> + requires(etl::same_as, Float>) + constexpr auto initialize(FunctionToApproximate func) -> void + { + for (auto i = etl::size_t{0}; i < Size; ++i) { + auto value = func(i); + _buffer[i] = value; + } + _buffer[Size] = _buffer[Size - 1]; + } + + [[nodiscard]] constexpr auto atUnchecked(Float index) const -> Float + { + auto const i = static_cast(index); + auto const f = index - Float(i); + auto const x0 = _buffer[i]; + auto const x1 = _buffer[i + 1]; + return linearInterpolation(x0, x1, f); + } + + [[nodiscard]] constexpr auto at(Float index) const -> Float + { + return atUnchecked(etl::clamp(index, Float(0), Float(Size - 1))); + } + + [[nodiscard]] constexpr auto operator[](Float index) const -> Float { return atUnchecked(index); } + + [[nodiscard]] static constexpr auto size() -> etl::size_t { return Size; } + +private: + etl::array _buffer; +}; + +} // namespace grit diff --git a/lib/grit/math/static_lookup_table_test.cpp b/lib/grit/math/static_lookup_table_test.cpp new file mode 100644 index 0000000..6c48ad8 --- /dev/null +++ b/lib/grit/math/static_lookup_table_test.cpp @@ -0,0 +1,20 @@ +#include "static_lookup_table.hpp" + +#include +#include + +TEMPLATE_TEST_CASE("grit/math: StaticLookupTable", "", float, double) +{ + using Float = TestType; + + auto lut = grit::StaticLookupTable{[](auto index) { return static_cast(index); }}; + REQUIRE(lut[Float(0)] == Catch::Approx(0.0)); + REQUIRE(lut[Float(55)] == Catch::Approx(55.0)); + REQUIRE(lut[Float(126)] == Catch::Approx(126.0)); + + REQUIRE(lut.at(Float(100)) == Catch::Approx(100.0)); + REQUIRE(lut.at(Float(125)) == Catch::Approx(125.0)); + REQUIRE(lut.at(Float(126)) == Catch::Approx(126.0)); + REQUIRE(lut.at(Float(127)) == Catch::Approx(126.0)); + REQUIRE(lut.at(Float(128)) == Catch::Approx(126.0)); +}