/* * lut.h * Copyright (c) 2025 Christopher Herb * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal * in the Software without restriction, including without limitation the rights * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell * copies of the Software, and to permit persons to whom the Software is * furnished to do so, subject to the following conditions: * * The above copyright notice and this permission notice shall be included in * all copies or substantial portions of the Software. * * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE * SOFTWARE. */ #pragma once #include #include namespace trnr { // Fixed-point log lookup table (Q12) constexpr int32_t LOG_TABLE_SIZE = 256; constexpr int32_t LOG_FRACTIONAL_BITS = 12; constexpr int32_t LOG_TABLE[LOG_TABLE_SIZE] = { -37726, -22594, -19806, -18163, -16993, -16084, -15341, -14712, -14167, -13686, -13256, -12866, -12511, -12183, -11880, -11598, -11334, -11086, -10853, -10632, -10422, -10222, -10032, -9850, -9676, -9509, -9348, -9194, -9045, -8901, -8763, -8628, -8499, -8373, -8250, -8132, -8016, -7904, -7795, -7689, -7585, -7484, -7385, -7289, -7195, -7103, -7013, -6925, -6839, -6754, -6672, -6591, -6511, -6433, -6357, -6281, -6208, -6135, -6064, -5994, -5925, -5858, -5791, -5725, -5661, -5598, -5535, -5473, -5413, -5353, -5294, -5236, -5179, -5122, -5067, -5012, -4957, -4904, -4851, -4799, -4747, -4696, -4646, -4597, -4548, -4499, -4451, -4404, -4357, -4311, -4265, -4220, -4175, -4131, -4087, -4044, -4001, -3958, -3916, -3875, -3834, -3793, -3753, -3713, -3673, -3634, -3595, -3557, -3518, -3481, -3443, -3406, -3370, -3333, -3297, -3261, -3226, -3191, -3156, -3121, -3087, -3053, -3019, -2986, -2953, -2920, -2887, -2855, -2823, -2791, -2759, -2728, -2697, -2666, -2635, -2605, -2574, -2544, -2515, -2485, -2456, -2427, -2398, -2369, -2340, -2312, -2284, -2256, -2228, -2201, -2173, -2146, -2119, -2092, -2065, -2039, -2013, -1986, -1960, -1935, -1909, -1883, -1858, -1833, -1808, -1783, -1758, -1733, -1709, -1685, -1661, -1637, -1613, -1589, -1565, -1542, -1519, -1495, -1472, -1449, -1426, -1404, -1381, -1359, -1336, -1314, -1292, -1270, -1248, -1227, -1205, -1184, -1162, -1141, -1120, -1099, -1078, -1057, -1036, -1016, -995, -975, -954, -934, -914, -894, -874, -854, -834, -815, -795, -776, -756, -737, -718, -699, -680, -661, -642, -623, -605, -586, -568, -549, -531, -513, -494, -476, -458, -440, -423, -405, -387, -370, -352, -335, -317, -300, -283, -265, -248, -231, -214, -197, -181, -164, -147, -131, -114, -98, -81, -65, -48, -32, -16, 0, }; // Fixed-point exp lookup table (Q12) constexpr int32_t EXP_TABLE_SIZE = 256; constexpr int32_t EXP_FRACTIONAL_BITS = 12; constexpr int32_t EXP_TABLE[EXP_TABLE_SIZE] = { 4096, 4169, 4243, 4319, 4396, 4474, 4553, 4635, 4717, 4801, 4887, 4974, 5062, 5152, 5244, 5337, 5432, 5529, 5627, 5728, 5830, 5933, 6039, 6147, 6256, 6367, 6481, 6596, 6714, 6833, 6955, 7079, 7205, 7333, 7463, 7596, 7732, 7869, 8009, 8152, 8297, 8445, 8595, 8748, 8904, 9062, 9224, 9388, 9555, 9725, 9898, 10075, 10254, 10436, 10622, 10811, 11004, 11200, 11399, 11602, 11809, 12019, 12233, 12451, 12672, 12898, 13128, 13361, 13599, 13841, 14088, 14339, 14594, 14854, 15118, 15387, 15661, 15940, 16224, 16513, 16807, 17106, 17410, 17720, 18036, 18357, 18684, 19016, 19355, 19700, 20050, 20407, 20771, 21140, 21517, 21900, 22290, 22687, 23091, 23502, 23920, 24346, 24779, 25221, 25670, 26127, 26592, 27065, 27547, 28037, 28537, 29045, 29562, 30088, 30624, 31169, 31724, 32289, 32864, 33449, 34044, 34650, 35267, 35895, 36534, 37185, 37847, 38520, 39206, 39904, 40615, 41338, 42074, 42823, 43585, 44361, 45151, 45955, 46773, 47606, 48453, 49316, 50194, 51088, 51997, 52923, 53865, 54824, 55800, 56794, 57805, 58834, 59881, 60947, 62032, 63137, 64261, 65405, 66569, 67755, 68961, 70189, 71438, 72710, 74005, 75322, 76663, 78028, 79417, 80831, 82270, 83735, 85226, 86743, 88288, 89859, 91459, 93088, 94745, 96432, 98148, 99896, 101674, 103485, 105327, 107202, 109111, 111053, 113031, 115043, 117091, 119176, 121298, 123457, 125655, 127892, 130169, 132487, 134845, 137246, 139690, 142177, 144708, 147284, 149906, 152575, 155292, 158056, 160870, 163735, 166650, 169617, 172636, 175710, 178838, 182022, 185263, 188561, 191918, 195335, 198813, 202352, 205955, 209622, 213354, 217152, 221018, 224953, 228958, 233035, 237184, 241406, 245704, 250079, 254531, 259063, 263675, 268369, 273147, 278010, 282960, 287998, 293125, 298344, 303655, 309061, 314564, 320164, 325864, 331666, 337571, 343581, 349698, 355924, 362261, 368710, }; inline int32_t fixed_log(int32_t x) { if (x <= 0) return LOG_TABLE[0] << 3; // Scale Q12 → Q15 int32_t max_val = (1 << LOG_FRACTIONAL_BITS); int32_t idx = (x * LOG_TABLE_SIZE) / max_val; if (idx >= LOG_TABLE_SIZE - 1) idx = LOG_TABLE_SIZE - 2; int32_t a = LOG_TABLE[idx] << 3; // Scale Q12 → Q15 int32_t b = LOG_TABLE[idx + 1] << 3; int32_t frac = ((x * LOG_TABLE_SIZE) - (idx * max_val)); return a + ((b - a) * frac / max_val); } inline int32_t fixed_exp(int32_t x) { int32_t max_val = (1 << EXP_FRACTIONAL_BITS); int32_t idx = (x * EXP_TABLE_SIZE) / max_val; if (idx >= EXP_TABLE_SIZE - 1) idx = EXP_TABLE_SIZE - 2; int32_t a = EXP_TABLE[idx] << 3; // Scale Q12 → Q15 int32_t b = EXP_TABLE[idx + 1] << 3; int32_t frac = ((x * EXP_TABLE_SIZE) - (idx * max_val)); return a + ((b - a) * frac / max_val); } } // namespace trnr