Skip to content
This repository has been archived by the owner on Aug 2, 2022. It is now read-only.

Fix #34 - deterministic_randomness test failures #40

Merged
merged 1 commit into from
Jun 26, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 15 additions & 9 deletions libraries/utilities/include/eos/utilities/randutils.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,9 @@
#include <thread>
#include <algorithm>

#include <boost/random/uniform_int_distribution.hpp>
#include <boost/random/uniform_real_distribution.hpp>

// Ugly platform-specific code for auto_seeded

#if !defined(RANDUTILS_CPU_ENTROPY) && defined(__has_builtin)
Expand Down Expand Up @@ -572,8 +575,8 @@ using auto_seed_256 = auto_seeded<seed_seq_fe256>;
template <typename Numeric>
using uniform_distribution = typename std::conditional<
std::is_integral<Numeric>::value,
std::uniform_int_distribution<Numeric>,
std::uniform_real_distribution<Numeric> >::type;
boost::random::uniform_int_distribution<Numeric>,
boost::random::uniform_real_distribution<Numeric> >::type;



Expand Down Expand Up @@ -730,16 +733,19 @@ class random_generator {
std::forward<Params>(params)...);
}

template <typename Iter>
void shuffle(Iter first, Iter last)
{
std::shuffle(first, last, engine_);
}

template <typename Range>
void shuffle(Range&& range)
{
shuffle(std::begin(range), std::end(range));
// Fisher-Yates shuffle algorithm
int idx_count = range.size();
for (auto idx = range.rbegin(); idx != range.rend() - 1; ++idx , --idx_count)
{
int rand_idx = uniform(0, idx_count - 1);
if (*idx != range.at(rand_idx))
{
std::swap(range.at(rand_idx), *idx);
}
}
}


Expand Down
37 changes: 34 additions & 3 deletions tests/tests/misc_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,43 @@ BOOST_AUTO_TEST_CASE(deterministic_randomness)
vector<string> words = {"infamy", "invests", "estimated", "potters", "memorizes", "hal9000"};
rng.shuffle(words);
BOOST_CHECK_EQUAL(fc::json::to_string(words),
fc::json::to_string(vector<string>{"potters","hal9000","memorizes","infamy","invests","estimated"}));
fc::json::to_string(vector<string>{"hal9000","infamy","estimated","memorizes","invests","potters"}));
rng.shuffle(words);
BOOST_CHECK_EQUAL(fc::json::to_string(words),
fc::json::to_string(vector<string>{"memorizes","hal9000","infamy","invests","estimated","potters"}));
BOOST_CHECK_EQUAL(fc::json::to_string(words),
fc::json::to_string(vector<string>{"hal9000","estimated","infamy","memorizes","potters","invests"}));
} FC_LOG_AND_RETHROW() }

BOOST_AUTO_TEST_CASE(deterministic_distributions)
{ try {
randutils::seed_seq_fe<1> seed({123454321});
randutils::random_generator<pcg32_fast> rng(seed);

std::vector<int> nums = {0, 1, 2};

BOOST_CHECK_EQUAL(rng.uniform(0.0, 1.0), 0.52802440151572227);
BOOST_CHECK_EQUAL(rng.uniform(0.0, 1.0), 0.36562641779892147);
BOOST_CHECK_EQUAL(rng.uniform(0.0, 1.0), 0.44247416267171502);

BOOST_CHECK_EQUAL(rng.pick(nums), 2);
BOOST_CHECK_EQUAL(rng.pick(nums), 0);
BOOST_CHECK_EQUAL(rng.pick(nums), 2);

rng.shuffle(nums);
std::vector<int> a{0, 1, 2};
BOOST_CHECK(std::equal(nums.begin(), nums.end(), a.begin()));
rng.shuffle(nums);
std::vector<int> b{0, 2, 1};
BOOST_CHECK(std::equal(nums.begin(), nums.end(), b.begin()));
rng.shuffle(nums);
std::vector<int> c{1, 0, 2};
BOOST_CHECK(std::equal(nums.begin(), nums.end(), c.begin()));

BOOST_CHECK_EQUAL(rng.uniform(0, 9), 2);
BOOST_CHECK_EQUAL(rng.uniform(0, 9), 9);
BOOST_CHECK_EQUAL(rng.uniform(0, 9), 0);
} FC_LOG_AND_RETHROW() }


BOOST_AUTO_TEST_SUITE_END()

} // namespace eos