LCOV - code coverage report
Current view: top level - firmware/libfirmware/util/test - test_interpolation.cpp (source / functions) Hit Total Coverage
Test: coverage.info Lines: 92 92 100.0 %
Date: 2024-04-25 02:23:43 Functions: 86 86 100.0 %

          Line data    Source code
       1             : #include "gtest/gtest.h"
       2             : 
       3             : #include <rusefi/arrays.h>
       4             : #include <rusefi/interpolation.h>
       5             : 
       6           4 : TEST(Util_Interpolation, testInterpolate2d) {
       7           1 :         float bins4[] = { 1, 2, 3, 4 };
       8           1 :         float values4[] = { 1, 20, 30, 400 };
       9             : 
      10           1 :         int result;
      11             : 
      12             :         // Left size
      13           1 :         result = interpolate2d(0, bins4, values4);
      14           1 :         ASSERT_EQ(1, result);
      15             : 
      16             :         // Right size
      17           1 :         result = interpolate2d(10, bins4, values4);
      18           1 :         ASSERT_EQ(400, result);
      19             : 
      20             :         // Middle
      21           1 :         result = interpolate2d(3, bins4, values4);
      22           1 :         ASSERT_EQ(30, result);
      23             : 
      24             :         // Middle
      25           1 :         result = interpolate2d(3.5, bins4, values4);
      26           1 :         ASSERT_EQ(215, result);
      27             : }
      28             : 
      29             : 
      30             : class TestTable2dSmall : public ::testing::Test
      31             : {
      32             : protected:
      33             :         float bins[2];
      34             :         float values[2];
      35             : 
      36           6 :         void SetUp() override
      37             :         {
      38             :                 // This test maps [20,30] -> [100,200]
      39           6 :                 copyArray(bins, { 20.0f, 30.0f });
      40           6 :                 copyArray(values, { 100.0f, 200.0f });
      41           6 :         }
      42             : };
      43             : 
      44           4 : TEST_F(TestTable2dSmall, OffScaleLow)
      45             : {
      46           1 :     EXPECT_FLOAT_EQ(interpolate2d(10, bins, values), 100);
      47           1 : }
      48             : 
      49           4 : TEST_F(TestTable2dSmall, OffScaleHigh)
      50             : {
      51           1 :     EXPECT_FLOAT_EQ(interpolate2d(40, bins, values), 200);
      52           1 : }
      53             : 
      54           4 : TEST_F(TestTable2dSmall, EdgeLeft)
      55             : {
      56           1 :     EXPECT_FLOAT_EQ(interpolate2d(20, bins, values), 100);
      57           1 : }
      58             : 
      59           4 : TEST_F(TestTable2dSmall, EdgeRight)
      60             : {
      61           1 :     EXPECT_FLOAT_EQ(interpolate2d(30, bins, values), 200);
      62           1 : }
      63             : 
      64           4 : TEST_F(TestTable2dSmall, Middle)
      65             : {
      66           1 :     EXPECT_FLOAT_EQ(interpolate2d(25, bins, values), 150);
      67           1 : }
      68             : 
      69           4 : TEST_F(TestTable2dSmall, NanInput)
      70             : {
      71           1 :     EXPECT_FLOAT_EQ(interpolate2d(NAN, bins, values), 100);
      72           1 : }
      73             : 
      74             : class Test2dTableMassive : public ::testing::Test
      75             : {
      76             :         static constexpr int Count = 2500;
      77             : 
      78             : protected:
      79             :         float bins[Count];
      80             :         float values[Count];
      81             : 
      82           1 :         void SetUp() override
      83             :         {
      84           1 :                 float x = 0;
      85             : 
      86        2501 :                 for (size_t i = 0; i < std::size(bins); i++)
      87             :                 {
      88        2500 :                         x += 0.1f;
      89        2500 :                         bins[i] = x;
      90        2500 :                         values[i] = x * x;
      91             :                 }
      92           1 :         }
      93             : };
      94             : 
      95           4 : TEST_F(Test2dTableMassive, t)
      96             : {
      97           1 :     float x = 0;
      98           1 :     float maxErr = -1;
      99             : 
     100       25001 :     for (size_t i = 0; i < 25000; i++)
     101             :     {
     102       25000 :         x += 0.01f;
     103             : 
     104       25000 :         float actual = x * x;
     105       25000 :         float lookup = interpolate2d(x, bins, values);
     106             : 
     107       25000 :         float err = std::abs(actual - lookup);
     108             : 
     109       25000 :         if (err > maxErr)
     110             :         {
     111           1 :             maxErr = err;
     112             :         }
     113             :     }
     114             : 
     115           1 :     EXPECT_LT(maxErr, 0.01);
     116           1 : }
     117             : 
     118             : // Helper for BinResult type
     119             : #define EXPECT_BINRESULT(actual, expectedIdx, expectedFrac) \
     120             :         { \
     121             :                 auto ___temp___ = actual; \
     122             :                 EXPECT_EQ(___temp___.Idx, expectedIdx); \
     123             :                 EXPECT_NEAR(___temp___.Frac, expectedFrac, expectedFrac / 1e4); \
     124             :         }
     125             : 
     126             : // Test with small bins: only two values
     127             : static const float smallBins[] = { 10, 20 };
     128             : 
     129           4 : TEST(Util_Interpolation, GetBinSmallOffScaleLeft)
     130             : {
     131           2 :     EXPECT_BINRESULT(priv::getBin(5, smallBins), 0, 0);
     132           1 : }
     133             : 
     134           4 : TEST(Util_Interpolation, GetBinSmallOffScaleRight)
     135             : {
     136           2 :     EXPECT_BINRESULT(priv::getBin(25, smallBins), 0, 1);
     137           1 : }
     138             : 
     139           4 : TEST(Util_Interpolation, GetBinSmallEdgeLeft)
     140             : {
     141           2 :     EXPECT_BINRESULT(priv::getBin(10, smallBins), 0, 0);
     142           1 : }
     143             : 
     144           4 : TEST(Util_Interpolation, GetBinSmallEdgeRight)
     145             : {
     146           2 :     EXPECT_BINRESULT(priv::getBin(10, smallBins), 0, 0);
     147           1 : }
     148             : 
     149           4 : TEST(Util_Interpolation, GetBinSmallMiddle)
     150             : {
     151           2 :     EXPECT_BINRESULT(priv::getBin(15, smallBins), 0, 0.5f);
     152           1 : }
     153             : 
     154           4 : TEST(Util_Interpolation, GetBinSmallNanInput)
     155             : {
     156           2 :         EXPECT_BINRESULT(priv::getBin(NAN, smallBins), 0, 0);
     157           1 : }
     158             : 
     159             : // Test with medium bins, 3 items
     160             : static const float bigBins[] = { 10, 20, 30 };
     161             : 
     162           4 : TEST(Util_Interpolation, GetBinBigOffScaleLow)
     163             : {
     164           2 :     EXPECT_BINRESULT(priv::getBin(5, bigBins), 0, 0);
     165           1 : }
     166             : 
     167           4 : TEST(Util_Interpolation, GetBinBigOffScaleHigh)
     168             : {
     169           2 :     EXPECT_BINRESULT(priv::getBin(35, bigBins), 1, 1.0f);
     170           1 : }
     171             : 
     172             : 
     173           4 : TEST(Util_Interpolation, GetBinBigNearMiddleLow)
     174             : {
     175           2 :     EXPECT_BINRESULT(priv::getBin(19.99f, bigBins), 0, 0.999f);
     176           1 : }
     177             : 
     178           4 : TEST(Util_Interpolation, GetBinBigNearMiddleExact)
     179             : {
     180           2 :     EXPECT_BINRESULT(priv::getBin(20.0f, bigBins), 1, 0);
     181           1 : }
     182             : 
     183           4 : TEST(Util_Interpolation, GetBinBigNearMiddleHigh)
     184             : {
     185           2 :     EXPECT_BINRESULT(priv::getBin(20.01f, bigBins), 1, 0.001f);
     186           1 : }
     187             : 
     188           4 : TEST(Util_Interpolation, GetBinBigLeftMiddle)
     189             : {
     190           2 :     EXPECT_BINRESULT(priv::getBin(15.0f, bigBins), 0, 0.5f);
     191           1 : }
     192             : 
     193           4 : TEST(Util_Interpolation, GetBinBigRightMiddle)
     194             : {
     195           2 :     EXPECT_BINRESULT(priv::getBin(25.0f, bigBins), 1, 0.5f);
     196           1 : }
     197             : 

Generated by: LCOV version 1.14