Skip to content

Commit

Permalink
Add StaticLookupTable
Browse files Browse the repository at this point in the history
  • Loading branch information
tobiashienzsch committed Feb 10, 2024
1 parent 82d8e95 commit 1e3a33b
Show file tree
Hide file tree
Showing 3 changed files with 77 additions and 0 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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()
56 changes: 56 additions & 0 deletions lib/grit/math/static_lookup_table.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
#pragma once

#include <grit/math/linear_interpolation.hpp>

#include <etl/algorithm.hpp>
#include <etl/array.hpp>
#include <etl/concepts.hpp>

namespace grit {

template<etl::floating_point Float, etl::size_t Size>
struct StaticLookupTable
{
constexpr StaticLookupTable() = default;

template<etl::regular_invocable<etl::size_t> FunctionToApproximate>
requires(etl::same_as<etl::invoke_result_t<FunctionToApproximate, etl::size_t>, Float>)
explicit constexpr StaticLookupTable(FunctionToApproximate func)
{
initialize(func);
}

template<etl::regular_invocable<etl::size_t> FunctionToApproximate>
requires(etl::same_as<etl::invoke_result_t<FunctionToApproximate, etl::size_t>, 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<etl::size_t>(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<Float, Size + 1> _buffer;
};

} // namespace grit
20 changes: 20 additions & 0 deletions lib/grit/math/static_lookup_table_test.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
#include "static_lookup_table.hpp"

#include <catch2/catch_approx.hpp>
#include <catch2/catch_template_test_macros.hpp>

TEMPLATE_TEST_CASE("grit/math: StaticLookupTable", "", float, double)
{
using Float = TestType;

auto lut = grit::StaticLookupTable<Float, 127>{[](auto index) { return static_cast<Float>(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));
}

0 comments on commit 1e3a33b

Please sign in to comment.