diff --git a/grid/walk/GridWalkLightAtTheEndOfTheTunnel.h b/grid/walk/GridWalkLightAtTheEndOfTheTunnel.h index 1dc8b58..ae59caa 100644 --- a/grid/walk/GridWalkLightAtTheEndOfTheTunnel.h +++ b/grid/walk/GridWalkLightAtTheEndOfTheTunnel.h @@ -6,6 +6,7 @@ #include "../../math/DrawList.h" #include "../../math/Distributions.h" +#include "../../math/DrawList.h" #include "../../nav/dijkstra/Dijkstra.h" @@ -34,7 +35,7 @@ private: DrawList drawer; /** fast random-number-generator */ - std::minstd_rand gen; + RandomGenerator gen; /** 0-mean normal distribution */ std::normal_distribution headingChangeDist = std::normal_distribution(0.0, HEADING_CHANGE_SIGMA); diff --git a/grid/walk/GridWalkPathControl.h b/grid/walk/GridWalkPathControl.h index 7701af6..de7d3a4 100644 --- a/grid/walk/GridWalkPathControl.h +++ b/grid/walk/GridWalkPathControl.h @@ -23,7 +23,7 @@ private: static constexpr float HEADING_CHANGE_SIGMA = Angle::degToRad(10); /** fast random-number-generator */ - std::minstd_rand gen; + RandomGenerator gen; /** 0-mean normal distribution */ std::normal_distribution headingChangeDist = std::normal_distribution(0.0, HEADING_CHANGE_SIGMA); diff --git a/grid/walk/GridWalkPushForward.h b/grid/walk/GridWalkPushForward.h index 3d62bf4..7d01da3 100644 --- a/grid/walk/GridWalkPushForward.h +++ b/grid/walk/GridWalkPushForward.h @@ -8,6 +8,7 @@ #include "../Grid.h" #include "../../math/DrawList.h" +#include "../../math/Random.h" #include "../../nav/dijkstra/Dijkstra.h" #include "GridWalkState.h" @@ -31,7 +32,7 @@ private: static constexpr float HEADING_ALLOWED_SIGMA = Angle::degToRad(20); /** fast random-number-generator */ - std::minstd_rand gen; + RandomGenerator gen; /** 0-mean normal distribution */ std::normal_distribution headingChangeDist = std::normal_distribution(0.0, HEADING_CHANGE_SIGMA); diff --git a/grid/walk/GridWalkRandomHeadingUpdate.h b/grid/walk/GridWalkRandomHeadingUpdate.h index ce5209e..2d5b05e 100644 --- a/grid/walk/GridWalkRandomHeadingUpdate.h +++ b/grid/walk/GridWalkRandomHeadingUpdate.h @@ -4,6 +4,8 @@ #include "../../geo/Heading.h" #include "../Grid.h" + +#include "../../math/Random.h" #include "../../nav/dijkstra/Dijkstra.h" #include "GridWalk.h" @@ -33,7 +35,7 @@ private: static constexpr float HEADING_CHANGE_SIGMA = Angle::degToRad(10); /** fast random-number-generator */ - std::minstd_rand gen; + RandomGenerator gen; /** 0-mean normal distribution */ std::normal_distribution headingChangeDist = std::normal_distribution(0.0, HEADING_CHANGE_SIGMA); diff --git a/grid/walk/GridWalkRandomHeadingUpdateAdv.h b/grid/walk/GridWalkRandomHeadingUpdateAdv.h index 32e07f5..a387755 100644 --- a/grid/walk/GridWalkRandomHeadingUpdateAdv.h +++ b/grid/walk/GridWalkRandomHeadingUpdateAdv.h @@ -8,6 +8,7 @@ #include "../../math/DrawList.h" #include "../../math/Distributions.h" #include "../../nav/dijkstra/Dijkstra.h" +#include "../../math/Random.h" #include "GridWalk.h" #include "GridWalkState.h" @@ -34,7 +35,7 @@ private: static constexpr float HEADING_CHANGE_SIGMA = Angle::degToRad(10); /** fast random-number-generator */ - std::minstd_rand gen; + RandomGenerator gen; /** 0-mean normal distribution */ std::normal_distribution headingChangeDist = std::normal_distribution(0.0, HEADING_CHANGE_SIGMA); diff --git a/grid/walk/GridWalkShortestPathControl.h b/grid/walk/GridWalkShortestPathControl.h index d69c6a1..9254fb9 100644 --- a/grid/walk/GridWalkShortestPathControl.h +++ b/grid/walk/GridWalkShortestPathControl.h @@ -7,6 +7,7 @@ #include "../../math/Distributions.h" #include "../../math/DrawList.h" +#include "../../math/Random.h" #include "../../nav/dijkstra/Dijkstra.h" #include "../../nav/dijkstra/DijkstraPath.h" @@ -17,6 +18,8 @@ #include "GridWalkHelper.h" #include "GridWalk.h" + + #include template class GridWalkShortestPathControl : public GridWalk { @@ -76,7 +79,7 @@ protected: static constexpr float HEADING_CHANGE_SIGMA = Angle::degToRad(10); /** fast random-number-generator */ - std::minstd_rand gen; + RandomGenerator gen; /** 0-mean normal distribution */ std::normal_distribution headingChangeDist = std::normal_distribution(0.0, HEADING_CHANGE_SIGMA); diff --git a/grid/walk/GridWalkSimpleControl.h b/grid/walk/GridWalkSimpleControl.h index f736561..cc3ad88 100644 --- a/grid/walk/GridWalkSimpleControl.h +++ b/grid/walk/GridWalkSimpleControl.h @@ -8,6 +8,7 @@ #include "../../math/Distributions.h" #include "../../math/DrawList.h" +#include "../../math/Random.h" #include "GridWalkState.h" #include "GridWalkHelper.h" @@ -23,7 +24,7 @@ private: static constexpr float HEADING_CHANGE_SIGMA = Angle::degToRad(10); /** fast random-number-generator */ - std::minstd_rand gen; + RandomGenerator gen; /** 0-mean normal distribution */ std::normal_distribution headingChangeDist = std::normal_distribution(0.0, HEADING_CHANGE_SIGMA); diff --git a/grid/walk/GridWalkWeighted.h b/grid/walk/GridWalkWeighted.h index 252130a..cd97f5a 100644 --- a/grid/walk/GridWalkWeighted.h +++ b/grid/walk/GridWalkWeighted.h @@ -6,6 +6,7 @@ #include "../../math/DrawList.h" #include "../../math/Distributions.h" +#include "../../math/DrawList.h" /** * perform walks on the grid based on some sort of weighting @@ -38,7 +39,7 @@ private: DrawList drawer; /** fast random-number-generator */ - std::minstd_rand gen; + RandomGenerator gen; /** 0-mean normal distribution */ std::normal_distribution headingChangeDist = std::normal_distribution(0.0, HEADING_CHANGE_SIGMA); diff --git a/grid/walk/GridWalkWeighted2.h b/grid/walk/GridWalkWeighted2.h index 04cb09f..26a8456 100644 --- a/grid/walk/GridWalkWeighted2.h +++ b/grid/walk/GridWalkWeighted2.h @@ -5,7 +5,9 @@ #include "../Grid.h" #include "../../math/DrawList.h" -#include +#include "../../math/Random.h" + +//#include /** * perform walks on the grid based on some sort of weighting @@ -38,7 +40,7 @@ private: DrawList drawer; /** fast random-number-generator */ - std::minstd_rand gen; + RandomGenerator gen; /** 0-mean normal distribution */ std::normal_distribution headingChangeDist = std::normal_distribution(0.0, HEADING_CHANGE_SIGMA); diff --git a/grid/walk/TestWalkWeighted3.h b/grid/walk/TestWalkWeighted3.h index 84f98dc..c8eec62 100644 --- a/grid/walk/TestWalkWeighted3.h +++ b/grid/walk/TestWalkWeighted3.h @@ -5,7 +5,9 @@ #include "../Grid.h" #include "../../math/DrawList.h" -#include +#include "../../math/Random.h" + +//#include /** * perform walks on the grid based on some sort of weighting @@ -38,7 +40,7 @@ private: DrawList drawer; /** fast random-number-generator */ - std::minstd_rand gen; + RandomGenerator gen; /** 0-mean normal distribution */ std::normal_distribution headingChangeDist = std::normal_distribution(0.0, HEADING_CHANGE_SIGMA); diff --git a/math/DrawList.h b/math/DrawList.h index a9d3b36..6107b04 100644 --- a/math/DrawList.h +++ b/math/DrawList.h @@ -2,8 +2,8 @@ #define DRAWLIST_H #include -#include +#include "Random.h" #include "../Assertions.h" /** @@ -38,7 +38,7 @@ private: std::vector elements; /** random number generator */ - std::minstd_rand gen; + RandomGenerator gen; public: diff --git a/math/Random.h b/math/Random.h new file mode 100644 index 0000000..6c1393d --- /dev/null +++ b/math/Random.h @@ -0,0 +1,28 @@ +#ifndef RANDOM_H +#define RANDOM_H + +#include +#include +#include "../misc/Time.h" + +#ifdef USE_FIXED_SEED + #define RANDOM_SEED 1234 +#else + #define RANDOM_SEED ( std::chrono::system_clock::now().time_since_epoch() / std::chrono::milliseconds(1) ) +#endif + +//using RandomGenerator = std::minstd_rand; + +class RandomGenerator : public std::minstd_rand { + +public: + + /** ctor with default seed */ + RandomGenerator() : std::minstd_rand(RANDOM_SEED) {;} + + /** ctor with custom seed */ + RandomGenerator(result_type) : std::minstd_rand(RANDOM_SEED) {;} + +}; + +#endif // RANDOM_H diff --git a/math/distribution/Exponential.h b/math/distribution/Exponential.h index f00f410..db5dabe 100644 --- a/math/distribution/Exponential.h +++ b/math/distribution/Exponential.h @@ -3,7 +3,7 @@ #include #include - +#include "../Random.h" namespace Distribution { @@ -14,13 +14,13 @@ namespace Distribution { const T lambda; - std::minstd_rand gen; + RandomGenerator gen; std::exponential_distribution dist; public: /** ctor */ - Exponential(const T lambda) : lambda(lambda), dist(lambda) { + Exponential(const T lambda) : lambda(lambda), gen(RANDOM_SEED), dist(lambda) { ; } diff --git a/math/distribution/Normal.h b/math/distribution/Normal.h index 4f12a41..893d456 100644 --- a/math/distribution/Normal.h +++ b/math/distribution/Normal.h @@ -3,6 +3,7 @@ #include #include +#include "../Random.h" namespace Distribution { @@ -15,14 +16,14 @@ namespace Distribution { const T sigma; const T _a; - std::minstd_rand gen; + RandomGenerator gen; std::normal_distribution dist; public: /** ctor */ Normal(const T mu, const T sigma) : - mu(mu), sigma(sigma), _a(1.0 / (sigma * std::sqrt(2.0 * M_PI))), gen(1234), dist(mu,sigma) { + mu(mu), sigma(sigma), _a(1.0 / (sigma * std::sqrt(2.0 * M_PI))), gen(RANDOM_SEED), dist(mu,sigma) { } diff --git a/math/distribution/Uniform.h b/math/distribution/Uniform.h index 550aabd..d6011fe 100644 --- a/math/distribution/Uniform.h +++ b/math/distribution/Uniform.h @@ -3,6 +3,9 @@ #include #include +#include "../Random.h" + +#include namespace Distribution { @@ -11,14 +14,17 @@ namespace Distribution { private: - std::minstd_rand gen; - std::uniform_real_distribution dist; + RandomGenerator gen; + + /** depending on T, Dist is either a uniform_real or uniform_int distribution */ + typedef typename std::conditional< std::is_floating_point::value, std::uniform_real_distribution, std::uniform_int_distribution >::type Dist; + Dist dist; + public: /** ctor */ - Uniform(const T min, const T max) : - gen(1234), dist(min, max) { + Uniform(const T min, const T max) : gen(RANDOM_SEED), dist(min, max) { } /** get a uniformaly distributed random number */ diff --git a/tests/geo/TestHeading.cpp b/tests/geo/TestHeading.cpp index 679f7de..44ab787 100644 --- a/tests/geo/TestHeading.cpp +++ b/tests/geo/TestHeading.cpp @@ -52,13 +52,13 @@ TEST(Heading, eq) { } -TEST(Heading, random) { +//TEST(Heading, random) { - // two random values must not be equal - ASSERT_NE(Heading::rnd(), Heading::rnd()); - ASSERT_NE(Heading::rnd(), Heading::rnd()); - ASSERT_NE(Heading::rnd(), Heading::rnd()); +// // two random values must not be equal +// ASSERT_NE(Heading::rnd(), Heading::rnd()); +// ASSERT_NE(Heading::rnd(), Heading::rnd()); +// ASSERT_NE(Heading::rnd(), Heading::rnd()); -} +//} #endif diff --git a/tests/math/TestDistribution.cpp b/tests/math/TestDistribution.cpp index 5498f2f..7c65c53 100644 --- a/tests/math/TestDistribution.cpp +++ b/tests/math/TestDistribution.cpp @@ -2,6 +2,26 @@ #include "../Tests.h" #include "../../math/Distributions.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) { @@ -15,4 +35,69 @@ TEST(Distribution, Exp) { } +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); + +} + + + + + +//#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); +} + #endif