From 8f55ead48d58ee4040e5b44623e5b0437b57913f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Kamil=20=C5=9Aliwak?= Date: Wed, 3 Jun 2020 13:52:37 +0200 Subject: [PATCH] yul-phaser: Switch from uint32_t to size_t in SimulationRNG - Also pass the appriopriate type internally to the distribution instead of relying on the default (which is uint32_t) --- tools/yulPhaser/GeneticAlgorithms.cpp | 2 +- tools/yulPhaser/SimulationRNG.cpp | 27 ++++++++++++++++++--------- tools/yulPhaser/SimulationRNG.h | 4 ++-- 3 files changed, 21 insertions(+), 12 deletions(-) diff --git a/tools/yulPhaser/GeneticAlgorithms.cpp b/tools/yulPhaser/GeneticAlgorithms.cpp index 1da31645f..4a90503aa 100644 --- a/tools/yulPhaser/GeneticAlgorithms.cpp +++ b/tools/yulPhaser/GeneticAlgorithms.cpp @@ -155,7 +155,7 @@ Population ClassicGeneticAlgorithm::select(Population _population, size_t _selec vector selectedIndividuals; for (size_t i = 0; i < _selectionSize; ++i) { - uint32_t ball = SimulationRNG::uniformInt(0, rouletteRange - 1); + size_t ball = SimulationRNG::uniformInt(0, rouletteRange - 1); size_t cumulativeFitness = 0; for (auto const& individual: _population.individuals()) diff --git a/tools/yulPhaser/SimulationRNG.cpp b/tools/yulPhaser/SimulationRNG.cpp index 2b596f4ed..26f438909 100644 --- a/tools/yulPhaser/SimulationRNG.cpp +++ b/tools/yulPhaser/SimulationRNG.cpp @@ -17,12 +17,17 @@ #include +// NOTE: The code would work with std::random but the results for a given seed would not be reproducible +// across different STL implementations. Boost does not guarantee this either but at least it has only one +// implementation. Reproducibility is not a hard requirement for yul-phaser but it's nice to have. #include #include #include #include +#include +using namespace std; using namespace solidity; using namespace solidity::phaser; @@ -30,23 +35,27 @@ thread_local boost::random::mt19937 SimulationRNG::s_generator(SimulationRNG::ge bool SimulationRNG::bernoulliTrial(double _successProbability) { - boost::random::bernoulli_distribution<> distribution(_successProbability); + boost::random::bernoulli_distribution distribution(_successProbability); - return static_cast(distribution(s_generator)); -} - -uint32_t SimulationRNG::uniformInt(uint32_t _min, uint32_t _max) -{ - boost::random::uniform_int_distribution<> distribution(_min, _max); return distribution(s_generator); } -uint32_t SimulationRNG::binomialInt(uint32_t _numTrials, double _successProbability) +size_t SimulationRNG::uniformInt(size_t _min, size_t _max) { - boost::random::binomial_distribution<> distribution(_numTrials, _successProbability); + boost::random::uniform_int_distribution distribution(_min, _max); return distribution(s_generator); } +size_t SimulationRNG::binomialInt(size_t _numTrials, double _successProbability) +{ + // NOTE: binomial_distribution would not work because it internally tries to use abs() + // and fails to compile due to ambiguous conversion. + assert(_numTrials <= static_cast(numeric_limits::max())); + + boost::random::binomial_distribution distribution(static_cast(_numTrials), _successProbability); + return static_cast(distribution(s_generator)); +} + uint32_t SimulationRNG::generateSeed() { // This is not a secure way to seed the generator but it's good enough for simulation purposes. diff --git a/tools/yulPhaser/SimulationRNG.h b/tools/yulPhaser/SimulationRNG.h index 1e8a1da18..d16189f9e 100644 --- a/tools/yulPhaser/SimulationRNG.h +++ b/tools/yulPhaser/SimulationRNG.h @@ -38,8 +38,8 @@ class SimulationRNG { public: static bool bernoulliTrial(double _successProbability); - static uint32_t uniformInt(uint32_t _min, uint32_t _max); - static uint32_t binomialInt(uint32_t _numTrials, double _successProbability); + static size_t uniformInt(size_t _min, size_t _max); + static size_t binomialInt(size_t _numTrials, double _successProbability); /// Resets generator to a known state given by the @a seed. Given the same seed, a fixed /// sequence of calls to the members generating random values is guaranteed to produce the