37 #ifndef VIGRA_RANDOM_HXX 
   38 #define VIGRA_RANDOM_HXX 
   40 #include "mathutil.hxx" 
   41 #include "functortraits.hxx" 
   42 #include "array_vector.hxx" 
   49   #include <vigra/windows.h>   
   54   #include <sys/syscall.h>   
   59   #include <sys/syscall.h>           
   60   #include <AvailabilityMacros.h>    
   65 enum RandomSeedTag { RandomSeed };
 
   69 enum RandomEngineTag { TT800, MT19937 };
 
   72 template<RandomEngineTag EngineTag>
 
   75 template <RandomEngineTag EngineTag>
 
   76 void seed(
UInt32 theSeed, RandomState<EngineTag> & engine)
 
   78     engine.state_[0] = theSeed;
 
   79     for(
UInt32 i=1; i<RandomState<EngineTag>::N; ++i)
 
   81         engine.state_[i] = 1812433253U * (engine.state_[i-1] ^ (engine.state_[i-1] >> 30)) + i;
 
   85 template <
class Iterator, RandomEngineTag EngineTag>
 
   86 void seed(Iterator init, 
UInt32 key_length, RandomState<EngineTag> & engine)
 
   88     const UInt32 N = RandomState<EngineTag>::N;
 
   89     int k = 
static_cast<int>(std::max(N, key_length));
 
   94         engine.state_[i] = (engine.state_[i] ^ ((engine.state_[i-1] ^ (engine.state_[i-1] >> 30)) * 1664525U))
 
  100             engine.state_[0] = engine.state_[N-1]; 
 
  112         engine.state_[i] = (engine.state_[i] ^ ((engine.state_[i-1] ^ (engine.state_[i-1] >> 30)) * 1566083941U))
 
  117             engine.state_[0] = engine.state_[N-1]; 
 
  122     engine.state_[0] = 0x80000000U;  
 
  125 template <RandomEngineTag EngineTag>
 
  126 void seed(RandomSeedTag, RandomState<EngineTag> & engine)
 
  128     static UInt32 globalCount = 0;
 
  129     ArrayVector<UInt32> seedData;
 
  131     seedData.push_back(static_cast<UInt32>(time(0)));
 
  132     seedData.push_back(static_cast<UInt32>(clock()));
 
  133     seedData.push_back(++globalCount);
 
  135     std::size_t ptr((
char*)&engine - (
char*)0);
 
  136     seedData.push_back(static_cast<UInt32>((ptr & 0xffffffff)));
 
  137     static const UInt32 shift = 
sizeof(ptr) > 4 ? 32 : 16;
 
  138     seedData.push_back(static_cast<UInt32>((ptr >> shift)));
 
  141     seedData.push_back(static_cast<UInt32>(GetCurrentProcessId()));
 
  142     seedData.push_back(static_cast<UInt32>(GetCurrentThreadId()));
 
  146     seedData.push_back(static_cast<UInt32>(getpid()));
 
  148     seedData.push_back(static_cast<UInt32>(syscall(SYS_gettid)));
 
  153     seedData.push_back(static_cast<UInt32>(getpid()));
 
  154   #if defined(SYS_thread_selfid) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6) 
  156     seedData.push_back(static_cast<UInt32>(syscall(SYS_thread_selfid)));
 
  160     seed(seedData.begin(), seedData.size(), engine);
 
  165 struct RandomState<TT800>
 
  167     static const UInt32 N = 25, M = 7;
 
  176             0x95f24dab, 0x0b685215, 0xe76ccae7, 0xaf3ec239, 0x715fad23,
 
  177             0x24a590ad, 0x69e4b5ef, 0xbf456141, 0x96bc1b7b, 0xa7bdf825,
 
  178             0xc1de75b7, 0x8858a9c9, 0x2da87693, 0xb657f9dd, 0xffdc8a9f,
 
  179             0x8121da71, 0x8b823ecb, 0x885d05f5, 0x4e20cd47, 0x5a9ad5d9,
 
  180             0x512c0c03, 0xea857ccd, 0x4cc1d30f, 0x8891a8a1, 0xa6b7aadb
 
  184             state_[i] = seeds[i];
 
  192             generateNumbers<void>();
 
  194         UInt32 y = state_[current_++];
 
  195         y ^= (y << 7) & 0x2b5b2500; 
 
  196         y ^= (y << 15) & 0xdb8b0000; 
 
  197         return y ^ (y >> 16);
 
  200     template <
