aboutsummaryrefslogtreecommitdiffhomepage
path: root/Eigen/src
diff options
context:
space:
mode:
authorGravatar Gael Guennebaud <g.gael@free.fr>2015-03-19 15:10:36 +0100
committerGravatar Gael Guennebaud <g.gael@free.fr>2015-03-19 15:10:36 +0100
commitf329d0908af35fd17bdc4dfeb87046dcaa6e6937 (patch)
tree7544488c7ffe9e2ea4ee8be1f45847bd41fc67f4 /Eigen/src
parentcc0f89eb3b07c65efb2b73890e4e7ac83525700a (diff)
Improve random number generation for integer and add unit test
Diffstat (limited to 'Eigen/src')
-rw-r--r--Eigen/src/Core/MathFunctions.h34
1 files changed, 15 insertions, 19 deletions
diff --git a/Eigen/src/Core/MathFunctions.h b/Eigen/src/Core/MathFunctions.h
index 0fde5c71e..e1b233d82 100644
--- a/Eigen/src/Core/MathFunctions.h
+++ b/Eigen/src/Core/MathFunctions.h
@@ -522,28 +522,24 @@ struct meta_floor_log2<n, lower, upper, meta_floor_log2_bogus>
template<typename Scalar>
struct random_default_impl<Scalar, false, true>
{
- typedef typename NumTraits<Scalar>::NonInteger NonInteger;
-
static inline Scalar run(const Scalar& x, const Scalar& y)
{
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;
+ using std::min;
+ typedef typename conditional<NumTraits<Scalar>::IsSigned,std::ptrdiff_t,std::size_t>::type ScalarX;
+ if(y<x)
+ return x;
+ std::size_t range = ScalarX(y)-ScalarX(x);
+ std::size_t offset = 0;
+ // rejection sampling
+ std::size_t divisor = (range+RAND_MAX-1)/(range+1);
+ std::size_t multiplier = (range+RAND_MAX-1)/std::size_t(RAND_MAX);
+
+ do {
+ offset = ( (std::size_t(std::rand()) * multiplier) / divisor );
+ } while (offset > range);
+
+ return Scalar(ScalarX(x) + offset);
}
static inline Scalar run()