From d9af08b0499d82cd480181555a82ceb7b7663108 Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Sun, 24 Apr 2016 15:08:51 -0400 Subject: [PATCH 1/2] Make sure a < b Copied this assertion from boost::random::uniform_real_distribution. --- include/boost/compute/random/uniform_real_distribution.hpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/include/boost/compute/random/uniform_real_distribution.hpp b/include/boost/compute/random/uniform_real_distribution.hpp index 231b0dba0..91d150b68 100644 --- a/include/boost/compute/random/uniform_real_distribution.hpp +++ b/include/boost/compute/random/uniform_real_distribution.hpp @@ -36,10 +36,12 @@ class uniform_real_distribution /// Creates a new uniform distribution producing numbers in the range /// [\p a, \p b). + /// Requires a < b uniform_real_distribution(RealType a = 0.f, RealType b = 1.f) : m_a(a), m_b(b) { + BOOST_ASSERT(a < b); } /// Destroys the uniform_real_distribution object. From 81b826d42a1568b754caa183d85aca84ae7fbafa Mon Sep 17 00:00:00 2001 From: Jason Rhinelander Date: Sun, 24 Apr 2016 15:10:19 -0400 Subject: [PATCH 2/2] Use nextafter to shift result off upper bound Currently b::c::r::uniform_real_distribution can produce a variate equal to the upper bound, which is wrong: it is supposed to (and claims to) produce values in [LO,HI), not [LO,HI], but when the random unsigned int draw equals UINT_MAX (or values close to it, with the rounding introduced by RealType = float), we get the upper limit, HI. This commit applies nextafter to the result to shift the result towards LO by the smallest amount possible, which therefore ensures that our maximum is now the largest representable value that is strictly less than HI. If we generate a value of LO (from a random uint of 0), we end up calling nextafter(LO, LO), which equals LO, so this will indeed conform to the [LO,HI) interval. --- include/boost/compute/random/uniform_real_distribution.hpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/include/boost/compute/random/uniform_real_distribution.hpp b/include/boost/compute/random/uniform_real_distribution.hpp index 91d150b68..3491d3c0c 100644 --- a/include/boost/compute/random/uniform_real_distribution.hpp +++ b/include/boost/compute/random/uniform_real_distribution.hpp @@ -71,7 +71,9 @@ class uniform_real_distribution { BOOST_COMPUTE_FUNCTION(RealType, scale_random, (const uint_ x), { - return LO + (convert_RealType(x) / MAX_RANDOM) * (HI - LO); + // Use nextafter to shift the result slightly towards LO to avoid being able to get a + // value of exactly HI. + return nextafter(LO + (convert_RealType(x) / MAX_RANDOM) * (HI - LO), LO); }); scale_random.define("LO", detail::make_literal(m_a));