2015-07-10 06:01:56 -07:00
|
|
|
/*
|
|
|
|
* test_find_index.cpp
|
|
|
|
*
|
|
|
|
* Created on: Oct 30, 2013
|
2020-01-13 18:57:43 -08:00
|
|
|
* @author Andrey Belomutskiy, (c) 2012-2020
|
2015-07-10 06:01:56 -07:00
|
|
|
*/
|
|
|
|
|
2018-09-16 19:39:46 -07:00
|
|
|
#include "global.h"
|
2015-07-10 06:01:56 -07:00
|
|
|
#include "engine_math.h"
|
|
|
|
#include "interpolation.h"
|
2018-03-04 20:08:32 -08:00
|
|
|
#include "unit_test_framework.h"
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2019-01-08 20:02:04 -08:00
|
|
|
static void testIndex(const int expected, const float array[], int size, float value) {
|
2019-01-14 12:37:05 -08:00
|
|
|
ASSERT_EQ(expected, findIndex(array, size, value));
|
2019-01-14 15:00:59 -08:00
|
|
|
ASSERT_EQ(expected, findIndex2(array, size, value));
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
2019-01-14 12:31:56 -08:00
|
|
|
TEST(misc, testFindIndex) {
|
2015-07-10 06:01:56 -07:00
|
|
|
printf("*************************************************** testFindIndex\r\n");
|
|
|
|
/*
|
|
|
|
{
|
|
|
|
// in real life we only use powers of 2 for sizes
|
|
|
|
float array5[] = { 1, 2, 3, 4, 5 };
|
|
|
|
const int size5 = 5;
|
|
|
|
printf("To the right5\r\n");
|
|
|
|
testIndex(4, array5, size5, 10.0);
|
|
|
|
|
|
|
|
printf("Middle2\r\n");
|
|
|
|
testIndex(3, array5, size5, 4);
|
|
|
|
|
|
|
|
printf("Middle2\r\n");
|
|
|
|
testIndex(2, array5, size5, 3.1);
|
|
|
|
|
|
|
|
}
|
|
|
|
*/
|
|
|
|
{
|
|
|
|
float array4[] = { 1, 2, 3, 4 };
|
|
|
|
const int size4 = 4;
|
|
|
|
|
|
|
|
printf("To the left\r\n");
|
|
|
|
testIndex(-1, array4, size4, -1.0);
|
|
|
|
|
|
|
|
printf("To the right4\r\n");
|
|
|
|
testIndex(3, array4, size4, 10.0);
|
|
|
|
|
|
|
|
printf("On the edge\r\n");
|
|
|
|
testIndex(3, array4, size4, 4.0);
|
|
|
|
|
|
|
|
printf("Another1\r\n");
|
|
|
|
testIndex(2, array4, size4, 3.9);
|
|
|
|
|
|
|
|
printf("Another2\r\n");
|
|
|
|
testIndex(3, array4, size4, 4.1);
|
|
|
|
|
|
|
|
printf("Another3\r\n");
|
|
|
|
testIndex(1, array4, size4, 2);
|
|
|
|
|
|
|
|
printf("Left edge1\r\n");
|
|
|
|
testIndex(0, array4, size4, 1);
|
|
|
|
|
|
|
|
printf("Left edge2\r\n");
|
|
|
|
testIndex(0, array4, size4, 1.1);
|
|
|
|
|
|
|
|
printf("Middle\r\n");
|
|
|
|
testIndex(2, array4, size4, 3);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-01-14 12:31:56 -08:00
|
|
|
TEST(misc, testInterpolate2d) {
|
2015-07-10 06:01:56 -07:00
|
|
|
printf("*************************************************** testInterpolate2d\r\n");
|
|
|
|
|
|
|
|
float bins4[] = { 1, 2, 3, 4 };
|
|
|
|
float values4[] = { 1, 20, 30, 400 };
|
|
|
|
|
|
|
|
int result;
|
|
|
|
|
|
|
|
printf("Left size\r\n");
|
2021-02-16 06:32:16 -08:00
|
|
|
result = interpolate2d(0, bins4, values4);
|
2019-01-14 15:00:59 -08:00
|
|
|
ASSERT_EQ(1, result);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
printf("Right size\r\n");
|
2021-02-16 06:32:16 -08:00
|
|
|
result = interpolate2d(10, bins4, values4);
|
2019-01-14 15:00:59 -08:00
|
|
|
ASSERT_EQ(400, result);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
printf("Middle1\r\n");
|
2021-02-16 06:32:16 -08:00
|
|
|
result = interpolate2d(3, bins4, values4);
|
2019-01-14 15:00:59 -08:00
|
|
|
ASSERT_EQ(30, result);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
printf("Middle1\r\n");
|
2021-02-16 06:32:16 -08:00
|
|
|
result = interpolate2d(3.5, bins4, values4);
|
2019-01-14 15:00:59 -08:00
|
|
|
ASSERT_EQ(215, result);
|
2015-07-10 06:01:56 -07:00
|
|
|
}
|
|
|
|
|
2019-01-14 12:31:56 -08:00
|
|
|
TEST(misc, testSetTableValue) {
|
2015-07-10 06:01:56 -07:00
|
|
|
printf("*************************************************** testSetTableValue\r\n");
|
|
|
|
|
|
|
|
persistent_config_s config;
|
|
|
|
|
|
|
|
for (int i = 0; i < CLT_CURVE_SIZE; i++) {
|
|
|
|
config.cltFuelCorrBins[i] = -40 + i * 10;
|
|
|
|
config.cltFuelCorr[i] = 1;
|
|
|
|
}
|
|
|
|
|
2019-01-14 15:00:59 -08:00
|
|
|
ASSERT_EQ(1, config.cltFuelCorr[0]);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2017-06-11 12:12:41 -07:00
|
|
|
setCurveValue(config.cltFuelCorrBins, config.cltFuelCorr, CLT_CURVE_SIZE, -40, 1.5);
|
2019-01-14 15:20:20 -08:00
|
|
|
ASSERT_FLOAT_EQ(1.5, config.cltFuelCorr[0]);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
2017-06-11 12:12:41 -07:00
|
|
|
setCurveValue(config.cltFuelCorrBins, config.cltFuelCorr, CLT_CURVE_SIZE, -50, 1.4);
|
2019-01-14 15:20:20 -08:00
|
|
|
ASSERT_FLOAT_EQ(1.4, config.cltFuelCorr[0]);
|
2015-07-10 06:01:56 -07:00
|
|
|
|
|
|
|
}
|
2021-01-11 05:00:15 -08:00
|
|
|
|
|
|
|
class TestTable2dSmall : public ::testing::Test
|
|
|
|
{
|
|
|
|
protected:
|
|
|
|
float bins[2];
|
|
|
|
float values[2];
|
|
|
|
|
|
|
|
void SetUp() override
|
|
|
|
{
|
|
|
|
// This test maps [20,30] -> [100,200]
|
|
|
|
copyArray(bins, { 20.0f, 30.0f });
|
|
|
|
copyArray(values, { 100.0f, 200.0f });
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
TEST_F(TestTable2dSmall, OffScaleLow)
|
|
|
|
{
|
|
|
|
EXPECT_FLOAT_EQ(interpolate2d(10, bins, values), 100);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(TestTable2dSmall, OffScaleHigh)
|
|
|
|
{
|
|
|
|
EXPECT_FLOAT_EQ(interpolate2d(40, bins, values), 200);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(TestTable2dSmall, EdgeLeft)
|
|
|
|
{
|
|
|
|
EXPECT_FLOAT_EQ(interpolate2d(20, bins, values), 100);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(TestTable2dSmall, EdgeRight)
|
|
|
|
{
|
|
|
|
EXPECT_FLOAT_EQ(interpolate2d(30, bins, values), 200);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(TestTable2dSmall, Middle)
|
|
|
|
{
|
|
|
|
EXPECT_FLOAT_EQ(interpolate2d(25, bins, values), 150);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST_F(TestTable2dSmall, NanInput)
|
|
|
|
{
|
|
|
|
EXPECT_FLOAT_EQ(interpolate2d(NAN, bins, values), 100);
|
|
|
|
}
|
|
|
|
|
|
|
|
class Test2dTableMassive : public ::testing::Test
|
|
|
|
{
|
|
|
|
static constexpr int Count = 2500;
|
|
|
|
|
|
|
|
protected:
|
|
|
|
float bins[Count];
|
|
|
|
float values[Count];
|
|
|
|
|
|
|
|
void SetUp() override
|
|
|
|
{
|
|
|
|
float x = 0;
|
|
|
|
|
|
|
|
for (size_t i = 0; i < std::size(bins); i++)
|
|
|
|
{
|
|
|
|
x += 0.1f;
|
|
|
|
bins[i] = x;
|
|
|
|
values[i] = x * x;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
TEST_F(Test2dTableMassive, t)
|
|
|
|
{
|
|
|
|
float x = 0;
|
|
|
|
float maxErr = -1;
|
|
|
|
|
|
|
|
for (size_t i = 0; i < 25000; i++)
|
|
|
|
{
|
|
|
|
x += 0.01f;
|
|
|
|
|
|
|
|
float actual = x * x;
|
|
|
|
float lookup = interpolate2d(x, bins, values);
|
|
|
|
|
|
|
|
float err = std::abs(actual - lookup);
|
|
|
|
|
|
|
|
if (err > maxErr)
|
|
|
|
{
|
|
|
|
maxErr = err;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
EXPECT_LT(maxErr, 0.01);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Helper for BinResult type
|
|
|
|
#define EXPECT_BINRESULT(actual, expectedIdx, expectedFrac) \
|
|
|
|
{ \
|
|
|
|
auto ___temp___ = actual; \
|
|
|
|
EXPECT_EQ(___temp___.Idx, expectedIdx); \
|
|
|
|
EXPECT_NEAR(___temp___.Frac, expectedFrac, expectedFrac / 1e4); \
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test with small bins: only two values
|
|
|
|
static const float smallBins[] = { 10, 20 };
|
|
|
|
|
|
|
|
TEST(TableBinsSmall, OffScaleLeft)
|
|
|
|
{
|
|
|
|
EXPECT_BINRESULT(priv::getBin(5, smallBins), 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(TableBinsSmall, OffScaleRight)
|
|
|
|
{
|
|
|
|
EXPECT_BINRESULT(priv::getBin(25, smallBins), 0, 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(TableBinsSmall, EdgeLeft)
|
|
|
|
{
|
|
|
|
EXPECT_BINRESULT(priv::getBin(10, smallBins), 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(TableBinsSmall, EdgeRight)
|
|
|
|
{
|
|
|
|
EXPECT_BINRESULT(priv::getBin(10, smallBins), 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(TableBinsSmall, Middle)
|
|
|
|
{
|
|
|
|
EXPECT_BINRESULT(priv::getBin(15, smallBins), 0, 0.5f);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(TableBinsSmall, NanInput)
|
|
|
|
{
|
|
|
|
EXPECT_BINRESULT(priv::getBin(NAN, smallBins), 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Test with medium bins, 3 items
|
|
|
|
static const float bigBins[] = { 10, 20, 30 };
|
|
|
|
|
|
|
|
TEST(TableBinsBig, OffScaleLow)
|
|
|
|
{
|
|
|
|
EXPECT_BINRESULT(priv::getBin(5, bigBins), 0, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(TableBinsBig, OffScaleHigh)
|
|
|
|
{
|
|
|
|
EXPECT_BINRESULT(priv::getBin(35, bigBins), 1, 1.0f);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
TEST(TableBinsBig, NearMiddleLow)
|
|
|
|
{
|
|
|
|
EXPECT_BINRESULT(priv::getBin(19.99f, bigBins), 0, 0.999f);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(TableBinsBig, NearMiddleExact)
|
|
|
|
{
|
|
|
|
EXPECT_BINRESULT(priv::getBin(20.0f, bigBins), 1, 0);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(TableBinsBig, NearMiddleHigh)
|
|
|
|
{
|
|
|
|
EXPECT_BINRESULT(priv::getBin(20.01f, bigBins), 1, 0.001f);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(TableBinsBig, LeftMiddle)
|
|
|
|
{
|
|
|
|
EXPECT_BINRESULT(priv::getBin(15.0f, bigBins), 0, 0.5f);
|
|
|
|
}
|
|
|
|
|
|
|
|
TEST(TableBinsBig, RightMiddle)
|
|
|
|
{
|
|
|
|
EXPECT_BINRESULT(priv::getBin(25.0f, bigBins), 1, 0.5f);
|
|
|
|
}
|