#ifdef WITH_TESTS #include "../Tests.h" #include "../../math/distribution/Normal.h" #include "../../math/distribution/Bessel.h" #include "../../math/distribution/LUT.h" #include "../../math/distribution/VonMises.h" #include "../../math/distribution/Exponential.h" #include "../../math/distribution/NormalCDF.h" #include "../../math/distribution/Region.h" #include "../../math/distribution/Triangle.h" #include "../../misc/Time.h" template void benchDist(Dist dist) { const int cnt = 1024*1024*32; float f = 0; auto tick = Time::tick(); for (int i = 0; i < cnt; ++i) { f = dist.getProbability(f); } auto tock = Time::tick(); std::cout.imbue(std::locale("en_US.UTF-8")); std::cout << (cnt / (Time::diffMS(tick, tock)+1) * 1000) << "/sec" << std::endl; } TEST(Distribution, Exp) { ASSERT_NEAR(1.5, Distribution::Exponential::getProbability(1.5, 0.0), 0.001); ASSERT_NEAR(1.0, Distribution::Exponential::getProbability(1.0, 0.0), 0.001); ASSERT_NEAR(0.5, Distribution::Exponential::getProbability(0.5, 0.0), 0.001); ASSERT_NEAR(0.35, Distribution::Exponential::getProbability(1.5, 1.0), 0.05); ASSERT_NEAR(0.35, Distribution::Exponential::getProbability(1.0, 1.0), 0.05); ASSERT_NEAR(0.35, Distribution::Exponential::getProbability(0.5, 1.0), 0.05); } TEST(Distribution, Exp_Performance) { Distribution::Exponential dist(0.5); benchDist(dist); } TEST(Distribution, BesselHelper) { Distribution::Bessel bessel; const float delta = 0.001; ASSERT_NEAR( 1.0, bessel.getModified(0, 0), delta); ASSERT_NEAR(11.3, bessel.getModified(0, +4), 0.1); ASSERT_NEAR(11.3, bessel.getModified(0, -4), 0.1); } TEST(Distribution, VonMises) { Distribution::VonMises dist4(0, 4); Distribution::VonMises dist2(0, 2); Distribution::VonMises dist1(0, 1); Distribution::VonMises dist05(0, 0.5); const float delta = 0.01; ASSERT_NEAR(0.768f, dist4.getProbability(0.0f), delta); ASSERT_NEAR(0.515f, dist2.getProbability(0.0f), delta); ASSERT_NEAR(0.342f, dist1.getProbability(0.0f), delta); ASSERT_NEAR(0.24f, dist05.getProbability(0.0f), delta); } TEST(Distribution, normalCDF1) { Distribution::NormalCDF nd(0,1); ASSERT_NEAR(0.5, nd.getProbability(0), 0.00001); ASSERT_NEAR(0.5, Distribution::NormalCDF::getProbability(0, 1, 0), 0.00001); ASSERT_NEAR(1.0, nd.getProbability(5), 0.00001); ASSERT_NEAR(1.0, Distribution::NormalCDF::getProbability(0, 1, 5), 0.00001); ASSERT_NEAR(0.0, nd.getProbability(-5), 0.00001); ASSERT_NEAR(0.0, Distribution::NormalCDF::getProbability(0, 1, -5), 0.00001); } TEST(Distribution, normalCDF2) { Distribution::NormalCDF nd(3,1); ASSERT_NEAR(0.5, nd.getProbability(3), 0.00001); ASSERT_NEAR(0.5, Distribution::NormalCDF::getProbability(3, 1, 3), 0.00001); ASSERT_NEAR(1.0, nd.getProbability(3+5), 0.00001); ASSERT_NEAR(1.0, Distribution::NormalCDF::getProbability(3, 1, 3+5), 0.00001); ASSERT_NEAR(0.0, nd.getProbability(3-5), 0.00001); ASSERT_NEAR(0.0, Distribution::NormalCDF::getProbability(3, 1, 3-5), 0.00001); } //#include //TEST(Distribution, VonMisesDump) { // Distribution::VonMises dist1(0, 4.0); // auto dist2 = dist1.getLUT(); // std::ofstream f1("/tmp/1.dat"); // std::ofstream f2("/tmp/2.dat"); // for (float i = -4; i <= +4; i += 0.001) { // f1 << i << " " << dist1.getProbability(i) << std::endl; // f2 << i << " " << dist2.getProbability(i) << std::endl; // } // f1.close(); // f2.close(); //} TEST(Distribution, VonMises_Performance) { Distribution::VonMises dist(0, 2.0); benchDist(dist); } TEST(Distribution, VonMisesLUT_Performance) { Distribution::VonMises src(0, 2.0); auto dist = src.getLUT(); benchDist(dist); } template float distCheckArea(Dist dist, const float min, const float max) { float step = 0.05; float sum = 0; for (float x = min; x <= max; x += step) { float val = dist.getProbability(x); sum += val*step; } return sum; } #include TEST(Distribution, Region1) { // std::ofstream out("/tmp/1.dat"); // for (float x = -9; x <= +9; x += 0.025) { // //const float y = Distribution::Region::getProbability(0, 3, 1.2, x); // const float y = Distribution::Region::getProbability(1, 2, x); // out << x << " " << y << "\n"; // } // out.close(); Distribution::Region dist1(0, 3); ASSERT_NEAR(1.0, distCheckArea(dist1, -20, +20), 0.01); Distribution::Region dist2(0, 1); ASSERT_NEAR(1.0, distCheckArea(dist2, -20, +20), 0.01); Distribution::Region dist3(1, 3); ASSERT_NEAR(1.0, distCheckArea(dist3, -20, +20), 0.01); Distribution::Region dist4(1, 2); ASSERT_NEAR(1.0, distCheckArea(dist4, -20, +20), 0.01); Distribution::Region dist5(-1, 4); ASSERT_NEAR(1.0, distCheckArea(dist5, -20, +20), 0.01); } TEST(Distribution, Triangle) { std::ofstream out("/tmp/1.dat"); for (float x = -9; x <= +9; x += 0.025) { //const float y = Distribution::Region::getProbability(0, 3, 1.2, x); const float y = Distribution::Triangle::getProbability(3, 6, x); out << x << " " << y << "\n"; } out.close(); Distribution::Triangle dist1(0, 3); ASSERT_NEAR(1.0, distCheckArea(dist1, -20, +20), 0.01); Distribution::Triangle dist2(0, 1); ASSERT_NEAR(1.0, distCheckArea(dist2, -20, +20), 0.01); Distribution::Triangle dist3(1, 3); ASSERT_NEAR(1.0, distCheckArea(dist3, -20, +20), 0.01); Distribution::Triangle dist4(1, 2); ASSERT_NEAR(1.0, distCheckArea(dist4, -20, +20), 0.01); Distribution::Triangle dist5(-1, 4); ASSERT_NEAR(1.0, distCheckArea(dist5, -20, +20), 0.01); } #endif