class DUMMY>
 
  201     void generateNumbers() 
const;
 
  203     void seedImpl(RandomSeedTag)
 
  205         seed(RandomSeed, *
this);
 
  208     void seedImpl(
UInt32 theSeed)
 
  210         seed(theSeed, *
this);
 
  213     template<
class Iterator>
 
  214     void seedImpl(Iterator init, 
UInt32 length)
 
  216         seed(init, length, *
this);
 
  220 template <
class DUMMY>
 
  221 void RandomState<TT800>::generateNumbers()
 const 
  223     UInt32 mag01[2]= { 0x0, 0x8ebfd028 };
 
  225     for(
UInt32 i=0; i<N-M; ++i)
 
  227         state_[i] = state_[i+M] ^ (state_[i] >> 1) ^ mag01[state_[i] % 2];
 
  229     for (
UInt32 i=N-M; i<N; ++i) 
 
  231         state_[i] = state_[i+(M-N)] ^ (state_[i] >> 1) ^ mag01[state_[i] % 2];
 
  238 struct RandomState<MT19937>
 
  240     static const UInt32 N = 624, M = 397;
 
  248         seed(19650218U, *
this);
 
  256             generateNumbers<void>();
 
  258         UInt32 x = state_[current_++];
 
  260         x ^= (x << 7) & 0x9D2C5680U;
 
  261         x ^= (x << 15) & 0xEFC60000U;
 
  262         return x ^ (x >> 18);
 
  265     template <
class DUMMY>
 
  266     void generateNumbers() 
const;
 
  270         return (((u & 0x80000000U) | (v & 0x7FFFFFFFU)) >> 1)
 
  271                 ^ ((v & 1U) ? 0x9908B0DFU : 0x0U);
 
  274     void seedImpl(RandomSeedTag)
 
  276         seed(RandomSeed, *
this);
 
  277         generateNumbers<void>();
 
  280     void seedImpl(
UInt32 theSeed)
 
  282         seed(theSeed, *
this);
 
  283         generateNumbers<void>();
 
  286     template<
class Iterator>
 
  287     void seedImpl(Iterator init, 
UInt32 length)
 
  289         seed(19650218U, *
this);
 
  290         seed(init, length, *
this);
 
  291         generateNumbers<void>();
 
  295 template <
class DUMMY>
 
  296 void RandomState<MT19937>::generateNumbers()
 const 
  298     for (
unsigned int i = 0; i < (N - M); ++i)
 
  300         state_[i] = state_[i + M] ^ twiddle(state_[i], state_[i + 1]);
 
  302     for (
unsigned int i = N - M; i < (N - 1); ++i)
 
  304         state_[i] = state_[i + M - N] ^ twiddle(state_[i], state_[i + 1]);
 
  306     state_[N - 1] = state_[M - 1] ^ twiddle(state_[N - 1], state_[0]);
 
  335 template <
class Engine = detail::RandomState<detail::MT19937> >
 
  339     mutable double normalCached_;
 
  340     mutable bool normalCachedValid_;
 
  350     : normalCached_(0.0),
 
  351       normalCachedValid_(false)
 
  365     : normalCached_(0.0),
 
  366       normalCachedValid_(false)
 
  368         this->seedImpl(RandomSeed);
 
  381     : normalCached_(0.0),
 
  382       normalCachedValid_(false)
 
  385             this->seedImpl(RandomSeed);
 
  387             this->seedImpl(theSeed);
 
  395     template<
class Iterator>
 
  397     : normalCached_(0.0),
 
  398       normalCachedValid_(false)
 
  400         this->seedImpl(init, length);
 
  418         this->seedImpl(RandomSeed);
 
  419         normalCachedValid_ = 
false;
 
  433             this->seedImpl(RandomSeed);
 
  435             this->seedImpl(theSeed);
 
  436         normalCachedValid_ = 
false;
 
  444     template<
class Iterator>
 
  447         this->seedImpl(init, length);
 
  448         normalCachedValid_ = 
false;
 
  470 #if 0 // difficult implementation necessary if low bits are not sufficiently random 
  477         UInt32 factor = factorForUniformInt(beyond);
 
  478         UInt32 res = this->
get() / factor;
 
  483             res = this->
