diff options
author | 2015-03-13 21:12:46 +0100 | |
---|---|---|
committer | 2015-03-13 21:12:46 +0100 | |
commit | d99ab35f9e886a014be6d47606d232af1e668f76 (patch) | |
tree | 5c6e647b2847104aa4cfba7765a5663dce569b84 /Eigen/src/Core/MathFunctions.h | |
parent | 8580eb6808428a53d5fb91be23fb5c6c8c9e9463 (diff) |
Fix internal::random(x,y) for integer types. The previous implementation could return y+1. The new implementation uses rejection sampling to get an unbiased behabior.
Diffstat (limited to 'Eigen/src/Core/MathFunctions.h')
-rw-r--r-- | Eigen/src/Core/MathFunctions.h | 21 |
1 files changed, 19 insertions, 2 deletions
diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h index 878f38e92..3c76a58b9 100644 --- a/Eigen/src/Core/MathFunctions.h +++ b/Eigen/src/Core/MathFunctions.h @@ -525,8 +525,25 @@ struct random_default_impl<Scalar, false, true> typedef typename NumTraits<Scalar>::NonInteger NonInteger; static inline Scalar run(const Scalar& x, const Scalar& y) - { - return x + Scalar((NonInteger(y)-x+1) * std::rand() / (RAND_MAX + NonInteger(1))); + { + using std::max; + Scalar range = (max)(Scalar(0),Scalar(y-x)); + Scalar offset = 0; + if(range<=RAND_MAX) + { + // rejection sampling + int divisor = RAND_MAX/(range+1); + + do { + offset = Scalar(std::rand() / divisor); + } while (offset > range); + } + else + { + offset = std::rand() * range; + } + + return x + offset; } static inline Scalar run() |