Make sure uint32_t is defined correctly in eoRNG.h and use it where
appropriate.
This commit is contained in:
parent
462fbaad66
commit
6e0c4a7264
13 changed files with 238 additions and 220 deletions
|
|
@ -1,6 +1,6 @@
|
|||
/*
|
||||
* Random number generator adapted from (see comments below)
|
||||
*
|
||||
*
|
||||
* The random number generator is modified into a class
|
||||
* by Maarten Keijzer (mak@dhi.dk). Also added the Box-Muller
|
||||
* transformation to generate normal deviates.
|
||||
|
|
@ -70,7 +70,7 @@
|
|||
//
|
||||
|
||||
//
|
||||
// uint32 must be an unsigned integer type capable of holding at least 32
|
||||
// uint32_t must be an unsigned integer type capable of holding at least 32
|
||||
// bits; exactly 32 should be fastest, but 64 is better on an Alpha with
|
||||
// GCC at -O3 optimization so try your options and see what's best for you
|
||||
//
|
||||
|
|
@ -81,6 +81,12 @@
|
|||
#ifndef EO_RANDOM_NUMBER_GENERATOR
|
||||
#define EO_RANDOM_NUMBER_GENERATOR
|
||||
|
||||
#ifdef HAVE_CONFIG_H
|
||||
#include <config.h>
|
||||
#endif
|
||||
#ifdef HAVE_INTTYPES_H
|
||||
#include <inttypes.h>
|
||||
#endif
|
||||
|
||||
#include "../eoPersistent.h"
|
||||
#include "../eoObject.h"
|
||||
|
|
@ -89,7 +95,14 @@
|
|||
// Unfortunately MSVC's preprocessor does not comprehend sizeof()
|
||||
// so neat preprocessing tricks will not work
|
||||
|
||||
typedef unsigned long uint32; // Compiler and platform dependent!
|
||||
#if(! (defined HAVE_UINT32_T))
|
||||
#if(SIZEOF_UNSIGNED_LONG == 4)
|
||||
typedef unsigned long uint32_t;
|
||||
#else
|
||||
#error Need to provide a type for uint32_t in eoRNG.h.
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// eoRng
|
||||
|
|
@ -101,7 +114,7 @@ for generating random numbers. The various member functions implement useful fun
|
|||
for evolutionary algorithms. Included are: rand(), random(), flip() and normal().
|
||||
|
||||
Note for people porting EO to other platforms: please make sure that the typedef
|
||||
uint32 in the file eoRng.h is exactly 32 bits long. It may be longer, but not
|
||||
uint32_t in the file eoRng.h is exactly 32 bits long. It may be longer, but not
|
||||
shorter. If it is longer, file compatibility between EO on different platforms
|
||||
may be broken.
|
||||
*/
|
||||
|
|
@ -113,8 +126,8 @@ public :
|
|||
@see reseed to see why the parameter to initialize is doubled
|
||||
*/
|
||||
|
||||
eoRng(uint32 s) : state(0), next(0), left(-1), cached(false), N(624), M(397), K(0x9908B0DFU) {
|
||||
state = new uint32[N+1];
|
||||
eoRng(uint32_t s) : state(0), next(0), left(-1), cached(false), N(624), M(397), K(0x9908B0DFU) {
|
||||
state = new uint32_t[N+1];
|
||||
initialize(2*s);
|
||||
}
|
||||
|
||||
|
|
@ -130,10 +143,10 @@ public :
|
|||
* the argument to reseed is now doubled before being passed on.
|
||||
*
|
||||
* Manually divide the seed by 2 if you want to re-run old runs
|
||||
*
|
||||
*
|
||||
* MS. 5 Oct. 2001
|
||||
*/
|
||||
void reseed(uint32 s)
|
||||
void reseed(uint32_t s)
|
||||
{
|
||||
initialize(2*s);
|
||||
}
|
||||
|
|
@ -141,7 +154,7 @@ public :
|
|||
/**
|
||||
Re-initializes the Random Number Generator - old version
|
||||
*/
|
||||
void oldReseed(uint32 s)
|
||||
void oldReseed(uint32_t s)
|
||||
{
|
||||
initialize(s);
|
||||
}
|
||||
|
|
@ -153,37 +166,37 @@ public :
|
|||
{ // random number between [0, m]
|
||||
return m * double(rand()) / double(1.0 + rand_max());
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
random() returns a random integer in the range [0, m)
|
||||
*/
|
||||
uint32 random(uint32 m)
|
||||
uint32_t random(uint32_t m)
|
||||
{
|
||||
return uint32(uniform() * double(m));
|
||||
return uint32_t(uniform() * double(m));
|
||||
}
|
||||
|
||||
/**
|
||||
flip() tosses a biased coin such that flip(x/100.0) will
|
||||
flip() tosses a biased coin such that flip(x/100.0) will
|
||||
returns true x% of the time
|
||||
*/
|
||||
bool flip(float bias=0.5)
|
||||
{
|
||||
return uniform() < bias;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
normal() zero mean gaussian deviate with standard deviation of 1
|
||||
*/
|
||||
double normal(void); // gaussian mutation, stdev 1
|
||||
double normal(void); // gaussian mutation, stdev 1
|
||||
|
||||
/**
|
||||
normal(stdev) zero mean gaussian deviate with user defined standard deviation
|
||||
*/
|
||||
double normal(double stdev)
|
||||
double normal(double stdev)
|
||||
{
|
||||
return stdev * normal();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
normal(mean, stdev) user defined mean gaussian deviate with user defined standard deviation
|
||||
*/
|
||||
|
|
@ -203,13 +216,13 @@ public :
|
|||
/**
|
||||
rand() returns a random number in the range [0, rand_max)
|
||||
*/
|
||||
uint32 rand();
|
||||
|
||||
uint32_t rand();
|
||||
|
||||
/**
|
||||
rand_max() the maximum returned by rand()
|
||||
*/
|
||||
uint32 rand_max(void) const { return (uint32) 0xffffffff; }
|
||||
|
||||
uint32_t rand_max(void) const { return (uint32_t) 0xffffffff; }
|
||||
|
||||
/**
|
||||
roulette_wheel(vec, total = 0) does a roulette wheel selection
|
||||
on the input std::vector vec. If the total is not supplied, it is
|
||||
|
|
@ -219,11 +232,11 @@ public :
|
|||
int roulette_wheel(const std::vector<T>& vec, T total = 0)
|
||||
{
|
||||
if (total == 0)
|
||||
{ // count
|
||||
{ // count
|
||||
for (unsigned i = 0; i < vec.size(); ++i)
|
||||
total += vec[i];
|
||||
}
|
||||
|
||||
|
||||
double fortune = uniform() * total;
|
||||
int i = 0;
|
||||
|
||||
|
|
@ -231,19 +244,19 @@ public :
|
|||
{
|
||||
fortune -= vec[i++];
|
||||
}
|
||||
|
||||
|
||||
return --i;
|
||||
}
|
||||
|
||||
/**
|
||||
/**
|
||||
* choice(vec), returns a uniformly chosen element from the vector
|
||||
*/
|
||||
template <class T>
|
||||
const T& choice(const std::vector<T>& vec) { return vec[rng.random(vec.size())]; }
|
||||
|
||||
|
||||
template <class T>
|
||||
T& choice(std::vector<T>& vec) { return vec[rng.random(vec.size())]; }
|
||||
|
||||
|
||||
///
|
||||
void printOn(std::ostream& _os) const
|
||||
{
|
||||
|
|
@ -275,11 +288,11 @@ public :
|
|||
std::string className(void) const { return "Mersenne-Twister"; }
|
||||
|
||||
private :
|
||||
uint32 restart(void);
|
||||
void initialize(uint32 seed);
|
||||
uint32_t restart(void);
|
||||
void initialize(uint32_t seed);
|
||||
|
||||
uint32* state; // the array for the state
|
||||
uint32* next;
|
||||
uint32_t* state; // the array for the state
|
||||
uint32_t* next;
|
||||
int left;
|
||||
|
||||
// for normal distribution
|
||||
|
|
@ -288,7 +301,7 @@ private :
|
|||
|
||||
const int N;
|
||||
const int M;
|
||||
const uint32 K; // a magic constant
|
||||
const uint32_t K; // a magic constant
|
||||
|
||||
|
||||
/**
|
||||
|
|
@ -319,7 +332,7 @@ using eo::rng;
|
|||
#define loBits(u) ((u) & 0x7FFFFFFFU) // mask the highest bit of u
|
||||
#define mixBits(u, v) (hiBit(u)|loBits(v)) // move hi bit of u to hi bit of v
|
||||
|
||||
inline void eoRng::initialize(uint32 seed)
|
||||
inline void eoRng::initialize(uint32_t seed)
|
||||
{
|
||||
//
|
||||
// We initialize state[0..(N-1)] via the generator
|
||||
|
|
@ -369,7 +382,7 @@ inline void eoRng::initialize(uint32 seed)
|
|||
|
||||
left = -1;
|
||||
|
||||
register uint32 x = (seed | 1U) & 0xFFFFFFFFU, *s = state;
|
||||
register uint32_t x = (seed | 1U) & 0xFFFFFFFFU, *s = state;
|
||||
register int j;
|
||||
|
||||
for(left=0, *s++=x, j=N; --j;
|
||||
|
|
@ -377,9 +390,9 @@ inline void eoRng::initialize(uint32 seed)
|
|||
}
|
||||
|
||||
|
||||
inline uint32 eoRng::restart(void)
|
||||
inline uint32_t eoRng::restart(void)
|
||||
{
|
||||
register uint32 *p0=state, *p2=state+2, *pM=state+M, s0, s1;
|
||||
register uint32_t *p0=state, *p2=state+2, *pM=state+M, s0, s1;
|
||||
register int j;
|
||||
|
||||
left=N-1, next=state+1;
|
||||
|
|
@ -397,10 +410,10 @@ inline uint32 eoRng::restart(void)
|
|||
return(s1 ^ (s1 >> 18));
|
||||
}
|
||||
|
||||
inline uint32 eoRng::rand(void)
|
||||
inline uint32_t eoRng::rand(void)
|
||||
{
|
||||
|
||||
uint32 y;
|
||||
uint32_t y;
|
||||
|
||||
if(--left < 0)
|
||||
return(restart());
|
||||
|
|
@ -428,20 +441,20 @@ inline double eoRng::normal(void)
|
|||
var2 = 2.0 * uniform() - 1.0;
|
||||
|
||||
rSquare = var1 * var1 + var2 * var2;
|
||||
}
|
||||
}
|
||||
while (rSquare >= 1.0 || rSquare == 0.0);
|
||||
|
||||
|
||||
factor = sqrt(-2.0 * log(rSquare) / rSquare);
|
||||
|
||||
|
||||
cacheValue = var1 * factor;
|
||||
cached = true;
|
||||
|
||||
|
||||
return (var2 * factor);
|
||||
}
|
||||
|
||||
namespace eo {
|
||||
// a few convenience functions for generating numbers
|
||||
|
||||
|
||||
/**
|
||||
* Templatized random function, works with most basic types such as:
|
||||
* char
|
||||
|
|
@ -453,7 +466,7 @@ namespace eo {
|
|||
template <typename T>
|
||||
inline
|
||||
T random(const T& mx) { return static_cast<T>(rng.uniform() * mx); }
|
||||
|
||||
|
||||
/** Normal distribution */
|
||||
inline double normal() { return rng.normal(); }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
normal_generator : normally distributed floats or doubles
|
||||
|
||||
(c) Maarten Keijzer (mak@dhi.dk) and GeNeura Team, 1999, 2000
|
||||
|
||||
|
||||
This library is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser General Public
|
||||
License as published by the Free Software Foundation; either
|
||||
|
|
@ -36,26 +36,26 @@
|
|||
|
||||
/**
|
||||
The class uniform_generator can be used in the STL generate function
|
||||
to easily generate random floats and doubles
|
||||
either in [0, _max) if only 1 value (_max) is given
|
||||
to easily generate random floats and doubles
|
||||
either in [0, _max) if only 1 value (_max) is given
|
||||
(or none, as _max defaults to 1.0)
|
||||
or in [_min,_max) if 2 values are given (_min, _max)
|
||||
*/
|
||||
template <class T = double> class uniform_generator
|
||||
{
|
||||
// added new ctor with 2 params, and modified the data to minim and range
|
||||
// added new ctor with 2 params, and modified the data to minim and range
|
||||
// (was maxim only). MS 3/11/2000
|
||||
public :
|
||||
uniform_generator(T _max = T(1.0), eoRng& _rng = rng) :
|
||||
uniform_generator(T _max = T(1.0), eoRng& _rng = rng) :
|
||||
minim(T(0.0)), range(_max), uniform(_rng) {}
|
||||
uniform_generator(T _min, T _max, eoRng& _rng = rng) :
|
||||
minim(_min), range(_max-_min), uniform(_rng)
|
||||
uniform_generator(T _min, T _max, eoRng& _rng = rng) :
|
||||
minim(_min), range(_max-_min), uniform(_rng)
|
||||
{
|
||||
if (_min>_max)
|
||||
throw std::logic_error("Min is greater than Max in uniform_generator");
|
||||
throw std::logic_error("Min is greater than Max in uniform_generator");
|
||||
}
|
||||
|
||||
T operator()(void) { return minim+static_cast<T>(uniform.uniform(range)); }
|
||||
|
||||
T operator()(void) { return minim+static_cast<T>(uniform.uniform(range)); }
|
||||
|
||||
private :
|
||||
T minim;
|
||||
|
|
@ -71,8 +71,8 @@ class boolean_generator
|
|||
{
|
||||
public :
|
||||
boolean_generator(float _bias = 0.5, eoRng& _rng = rng) : bias(_bias), gen(_rng) {}
|
||||
|
||||
bool operator()(void) { return gen.flip(bias); }
|
||||
|
||||
bool operator()(void) { return gen.flip(bias); }
|
||||
private :
|
||||
float bias;
|
||||
eoRng& gen;
|
||||
|
|
@ -80,26 +80,26 @@ class boolean_generator
|
|||
|
||||
/**
|
||||
The class random_generator can be used in the STL generate function
|
||||
to easily generate random ints
|
||||
to easily generate random ints
|
||||
either between [0, _max) if only one value (_max) is given to the ctor
|
||||
or in [_min,_max) if 2 values are given (_min, _max)
|
||||
*/
|
||||
template <class T = uint32> class random_generator
|
||||
template <class T = uint32_t> class random_generator
|
||||
{
|
||||
public :
|
||||
// added new ctor with 2 params, and modified the data to minim and range
|
||||
// added new ctor with 2 params, and modified the data to minim and range
|
||||
// (was maxim only). MS 3/11/2000
|
||||
random_generator(T _max, eoRng& _rng = rng) :
|
||||
random_generator(T _max, eoRng& _rng = rng) :
|
||||
minim(T(0.0)), range(_max), random(_rng) {}
|
||||
random_generator(T _min, T _max, eoRng& _rng = rng) :
|
||||
minim(_min), range(_max-_min), random(_rng)
|
||||
random_generator(T _min, T _max, eoRng& _rng = rng) :
|
||||
minim(_min), range(_max-_min), random(_rng)
|
||||
{
|
||||
if (_min>_max)
|
||||
throw std::logic_error("Min is greater than Max in random_generator");
|
||||
throw std::logic_error("Min is greater than Max in random_generator");
|
||||
}
|
||||
|
||||
|
||||
T operator()(void) { return (T) (minim + random.random(range)); }
|
||||
|
||||
|
||||
private :
|
||||
T minim;
|
||||
T range;
|
||||
|
|
@ -114,18 +114,18 @@ inline bool random_generator<bool>::operator()(void)
|
|||
}
|
||||
|
||||
/**
|
||||
Another class random_generator that can be used in the STL random_shuffle
|
||||
function (see eoPop::shuffle): its operator() takes an unsigned argument m
|
||||
Another class random_generator that can be used in the STL random_shuffle
|
||||
function (see eoPop::shuffle): its operator() takes an unsigned argument m
|
||||
and must return an unsigned uniformly distributed in [0,m}
|
||||
*/
|
||||
template <class T = uint32> class UF_random_generator
|
||||
template <class T = uint32_t> class UF_random_generator
|
||||
{
|
||||
public :
|
||||
UF_random_generator(eoRng& _rng = rng) :
|
||||
UF_random_generator(eoRng& _rng = rng) :
|
||||
random(_rng) {}
|
||||
|
||||
|
||||
T operator()(T _t) { return (T) (random.random(_t)); }
|
||||
|
||||
|
||||
private :
|
||||
eoRng& random;
|
||||
};
|
||||
|
|
@ -140,9 +140,9 @@ template <class T = double> class normal_generator
|
|||
{
|
||||
public :
|
||||
normal_generator(T _stdev = T(1.0), eoRng& _rng = rng) : stdev(_stdev), normal(_rng) {}
|
||||
|
||||
|
||||
T operator()(void) { return (T) normal.normal(stdev); }
|
||||
|
||||
|
||||
private :
|
||||
T stdev;
|
||||
eoRng& normal;
|
||||
|
|
@ -157,9 +157,9 @@ template <class T = double> class negexp_generator
|
|||
{
|
||||
public :
|
||||
negexp_generator(T _mean = 1.0, eoRng& _rng = rng) : mean(_mean), negexp(_rng) {}
|
||||
|
||||
|
||||
T operator()(void) { return (T) negexp.negexp(mean); }
|
||||
|
||||
|
||||
private :
|
||||
T mean;
|
||||
eoRng& negexp;
|
||||
|
|
|
|||
Reference in a new issue