get() / factor;
 
  499         UInt32 remainder = (NumericTraits<UInt32>::max() - beyond + 1) % beyond;
 
  500         UInt32 lastSafeValue = NumericTraits<UInt32>::max() - remainder;
 
  505         while(res > lastSafeValue)
 
  518         return ( (this->
get() >> 5) * 67108864.0 + (this->
get() >> 6)) * (1.0/9007199254740992.0); 
 
  528         return static_cast<double>(this->
get()) / 4294967295.0;
 
  536     double uniform(
double lower, 
double upper)
 const 
  538         vigra_precondition(lower < upper,
 
  539           "RandomNumberGenerator::uniform(): lower bound must be smaller than upper bound."); 
 
  540         return uniform() * (upper-lower) + lower;
 
  554     double normal(
double mean, 
double stddev)
 const 
  556         vigra_precondition(stddev > 0.0,
 
  557           "RandomNumberGenerator::normal(): standard deviation must be positive."); 
 
  558         return normal()*stddev + mean;
 
  573         return (range > 2147483648U || range == 0)
 
  581 template <
class Engine>
 
  582 RandomNumberGenerator<Engine> RandomNumberGenerator<Engine>::global_(RandomSeed);
 
  585 template <
class Engine>
 
  588     if(normalCachedValid_)
 
  590         normalCachedValid_ = 
false;
 
  591         return normalCached_;
 
  598              x1 = uniform(-1.0, 1.0);
 
  599              x2 = uniform(-1.0, 1.0);
 
  600              w = x1 * x1 + x2 * x2;
 
  602         while ( w > 1.0 || w == 0.0);
 
  606         normalCached_ = x2 * w;
 
  607         normalCachedValid_ = 
true;
 
  637 template <
class Engine>
 
  638 class FunctorTraits<RandomNumberGenerator<Engine> >
 
  641     typedef RandomNumberGenerator<Engine> type;
 
  643     typedef VigraTrueType  isInitializer;
 
  645     typedef VigraFalseType isUnaryFunctor;
 
  646     typedef VigraFalseType isBinaryFunctor;
 
  647     typedef VigraFalseType isTernaryFunctor;
 
  649     typedef VigraFalseType isUnaryAnalyser;
 
  650     typedef VigraFalseType isBinaryAnalyser;
 
  651     typedef VigraFalseType isTernaryAnalyser;
 
  668 template <
class Engine = MersenneTwister>
 
  671     UInt32 lower_, difference_, factor_;
 
  672     Engine 
const & generator_;
 
  686     : lower_(0), difference_(0xffffffff), factor_(1),
 
  687       generator_(generator),
 
  701                             Engine 
const & generator = Engine::global(),
 
  702                             bool useLowBits = 
true)
 
  703     : lower_(lower), difference_(upper-lower), 
 
  704       factor_(Engine::factorForUniformInt(difference_ + 1)),
 
  705       generator_(generator),
 
  706       useLowBits_(useLowBits)
 
  708         vigra_precondition(lower < upper,
 
  709           "UniformIntRandomFunctor(): lower bound must be smaller than upper bound."); 
 
  716         if(difference_ == 0xffffffff) 
 
  719             return generator_.uniformInt(difference_+1) + lower_;
 
  722             UInt32 res = generator_() / factor_;
 
  726             while(res > difference_)
 
  727                 res = generator_() / factor_;
 
  743         return generator_.uniformInt(beyond);
 
  747 template <
class Engine>
 
  748 class FunctorTraits<UniformIntRandomFunctor<Engine> >
 
  751     typedef UniformIntRandomFunctor<Engine> type;
 
  753     typedef VigraTrueType  isInitializer;
 
  755     typedef VigraTrueType  isUnaryFunctor;
 
  756     typedef VigraFalseType isBinaryFunctor;
 
  757     typedef VigraFalseType isTernaryFunctor;
 
  759     typedef VigraFalseType isUnaryAnalyser;
 
  760     typedef VigraFalseType isBinaryAnalyser;
 
  761     typedef VigraFalseType isTernaryAnalyser;
 
  775 template <
class Engine = MersenneTwister>
 
  778     double offset_, scale_;
 
  779     Engine 
const & generator_;
 
  793       generator_(generator)
 
  802                          Engine & generator = Engine::global())
 
  804       scale_(upper - lower),
 
  805       generator_(generator)
 
  807         vigra_precondition(lower < upper,
 
  808           "UniformRandomFunctor(): lower bound must be smaller than upper bound."); 
 
  815         return generator_.uniform() * scale_ + offset_;
 
  819 template <
class Engine>
 
  820 class FunctorTraits<UniformRandomFunctor<Engine> >
 
  823     typedef UniformRandomFunctor<Engine> type;
 
  825     typedef VigraTrueType  isInitializer;
 
  827     typedef VigraFalseType isUnaryFunctor;
 
  828     typedef VigraFalseType isBinaryFunctor;
 
  829     typedef VigraFalseType isTernaryFunctor;
 
  831     typedef VigraFalseType isUnaryAnalyser;
 
  832     typedef VigraFalseType isBinaryAnalyser;
 
  833     typedef VigraFalseType isTernaryAnalyser;
 
  847 template <
class Engine = MersenneTwister>
 
  850     double mean_, stddev_;
 
  851     Engine 
const & generator_;
 
  865       generator_(generator)
 
  872                         Engine & generator = Engine::global())
 
  875       generator_(generator)
 
  877         vigra_precondition(stddev > 0.0,
 
  878           "NormalRandomFunctor(): standard deviation must be positive."); 
 
  885         return generator_.normal() * stddev_ + mean_;
 
  890 template <
class Engine>
 
  891 class FunctorTraits<NormalRandomFunctor<Engine> >
 
  894     typedef UniformRandomFunctor<Engine>  type;
 
  896     typedef VigraTrueType  isInitializer;
 
  898     typedef VigraFalseType isUnaryFunctor;
 
  899     typedef VigraFalseType isBinaryFunctor;
 
  900     typedef VigraFalseType isTernaryFunctor;
 
  902     typedef VigraFalseType isUnaryAnalyser;
 
  903     typedef VigraFalseType isBinaryAnalyser;
 
  904     typedef VigraFalseType isTernaryAnalyser;
 
  911 #endif // VIGRA_RANDOM_HXX 
UInt32 uniformInt() const 
Definition: random.hxx:464
void seed(RandomSeedTag)
Definition: random.hxx:416
void seed(Iterator init, UInt32 length)
Definition: random.hxx:445
double uniform(double lower, double upper) const 
Definition: random.hxx:536
double normal(double mean, double stddev) const 
Definition: random.hxx:554
NormalRandomFunctor(double mean, double stddev, Engine &generator=Engine::global())
Definition: random.hxx:871
double normal() const 
Definition: random.hxx:586
RandomNumberGenerator(Iterator init, UInt32 length)
Definition: random.hxx:396
UInt32 uniformInt(UInt32 beyond) const 
Definition: random.hxx:492
double uniform53() const 
Definition: random.hxx:515
double result_type
STL required functor result type. 
Definition: random.hxx:855
RandomMT19937 & randomMT19937()
Definition: random.hxx:635
RandomTT800 & randomTT800()
Definition: random.hxx:631
RandomNumberGenerator< detail::RandomState< detail::TT800 > > RandomTT800
Definition: random.hxx:615
static RandomNumberGenerator & global()
Definition: random.hxx:566
double uniform() const 
Definition: random.hxx:526
RandomNumberGenerator< detail::RandomState< detail::TT800 > > TemperedTwister
Definition: random.hxx:619
Definition: random.hxx:848
RandomNumberGenerator()
Definition: random.hxx:349
UInt32 operator()() const 
Definition: random.hxx:455
double operator()() const 
Definition: random.hxx:883
linalg::TemporaryMatrix< T > log(MultiArrayView< 2, T, C > const &v)
RandomNumberGenerator< detail::RandomState< detail::MT19937 > > RandomMT19937
Definition: random.hxx:623
NormalRandomFunctor(Engine const &generator=Engine::global())
Definition: random.hxx:862
detail::SelectIntegerType< 32, detail::UnsignedIntTypes >::type UInt32
32-bit unsigned int 
Definition: sized_int.hxx:183
RandomNumberGenerator(UInt32 theSeed, bool ignoreSeed=false)
Definition: random.hxx:380
Definition: random.hxx:336
RandomNumberGenerator< detail::RandomState< detail::MT19937 > > MersenneTwister
Definition: random.hxx:627
UInt32 ceilPower2(UInt32 x)
Round up to the nearest power of 2. 
Definition: mathutil.hxx:294
RandomNumberGenerator(RandomSeedTag)
Definition: random.hxx:364
SquareRootTraits< FixedPoint< IntBits, FracBits > >::SquareRootResult sqrt(FixedPoint< IntBits, FracBits > v)
square root. 
Definition: fixedpoint.hxx:616
void seed(UInt32 theSeed, bool ignoreSeed=false)
Definition: random.hxx:430