Skip to content

Commit f2cb4ba

Browse files
committed
Merge branch 'lut'
2 parents c371912 + 6d4e3a3 commit f2cb4ba

File tree

2 files changed

+112
-0
lines changed

2 files changed

+112
-0
lines changed

tests/lut_tests.cc

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
#include "doctest.h"
2+
#include "util/lut.hh"
3+
4+
struct VoltageToFreqTableRange {
5+
static constexpr float min = -0.1f;
6+
static constexpr float max = 0.5f;
7+
};
8+
constinit auto VoltageToFrequencyTable =
9+
Mapping::LookupTable_t<50>::generate<VoltageToFreqTableRange>([](float x) { return x * x + 7; });
10+
11+
TEST_CASE("check mapping table") {
12+
constexpr unsigned LEN = 50;
13+
constexpr float min = -0.1f;
14+
constexpr float max = 0.5f;
15+
16+
// generate check data with original table:
17+
// for (unsigned i = 0; i < LEN; i++) {
18+
// auto x = min + i * (max - min) / float(LEN - 1);
19+
// std::cout << "\t{" << x << ", " << VoltageToFrequencyTable.lookup(x) << "},\n";
20+
// }
21+
constexpr std::pair<float, float> checkdata[] = {
22+
{-0.1, 7.01}, {-0.0877551, 7.0077}, {-0.0755102, 7.0057}, {-0.0632653, 7.004}, {-0.0510204, 7.0026},
23+
{-0.0387755, 7.0015}, {-0.0265306, 7.0007}, {-0.0142857, 7.0002}, {-0.00204081, 7}, {0.0102041, 7.0001},
24+
{0.022449, 7.0005}, {0.0346939, 7.0012}, {0.0469388, 7.0022}, {0.0591837, 7.0035}, {0.0714286, 7.0051},
25+
{0.0836735, 7.007}, {0.0959184, 7.0092}, {0.108163, 7.0117}, {0.120408, 7.0145}, {0.132653, 7.0176},
26+
{0.144898, 7.021}, {0.157143, 7.02469}, {0.169388, 7.02869}, {0.181633, 7.03299}, {0.193878, 7.03759},
27+
{0.206122, 7.04249}, {0.218367, 7.04768}, {0.230612, 7.05318}, {0.242857, 7.05898}, {0.255102, 7.06508},
28+
{0.267347, 7.07147}, {0.279592, 7.07817}, {0.291837, 7.08517}, {0.304082, 7.09247}, {0.316327, 7.10006},
29+
{0.328571, 7.10796}, {0.340816, 7.11616}, {0.353061, 7.12465}, {0.365306, 7.13345}, {0.377551, 7.14254},
30+
{0.389796, 7.15194}, {0.402041, 7.16164}, {0.414286, 7.17163}, {0.426531, 7.18193}, {0.438776, 7.19252},
31+
{0.45102, 7.20342}, {0.463265, 7.21461}, {0.47551, 7.22611}, {0.487755, 7.23791}, {0.5, 7.25},
32+
};
33+
34+
// Check data with refactored table:
35+
for (unsigned i = 0; i < LEN; i++) {
36+
auto x = min + i * (max - min) / float(LEN - 1);
37+
auto y = VoltageToFrequencyTable.lookup(x);
38+
CHECK(y == doctest::Approx(checkdata[i].second));
39+
}
40+
}

util/lut.hh

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
#pragma once
2+
#include <algorithm>
3+
#include <array>
4+
#include <cmath>
5+
#include <cstdint>
6+
7+
namespace Mapping
8+
{
9+
10+
namespace Impl
11+
{
12+
13+
template<typename T, std::size_t LEN, typename rangeClass, typename F>
14+
struct EmptyArray {
15+
constexpr EmptyArray(const F &func)
16+
: data() {
17+
constexpr float min = rangeClass::min;
18+
constexpr float max = rangeClass::max;
19+
20+
for (std::size_t i = 0; i < LEN; i++) {
21+
auto x = min + i * (max - min) / float(LEN - 1);
22+
data[i] = func(x);
23+
}
24+
}
25+
std::array<T, LEN> data;
26+
};
27+
28+
} // namespace Impl
29+
30+
template<std::size_t LEN>
31+
class LookupTable_t {
32+
public:
33+
using Base_t = std::array<float, LEN>;
34+
35+
public:
36+
constexpr LookupTable_t(const float min_, const float max_, const Base_t &input)
37+
: min(min_)
38+
, max(max_) {
39+
static_assert(LEN >= 2);
40+
std::copy_n(input.begin(), LEN, points.begin());
41+
}
42+
43+
constexpr float lookup(float val) const {
44+
float idx = ((val - min) / (max - min)) * (LEN - 1);
45+
46+
if (idx <= 0.f)
47+
return points.front();
48+
else if (idx >= (LEN - 1))
49+
return points.back();
50+
else {
51+
auto lower_idx = (uint32_t)idx;
52+
float phase = idx - lower_idx;
53+
auto lower = points[lower_idx];
54+
auto upper = points[lower_idx + 1];
55+
return lower + phase * (upper - lower);
56+
}
57+
}
58+
59+
private:
60+
Base_t points;
61+
const float min;
62+
const float max;
63+
64+
public:
65+
template<typename rangeClass, typename F>
66+
static constexpr LookupTable_t generate(const F func) {
67+
constexpr Impl::EmptyArray<float, LEN, rangeClass, F> dataArray(func);
68+
return LookupTable_t(rangeClass::min, rangeClass::max, dataArray.data);
69+
}
70+
};
71+
72+
} // namespace Mapping

0 commit comments

Comments
 (0)