Minor modifications (eoRng function increment_position(), tests file and
compilation/installation script). Failed tests: From SMP: t-smpMW_eoEasyEA (OTHER_FAULT) From EOMPI (issue #34): t-mpi-parallelApply (OTHER_FAULT) t-mpi-wrapper (NUMERICAL) t-mpi-multipleRoles (OTHER_FAULT) t-mpi-distrib-exp (OTHER_FAULT)
This commit is contained in:
parent
6b464f7fa6
commit
34be39f0aa
3 changed files with 47 additions and 43 deletions
|
|
@ -137,7 +137,7 @@ if [ "$res" = "y" ]; then
|
||||||
fi #ENABLE_64_BIT_RNG_NUMBERS
|
fi #ENABLE_64_BIT_RNG_NUMBERS
|
||||||
|
|
||||||
else
|
else
|
||||||
FLAG=$FLAG' '" -DENABLE_CXX11_RANDOM=false"
|
FLAG=$FLAG' '" -DENABLE_CXX11_RANDOM=false -DENABLE_64_BIT_RNG_NUMBERS=false"
|
||||||
fi #ENABLE_CXX11_RANDOM
|
fi #ENABLE_CXX11_RANDOM
|
||||||
|
|
||||||
color 5 "set $FLAG"
|
color 5 "set $FLAG"
|
||||||
|
|
|
||||||
|
|
@ -55,17 +55,15 @@ Old contact information: todos@geneura.ugr.es, http://geneura.ugr.es
|
||||||
#include "../eoPersistent.h"
|
#include "../eoPersistent.h"
|
||||||
#include "../eoObject.h"
|
#include "../eoObject.h"
|
||||||
|
|
||||||
#ifdef HAVE_RANDOM
|
|
||||||
#include <random> // Mersenne Twister available since C++11 ! About random library :
|
|
||||||
// "this library allows to produce random numbers using combinations of generators and distributions".
|
|
||||||
// (see www.cplusplus.com/reference/random/)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if (UINT_MAX == 0xFFFFFFFFU) // Compile time check (32-bit vs. 64-bit environment)
|
#if (UINT_MAX == 0xFFFFFFFFU) // Compile time check (32-bit vs. 64-bit environment)
|
||||||
#define ENV32BIT
|
#define ENV32BIT
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef HAVE_RANDOM // If set to true (see CMake cache values)
|
#ifdef HAVE_RANDOM // If set to true (see CMake cache values)
|
||||||
|
#include <random> // Mersenne Twister available since C++11 ! About random library :
|
||||||
|
// "this library allows to produce random numbers using combinations of generators and distributions".
|
||||||
|
// (see www.cplusplus.com/reference/random/)
|
||||||
|
|
||||||
#ifndef ENV32BIT // Only on 64-bit environment
|
#ifndef ENV32BIT // Only on 64-bit environment
|
||||||
#ifdef WITH_64_BIT_RNG_NUMBERS // If set to true (see CMake cache values)
|
#ifdef WITH_64_BIT_RNG_NUMBERS // If set to true (see CMake cache values)
|
||||||
typedef uint64_t uint_t; // The C++11 Mersenne Twister pseudo-random generator can generate 64-bits numbers !
|
typedef uint64_t uint_t; // The C++11 Mersenne Twister pseudo-random generator can generate 64-bits numbers !
|
||||||
|
|
@ -150,7 +148,7 @@ public :
|
||||||
*/
|
*/
|
||||||
eoRng(uint_t s)
|
eoRng(uint_t s)
|
||||||
#ifdef HAVE_RANDOM
|
#ifdef HAVE_RANDOM
|
||||||
: seed(s), position(0)
|
: seed(s), position(0), discard (false)
|
||||||
{
|
{
|
||||||
generator.seed(s); // initialize the internal state value
|
generator.seed(s); // initialize the internal state value
|
||||||
}
|
}
|
||||||
|
|
@ -181,9 +179,10 @@ public :
|
||||||
void reseed(uint_t s)
|
void reseed(uint_t s)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_RANDOM
|
#ifdef HAVE_RANDOM
|
||||||
seed = s;
|
seed = 2*s;
|
||||||
position = 0;
|
position = 0;
|
||||||
generator.seed(s); // re-initialize the internal state value
|
discard = false;
|
||||||
|
generator.seed(seed); // re-initialize the internal state value
|
||||||
#else
|
#else
|
||||||
initialize(2*s);
|
initialize(2*s);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -229,7 +228,7 @@ public :
|
||||||
double uniform(double min, double max)
|
double uniform(double min, double max)
|
||||||
{ // random number between [min, max]
|
{ // random number between [min, max]
|
||||||
#ifdef HAVE_RANDOM
|
#ifdef HAVE_RANDOM
|
||||||
increment_position();
|
discard = true;
|
||||||
std::uniform_real_distribution<double> distribution(min, max);
|
std::uniform_real_distribution<double> distribution(min, max);
|
||||||
return distribution(generator);
|
return distribution(generator);
|
||||||
#else
|
#else
|
||||||
|
|
@ -300,15 +299,9 @@ public :
|
||||||
double normal(double mean, double stdev)
|
double normal(double mean, double stdev)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_RANDOM
|
#ifdef HAVE_RANDOM
|
||||||
// Don't increment the position here ...
|
discard = true;
|
||||||
std::normal_distribution<double> distribution(mean, stdev);
|
std::normal_distribution<double> distribution(mean, stdev);
|
||||||
double ret = distribution(generator);
|
return distribution(generator);
|
||||||
// ... but reseed the generator and call discard() to go further into the state sequence.
|
|
||||||
generator.seed(seed);
|
|
||||||
generator.discard(position); // According to the C++11 random library documentation
|
|
||||||
// the function complexity will be linear in the
|
|
||||||
// number of equivalent advances
|
|
||||||
return ret;
|
|
||||||
#else
|
#else
|
||||||
return mean + normal(stdev);
|
return mean + normal(stdev);
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -322,7 +315,7 @@ public :
|
||||||
double negexp(double mean)
|
double negexp(double mean)
|
||||||
{
|
{
|
||||||
#ifdef HAVE_RANDOM
|
#ifdef HAVE_RANDOM
|
||||||
increment_position();
|
discard = true;
|
||||||
std::exponential_distribution<double> distribution(mean);
|
std::exponential_distribution<double> distribution(mean);
|
||||||
return distribution(generator);
|
return distribution(generator);
|
||||||
#else
|
#else
|
||||||
|
|
@ -404,10 +397,7 @@ public :
|
||||||
#ifdef HAVE_RANDOM
|
#ifdef HAVE_RANDOM
|
||||||
_is >> seed;
|
_is >> seed;
|
||||||
_is >> position;
|
_is >> position;
|
||||||
generator.seed(seed);
|
discard = true;
|
||||||
generator.discard(position); // According to the C++11 random library documentation
|
|
||||||
// the function complexity will be linear in the
|
|
||||||
// number of equivalent advances
|
|
||||||
#else
|
#else
|
||||||
for (int i = 0; i < N; ++i)
|
for (int i = 0; i < N; ++i)
|
||||||
{
|
{
|
||||||
|
|
@ -448,8 +438,18 @@ public :
|
||||||
void increment_position()
|
void increment_position()
|
||||||
{
|
{
|
||||||
if (position >= generator.state_size)
|
if (position >= generator.state_size)
|
||||||
|
{
|
||||||
|
generator.seed(seed);
|
||||||
position = 1;
|
position = 1;
|
||||||
else
|
discard = false;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (discard)
|
||||||
|
{
|
||||||
|
generator.seed(seed);
|
||||||
|
generator.discard(position); // linear complexity
|
||||||
|
discard = false;
|
||||||
|
}
|
||||||
++position;
|
++position;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -499,6 +499,8 @@ private:
|
||||||
unsigned position; // Position of the last generated number into the state sequence
|
unsigned position; // Position of the last generated number into the state sequence
|
||||||
// (one of the two requested parameters for the serialization)
|
// (one of the two requested parameters for the serialization)
|
||||||
|
|
||||||
|
bool discard; // Call discard() after using a distribution
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
uint_t restart();
|
uint_t restart();
|
||||||
|
|
|
||||||
|
|
@ -41,12 +41,13 @@ void basic_tests()
|
||||||
void test_function(const unsigned N, uint_t(eoRng::*ptr)())
|
void test_function(const unsigned N, uint_t(eoRng::*ptr)())
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << rng; // Print eoRNG on stream
|
rng.rand();
|
||||||
uint_t r1 = (rng.*ptr)();
|
|
||||||
for (unsigned i = 0; i < N; i++)
|
for (unsigned i = 0; i < N; i++)
|
||||||
(rng.*ptr)();
|
(rng.*ptr)();
|
||||||
|
ss << rng; // Print eoRNG on stream
|
||||||
|
uint_t r1 = rng.rand();
|
||||||
ss >> rng; // Read eoRNG from stream
|
ss >> rng; // Read eoRNG from stream
|
||||||
uint_t r2 = (rng.*ptr)();
|
uint_t r2 = rng.rand();
|
||||||
|
|
||||||
assert(r1 == r2);
|
assert(r1 == r2);
|
||||||
}
|
}
|
||||||
|
|
@ -54,12 +55,13 @@ void test_function(const unsigned N, uint_t(eoRng::*ptr)())
|
||||||
void test_function(const unsigned N, double(eoRng::*ptr)(double), const double m)
|
void test_function(const unsigned N, double(eoRng::*ptr)(double), const double m)
|
||||||
{
|
{
|
||||||
std::stringstream ss;
|
std::stringstream ss;
|
||||||
ss << rng; // Print eoRNG on stream
|
rng.rand();
|
||||||
uint_t r1 = (rng.*ptr)(m);
|
|
||||||
for (unsigned i = 0; i < N; i++)
|
for (unsigned i = 0; i < N; i++)
|
||||||
(rng.*ptr)(m);
|
(rng.*ptr)(m);
|
||||||
|
ss << rng; // Print eoRNG on stream
|
||||||
|
uint_t r1 = rng.rand();
|
||||||
ss >> rng; // Read eoRNG from stream
|
ss >> rng; // Read eoRNG from stream
|
||||||
uint_t r2 = (rng.*ptr)(m);
|
uint_t r2 = rng.rand();
|
||||||
|
|
||||||
assert(r1 == r2);
|
assert(r1 == r2);
|
||||||
}
|
}
|
||||||
|
|
@ -176,7 +178,7 @@ void stat_tests(const unsigned N)
|
||||||
double p_value = PyFloat_AsDouble(PyTuple_GetItem(pResult, 1));
|
double p_value = PyFloat_AsDouble(PyTuple_GetItem(pResult, 1));
|
||||||
std::cout << "Shapiro-Wilk test statistic:" << W << std::endl;
|
std::cout << "Shapiro-Wilk test statistic:" << W << std::endl;
|
||||||
std::cout << "p-value of the Shapiro-Wilk test (strong if < 0.05):" << p_value << std::endl;
|
std::cout << "p-value of the Shapiro-Wilk test (strong if < 0.05):" << p_value << std::endl;
|
||||||
//Py_DECREF(pResult);
|
Py_DECREF(pResult);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Free allocated memory
|
// Free allocated memory
|
||||||
|
|
@ -206,10 +208,10 @@ void stat_tests(const unsigned N)
|
||||||
|
|
||||||
for (unsigned i = 0; i < N; i++)
|
for (unsigned i = 0; i < N; i++)
|
||||||
{
|
{
|
||||||
// Important : don't forget to reseed the generator
|
// // Important : don't forget to reseed the generator
|
||||||
s = static_cast<uint_t>(time(0) + i-1); // Chosen method to reseed generator (contestable):
|
// s = static_cast<uint_t>(time(0) + i-1); // Chosen method to reseed generator (contestable):
|
||||||
// Add i-1 seconds to the current time based on the current system
|
// // Add i-1 seconds to the current time based on the current system
|
||||||
rng.reseed(s);
|
// rng.reseed(s);
|
||||||
|
|
||||||
// Observed frequencies
|
// Observed frequencies
|
||||||
obs_freq[i] = rng.uniform();
|
obs_freq[i] = rng.uniform();
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue