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