vigra - vigra/random.hxx Source File

[ VIGRA Homepage | Function Index | Class Index | Namespaces | File List | Main Page ]

random.hxx |

1 /************************************************************************/
2 /* */
3 /* Copyright 2008 by Ullrich Koethe */
4 /* */
5 /* This file is part of the VIGRA computer vision library. */
6 /* The VIGRA Website is */
7 /* http://hci.iwr.uni-heidelberg.de/vigra/ */
8 /* Please direct questions, bug reports, and contributions to */
9 /* ullrich.koethe@iwr.uni-heidelberg.de or */
10 /* vigra@informatik.uni-hamburg.de */
11 /* */
12 /* Permission is hereby granted, free of charge, to any person */
13 /* obtaining a copy of this software and associated documentation */
14 /* files (the "Software"), to deal in the Software without */
15 /* restriction, including without limitation the rights to use, */
16 /* copy, modify, merge, publish, distribute, sublicense, and/or */
17 /* sell copies of the Software, and to permit persons to whom the */
18 /* Software is furnished to do so, subject to the following */
19 /* conditions: */
20 /* */
21 /* The above copyright notice and this permission notice shall be */
22 /* included in all copies or substantial portions of the */
23 /* Software. */
24 /* */
25 /* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND */
26 /* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES */
27 /* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND */
28 /* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT */
29 /* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, */
30 /* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING */
31 /* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR */
32 /* OTHER DEALINGS IN THE SOFTWARE. */
33 /* */
34 /************************************************************************/
35
36
37 #ifndef VIGRA_RANDOM_HXX
38 #define VIGRA_RANDOM_HXX
39
40 #include "mathutil.hxx"
41 #include "functortraits.hxx"
42 #include "array_vector.hxx"
43
44 #include <ctime>
45
46 // includes to get the current process and thread IDs
47 // to be used for automated seeding
48 #ifdef _MSC_VER
49 #include <vigra/windows.h> // for GetCurrentProcessId() and GetCurrentThreadId()
50 #endif
51
52 #if __linux__
53 #include <unistd.h> // for getpid()
54 #include <sys/syscall.h> // for SYS_gettid
55 #endif
56
57 #if __APPLE__
58 #include <unistd.h> // for getpid()
59 #include <sys/syscall.h> // SYS_thread_selfid
60 #include <AvailabilityMacros.h> // to check if we are on MacOS 10.6 or later
61 #endif
62
63 namespace vigra {
64
65 enum RandomSeedTag { RandomSeed };
66
67 namespace detail {
68
69 enum RandomEngineTag { TT800, MT19937 };
70
71
72 template<RandomEngineTag EngineTag>
73 struct RandomState;
74
75 template <RandomEngineTag EngineTag>
76 void seed(UInt32 theSeed, RandomState<EngineTag> & engine)
77 {
78 engine.state_[0] = theSeed;
79 for(UInt32 i=1; i<RandomState<EngineTag>::N; ++i)
80 {
81 engine.state_[i] = 1812433253U * (engine.state_[i-1] ^ (engine.state_[i-1] >> 30)) + i;
82 }
83 }
84
85 template <class Iterator, RandomEngineTag EngineTag>
86 void seed(Iterator init, UInt32 key_length, RandomState<EngineTag> & engine)
87 {
88 const UInt32 N = RandomState<EngineTag>::N;
89 int k = (int)std::max(N, key_length);
90 UInt32 i = 1, j = 0;
91 Iterator data = init;
92 for (; k; --k)
93 {
94 engine.state_[i] = (engine.state_[i] ^ ((engine.state_[i-1] ^ (engine.state_[i-1] >> 30)) * 1664525U))
95 + *data + j; /* non linear */
96 ++i; ++j; ++data;
97
98 if (i >= N)
99 {
100 engine.state_[0] = engine.state_[N-1];
101 i=1;
102 }
103 if (j>=key_length)
104 {
105 j=0;
106 data = init;
107 }
108 }
109
110 for (k=N-1; k; --k)
111 {
112 engine.state_[i] = (engine.state_[i] ^ ((engine.state_[i-1] ^ (engine.state_[i-1] >> 30)) * 1566083941U))
113 - i; /* non linear */
114 ++i;
115 if (i>=N)
116 {
117 engine.state_[0] = engine.state_[N-1];
118 i=1;
119 }
120 }
121
122 engine.state_[0] = 0x80000000U; /* MSB is 1; assuring non-zero initial array */
123 }
124
125 template <RandomEngineTag EngineTag>
126 void seed(RandomSeedTag, RandomState<EngineTag> & engine)
127 {
128 static UInt32 globalCount = 0;
129 ArrayVector<UInt32> seedData;
130
131 seedData.push_back((UInt32)time(0));
132 seedData.push_back((UInt32)clock());
133 seedData.push_back(++globalCount);
134
135 std::size_t ptr((char*)&engine - (char*)0);
136 seedData.push_back((UInt32)(ptr & 0xffffffff));
137 static const UInt32 shift = sizeof(ptr) > 4 ? 32 : 16;
138 seedData.push_back((UInt32)(ptr >> shift));
139
140 #ifdef _MSC_VER
141 seedData.push_back((UInt32)GetCurrentProcessId());
142 seedData.push_back((UInt32)GetCurrentThreadId());
143 #endif
144
145 #ifdef __linux__
146 seedData.push_back((UInt32)getpid());
147 # ifdef SYS_gettid
148 seedData.push_back((UInt32)syscall(SYS_gettid));
149 # endif
150 #endif
151
152 #ifdef __APPLE__
153 seedData.push_back((UInt32)getpid());
154 #if defined(SYS_thread_selfid) && (MAC_OS_X_VERSION_MIN_REQUIRED >= MAC_OS_X_VERSION_10_6)
155 // SYS_thread_selfid was introduced in MacOS 10.6
156 seedData.push_back((UInt32)syscall(SYS_thread_selfid));
157 #endif
158 #endif
159
160 seed(seedData.begin(), seedData.size(), engine);
161 }
162
163 /* Tempered twister TT800 by M. Matsumoto */
164 template<>
165 struct RandomState<TT800>
166 {
167 static const UInt32 N = 25, M = 7;
168
169 mutable UInt32 state_[N];
170 mutable UInt32 current_;
171
172 RandomState()
173 : current_(0)
174 {
175 UInt32 seeds[N] = {
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
181 };
182
183 for(UInt32 i=0; i<N; ++i)
184 state_[i] = seeds[i];
185 }
186
187 protected:
188
189 UInt32 get() const
190 {
191 if(current_ == N)
192 generateNumbers<void>();
193
194 UInt32 y = state_[current_++];
195 y ^= (y << 7) & 0x2b5b2500;
196 y ^= (y << 15) & 0xdb8b0000;
197 return y ^ (y >> 16);
198 }
199
200 template <class DUMMY>
201 void generateNumbers() const;
202
203 void seedImpl(RandomSeedTag)
204 {
205 seed(RandomSeed, *this);
206 }
207
208 void seedImpl(UInt32 theSeed)
209 {
210 seed(theSeed, *this);
211 }
212
213 template<class Iterator>
214 void seedImpl(Iterator init, UInt32 length)
215 {
216 seed(init, length, *this);
217 }
218 };
219
220 template <class DUMMY>
221 void RandomState<TT800>::generateNumbers() const
222 {
223 UInt32 mag01[2]= { 0x0, 0x8ebfd028 };
224
225 for(UInt32 i=0; i<N-M; ++i)
226 {
227 state_[i] = state_[i+M] ^ (state_[i] >> 1) ^ mag01[state_[i] % 2];
228 }
229 for (UInt32 i=N-M; i<N; ++i)
230 {
231 state_[i] = state_[i+(M-N)] ^ (state_[i] >> 1) ^ mag01[state_[i] % 2];
232 }
233 current_ = 0;
234 }
235
236 /* Mersenne twister MT19937 by M. Matsumoto */
237 template<>
238 struct RandomState<MT19937>
239 {
240 static const UInt32 N = 624, M = 397;
241
242 mutable UInt32 state_[N];
243 mutable UInt32 current_;
244
245 RandomState()
246 : current_(0)
247 {
248 seed(19650218U, *this);
249 }
250
251 protected:
252
253 UInt32 get() const
254 {
255 if(current_ == N)
256 generateNumbers<void>();
257
258 UInt32 x = state_[current_++];
259 x ^= (x >> 11);
260 x ^= (x << 7) & 0x9D2C5680U;
261 x ^= (x << 15) & 0xEFC60000U;
262 return x ^ (x >> 18);
263 }
264
265 template <class DUMMY>
266 void generateNumbers() const;
267
268 static UInt32 twiddle(UInt32 u, UInt32 v)
269 {
270 return (((u & 0x80000000U) | (v & 0x7FFFFFFFU)) >> 1)
271 ^ ((v & 1U) ? 0x9908B0DFU : 0x0U);
272 }
273
274 void seedImpl(RandomSeedTag)
275 {
276 seed(RandomSeed, *this);
277 generateNumbers<void>();
278 }
279
280 void seedImpl(UInt32 theSeed)
281 {
282 seed(theSeed, *this);
283 generateNumbers<void>();
284 }
285
286 template<class Iterator>
287 void seedImpl(Iterator init, UInt32 length)
288 {
289 seed(19650218U, *this);
290 seed(init, length, *this);
291 generateNumbers<void>();
292 }
293 };
294
295 template <class DUMMY>
296 void RandomState<MT19937>::generateNumbers() const
297 {
298 for (unsigned int i = 0; i < (N - M); ++i)
299 {
300 state_[i] = state_[i + M] ^ twiddle(state_[i], state_[i + 1]);
301 }
302 for (unsigned int i = N - M; i < (N - 1); ++i)
303 {
304 state_[i] = state_[i + M - N] ^ twiddle(state_[i], state_[i + 1]);
305 }
306 state_[N - 1] = state_[M - 1] ^ twiddle(state_[N - 1], state_[0]);
307 current_ = 0;
308 }
309
310 } // namespace detail
311
312
313 /** \addtogroup RandomNumberGeneration Random Number Generation
314
315 High-quality random number generators and related functors.
316 */
317 //@{
318
319 /** Generic random number generator.
320
321 The actual generator is passed in the template argument <tt>Engine</tt>. Two generators
322 are currently available:
323 <ul>
324 <li> <tt>RandomMT19937</tt>: The state-of-the-art <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html">Mersenne Twister</a> with a state length of 2<sup>19937</sup> and very high statistical quality.
325 <li> <tt>RandomTT800</tt>: (default) The Tempered Twister, a simpler predecessor of the Mersenne Twister with period length 2<sup>800</sup>.
326 </ul>
327
328 Both generators have been designed by <a href="http://www.math.sci.hiroshima-u.ac.jp/~m-mat/eindex.html">Makoto Matsumoto</a>.
329
330 <b>Traits defined:</b>
331
332 \verbatim FunctorTraits<RandomNumberGenerator<Engine> >::isInitializer \endverbatim
333 is true (<tt>VigraTrueType</tt>).
334 */
335 template <class Engine = detail::RandomState<detail::MT19937> >
336 class RandomNumberGenerator
337 : public Engine
338 {
339 mutable double normalCached_;
340 mutable bool normalCachedValid_;
341
342 public:
343
344 /** Create a new random generator object with standard seed.
345
346 Due to standard seeding, the random numbers generated will always be the same.
347 This is useful for debugging.
348 */
349 RandomNumberGenerator()
350 : normalCached_(0.0),
351 normalCachedValid_(false)
352 {}
353
354 /** Create a new random generator object with a random seed.
355
356 The seed is obtained from the machines current <tt>clock()</tt> and <tt>time()</tt>
357 values.
358
359 <b>Usage:</b>
360 \code
361 RandomNumberGenerator<> rnd = RandomNumberGenerator<>(RandomSeed);
362 \endcode
363 */
364 RandomNumberGenerator(RandomSeedTag)
365 : normalCached_(0.0),
366 normalCachedValid_(false)
367 {
368 this->seedImpl(RandomSeed);
369 }
370
371 /** Create a new random generator object from the given seed.
372
373 The same seed will always produce identical random sequences.
374 If \a ignoreSeed is <tt>true</tt>, the given seed is ignored,
375 and the generator is seeded randomly (as if it was constructed
376 with <tt>RandomNumberGenerator<>(RandomSeed)</tt>). This allows
377 you to switch between random and deterministic seeding at
378 run-time.
379 */
380 RandomNumberGenerator(UInt32 theSeed, bool ignoreSeed=false)
381 : normalCached_(0.0),
382 normalCachedValid_(false)
383 {
384 if(ignoreSeed)
385 this->seedImpl(RandomSeed);
386 else
387 this->seedImpl(theSeed);
388 }
389
390 /** Create a new random generator object from the given seed sequence.
391
392 Longer seed sequences lead to better initialization in the sense that the generator's
393 state space is covered much better than is possible with 32-bit seeds alone.
394 */
395 template<class Iterator>
396 RandomNumberGenerator(Iterator init, UInt32 length)
397 : normalCached_(0.0),
398 normalCachedValid_(false)
399 {
400 this->seedImpl(init, length);
401 }
402
403
404 /** Re-initialize the random generator object with a random seed.
405
406 The seed is obtained from the machines current <tt>clock()</tt> and <tt>time()</tt>
407 values.
408
409 <b>Usage:</b>
410 \code
411 RandomNumberGenerator<> rnd = ...;
412 ...
413 rnd.seed(RandomSeed);
414 \endcode
415 */
416 void seed(RandomSeedTag)
417 {
418 this->seedImpl(RandomSeed);
419 normalCachedValid_ = false;
420 }
421
422 /** Re-initialize the random generator object from the given seed.
423
424 The same seed will always produce identical random sequences.
425 If \a ignoreSeed is <tt>true</tt>, the given seed is ignored,
426 and the generator is seeded randomly (as if <tt>seed(RandomSeed)</tt>
427 was called). This allows you to switch between random and deterministic
428 seeding at run-time.
429 */
430 void seed(UInt32 theSeed, bool ignoreSeed=false)
431 {
432 if(ignoreSeed)
433 this->seedImpl(RandomSeed);
434 else
435 this->seedImpl(theSeed);
436 normalCachedValid_ = false;
437 }
438
439 /** Re-initialize the random generator object from the given seed sequence.
440
441 Longer seed sequences lead to better initialization in the sense that the generator's
442 state space is covered much better than is possible with 32-bit seeds alone.
443 */
444 template<class Iterator>
445 void seed(Iterator init, UInt32 length)
446 {
447 this->seedImpl(init, length);
448 normalCachedValid_ = false;
449 }
450
451 /** Return a uniformly distributed integer random number in [0, 2<sup>32</sup>).
452
453 That is, 0 &lt;= i &lt; 2<sup>32</sup>.
454 */
455 UInt32 operator()() const
456 {
457 return this->get();
458 }
459
460 /** Return a uniformly distributed integer random number in [0, 2<sup>32</sup>).
461
462 That is, 0 &lt;= i &lt; 2<sup>32</sup>.
463 */
464 UInt32 uniformInt() const
465 {
466 return this->get();
467 }
468
469
470 #if 0 // difficult implementation necessary if low bits are not sufficiently random
471 // in [0,beyond)
472 UInt32 uniformInt(UInt32 beyond) const
473 {
474 if(beyond < 2)
475 return 0;
476
477 UInt32 factor = factorForUniformInt(beyond);
478 UInt32 res = this->get() / factor;
479
480 // Use rejection method to avoid quantization bias.
481 // On average, we will need two raw random numbers to generate one.
482 while(res >= beyond)
483 res = this->get() / factor;
484 return res;
485 }
486 #endif /* #if 0 */
487
488 /** Return a uniformly distributed integer random number in [0, <tt>beyond</tt>).
489
490 That is, 0 &lt;= i &lt; <tt>beyond</tt>.
491 */
492 UInt32 uniformInt(UInt32 beyond) const
493 {
494 // in [0,beyond) -- simple implementation when low bits are sufficiently random, which is
495 // the case for TT800 and MT19937
496 if(beyond < 2)
497 return 0;
498
499 UInt32 remainder = (NumericTraits<UInt32>::max() - beyond + 1) % beyond;
500 UInt32 lastSafeValue = NumericTraits<UInt32>::max() - remainder;
501 UInt32 res = this->get();
502
503 // Use rejection method to avoid quantization bias.
504 // We will need two raw random numbers in amortized worst case.
505 while(res > lastSafeValue)
506 res = this->get();
507 return res % beyond;
508 }
509
510 /** Return a uniformly distributed double-precision random number in [0.0, 1.0).
511
512 That is, 0.0 &lt;= i &lt; 1.0. All 53-bit bits of the mantissa are random (two 32-bit integers are used to
513 create this number).
514 */
515 double uniform53() const
516 {
517 // make full use of the entire 53-bit mantissa of a double, by Isaku Wada
518 return ( (this->get() >> 5) * 67108864.0 + (this->get() >> 6)) * (1.0/9007199254740992.0);
519 }
520
521 /** Return a uniformly distributed double-precision random number in [0.0, 1.0].
522
523 That is, 0.0 &lt;= i &lt;= 1.0. This number is computed by <tt>uniformInt()</tt> / (2<sup>32</sup> - 1),
524 so it has effectively only 32 random bits.
525 */
526 double uniform() const
527 {
528 return (double)this->get() / 4294967295.0;
529 }
530
531 /** Return a uniformly distributed double-precision random number in [lower, upper].
532
533 That is, <tt>lower</tt> &lt;= i &lt;= <tt>upper</tt>. This number is computed
534 from <tt>uniform()</tt>, so it has effectively only 32 random bits.
535 */
536 double uniform(double lower, double upper) const
537 {
538 vigra_precondition(lower < upper,
539 "RandomNumberGenerator::uniform(): lower bound must be smaller than upper bound.");
540 return uniform() * (upper-lower) + lower;
541 }
542
543 /** Return a standard normal variate (Gaussian) random number.
544
545 Mean is zero, standard deviation is 1.0. It uses the polar form of the
546 Box-Muller transform.
547 */
548 double normal() const;
549
550 /** Return a normal variate (Gaussian) random number with the given mean and standard deviation.
551
552 It uses the polar form of the Box-Muller transform.
553 */
554 double normal(double mean, double stddev) const
555 {
556 vigra_precondition(stddev > 0.0,
557 "RandomNumberGenerator::normal(): standard deviation must be positive.");
558 return normal()*stddev + mean;
559 }
560
561 /** Access the global (program-wide) instance of the present random number generator.
562
563 Normally, you will create a local generator by one of the constructor calls. But sometimes
564 it is useful to have all program parts access the same generator.
565 */
566 static RandomNumberGenerator & global()
567 {
568 return global_;
569 }
570
571 static UInt32 factorForUniformInt(UInt32 range)
572 {
573 return (range > 2147483648U || range == 0)
574 ? 1
575 : 2*(2147483648U / ceilPower2(range));
576 }
577
578 static RandomNumberGenerator global_;
579 };
580
581 template <class Engine>
582 RandomNumberGenerator<Engine> RandomNumberGenerator<Engine>::global_(RandomSeed);
583
584
585 template <class Engine>
586 double RandomNumberGenerator<Engine>::normal() const
587 {
588 if(normalCachedValid_)
589 {
590 normalCachedValid_ = false;
591 return normalCached_;
592 }
593 else
594 {
595 double x1, x2, w;
596 do
597 {
598 x1 = uniform(-1.0, 1.0);
599 x2 = uniform(-1.0, 1.0);
600 w = x1 * x1 + x2 * x2;
601 }
602 while ( w > 1.0 || w == 0.0);
603
604 w = std::sqrt( -2.0 * std::log( w ) / w );
605
606 normalCached_ = x2 * w;
607 normalCachedValid_ = true;
608
609 return x1 * w;
610 }
611 }
612
613 /** Shorthand for the TT800 random number generator class.
614 */
615 typedef RandomNumberGenerator<detail::RandomState<detail::TT800> > RandomTT800;
616
617 /** Shorthand for the TT800 random number generator class (same as RandomTT800).
618 */
619 typedef RandomNumberGenerator<detail::RandomState<detail::TT800> > TemperedTwister;
620
621 /** Shorthand for the MT19937 random number generator class.
622 */
623 typedef RandomNumberGenerator<detail::RandomState<detail::MT19937> > RandomMT19937;
624
625 /** Shorthand for the MT19937 random number generator class (same as RandomMT19937).
626 */
627 typedef RandomNumberGenerator<detail::RandomState<detail::MT19937> > MersenneTwister;
628
629 /** Access the global (program-wide) instance of the TT800 random number generator.
630 */
631 inline RandomTT800 & randomTT800() { return RandomTT800::global(); }
632
633 /** Access the global (program-wide) instance of the MT19937 random number generator.
634 */
635 inline RandomMT19937 & randomMT19937() { return RandomMT19937::global(); }
636
637 template <class Engine>
638 class FunctorTraits<RandomNumberGenerator<Engine> >
639 {
640 public:
641 typedef RandomNumberGenerator<Engine> type;
642
643 typedef VigraTrueType isInitializer;
644
645 typedef VigraFalseType isUnaryFunctor;
646 typedef VigraFalseType isBinaryFunctor;
647 typedef VigraFalseType isTernaryFunctor;
648
649 typedef VigraFalseType isUnaryAnalyser;
650 typedef VigraFalseType isBinaryAnalyser;
651 typedef VigraFalseType isTernaryAnalyser;
652 };
653
654
655 /** Functor to create uniformly distributed integer random numbers.
656
657 This functor encapsulates the appropriate functions of the given random number
658 <tt>Engine</tt> (usually <tt>RandomTT800</tt> or <tt>RandomMT19937</tt>)
659 in an STL-compatible interface.
660
661 <b>Traits defined:</b>
662
663 \verbatim FunctorTraits<UniformIntRandomFunctor<Engine> >::isInitializer \endverbatim
664 and
665 \verbatim FunctorTraits<UniformIntRandomFunctor<Engine> >::isUnaryFunctor \endverbatim
666 are true (<tt>VigraTrueType</tt>).
667 */
668 template <class Engine = MersenneTwister>
669 class UniformIntRandomFunctor
670 {
671 UInt32 lower_, difference_, factor_;
672 Engine const & generator_;
673 bool useLowBits_;
674
675 public:
676
677 typedef UInt32 argument_type; ///< STL required functor argument type
678 typedef UInt32 result_type; ///< STL required functor result type
679
680 /** Create functor for uniform random integers in the range [0, 2<sup>32</sup>)
681 using the given engine.
682
683 That is, the generated numbers satisfy 0 &lt;= i &lt; 2<sup>32</sup>.
684 */
685 explicit UniformIntRandomFunctor(Engine const & generator = Engine::global() )
686 : lower_(0), difference_(0xffffffff), factor_(1),
687 generator_(generator),
688 useLowBits_(true)
689 {}
690
691 /** Create functor for uniform random integers in the range [<tt>lower</tt>, <tt>upper</tt>]
692 using the given engine.
693
694 That is, the generated numbers satisfy <tt>lower</tt> &lt;= i &lt;= <tt>upper</tt>.
695 \a useLowBits should be set to <tt>false</tt> when the engine generates
696 random numbers whose low bits are significantly less random than the high
697 bits. This does not apply to <tt>RandomTT800</tt> and <tt>RandomMT19937</tt>,
698 but is necessary for simpler linear congruential generators.
699 */
700 UniformIntRandomFunctor(UInt32 lower, UInt32 upper,
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)
707 {
708 vigra_precondition(lower < upper,
709 "UniformIntRandomFunctor(): lower bound must be smaller than upper bound.");
710 }
711
712 /** Return a random number as specified in the constructor.
713 */
714 UInt32 operator()() const
715 {
716 if(difference_ == 0xffffffff) // lower_ is necessarily 0
717 return generator_();
718 else if(useLowBits_)
719 return generator_.uniformInt(difference_+1) + lower_;
720 else
721 {
722 UInt32 res = generator_() / factor_;
723
724 // Use rejection method to avoid quantization bias.
725 // On average, we will need two raw random numbers to generate one.
726 while(res > difference_)
727 res = generator_() / factor_;
728 return res + lower_;
729 }
730 }
731
732 /** Return a uniformly distributed integer random number in the range [0, <tt>beyond</tt>).
733
734 That is, 0 &lt;= i &lt; <tt>beyond</tt>. This is a required interface for
735 <tt>std::random_shuffle</tt>. It ignores the limits specified
736 in the constructor and the flag <tt>useLowBits</tt>.
737 */
738 UInt32 operator()(UInt32 beyond) const
739 {
740 if(beyond < 2)
741 return 0;
742
743 return generator_.uniformInt(beyond);
744 }
745 };
746
747 template <class Engine>
748 class FunctorTraits<UniformIntRandomFunctor<Engine> >
749 {
750 public:
751 typedef UniformIntRandomFunctor<Engine> type;
752
753 typedef VigraTrueType isInitializer;
754
755 typedef VigraTrueType isUnaryFunctor;
756 typedef VigraFalseType isBinaryFunctor;
757 typedef VigraFalseType isTernaryFunctor;
758
759 typedef VigraFalseType isUnaryAnalyser;
760 typedef VigraFalseType isBinaryAnalyser;
761 typedef VigraFalseType isTernaryAnalyser;
762 };
763
764 /** Functor to create uniformly distributed double-precision random numbers.
765
766 This functor encapsulates the function <tt>uniform()</tt> of the given random number
767 <tt>Engine</tt> (usually <tt>RandomTT800</tt> or <tt>RandomMT19937</tt>)
768 in an STL-compatible interface.
769
770 <b>Traits defined:</b>
771
772 \verbatim FunctorTraits<UniformIntRandomFunctor<Engine> >::isInitializer \endverbatim
773 is true (<tt>VigraTrueType</tt>).
774 */
775 template <class Engine = MersenneTwister>
776 class UniformRandomFunctor
777 {
778 double offset_, scale_;
779 Engine const & generator_;
780
781 public:
782
783 typedef double result_type; ///< STL required functor result type
784
785 /** Create functor for uniform random double-precision numbers in the range [0.0, 1.0]
786 using the given engine.
787
788 That is, the generated numbers satisfy 0.0 &lt;= i &lt;= 1.0.
789 */
790 UniformRandomFunctor(Engine const & generator = Engine::global())
791 : offset_(0.0),
792 scale_(1.0),
793 generator_(generator)
794 {}
795
796 /** Create functor for uniform random double-precision numbers in the range [<tt>lower</tt>, <tt>upper</tt>]
797 using the given engine.
798
799 That is, the generated numbers satisfy <tt>lower</tt> &lt;= i &lt;= <tt>upper</tt>.
800 */
801 UniformRandomFunctor(double lower, double upper,
802 Engine & generator = Engine::global())
803 : offset_(lower),
804 scale_(upper - lower),
805 generator_(generator)
806 {
807 vigra_precondition(lower < upper,
808 "UniformRandomFunctor(): lower bound must be smaller than upper bound.");
809 }
810
811 /** Return a random number as specified in the constructor.
812 */
813 double operator()() const
814 {
815 return generator_.uniform() * scale_ + offset_;
816 }
817 };
818
819 template <class Engine>
820 class FunctorTraits<UniformRandomFunctor<Engine> >
821 {
822 public:
823 typedef UniformRandomFunctor<Engine> type;
824
825 typedef VigraTrueType isInitializer;
826
827 typedef VigraFalseType isUnaryFunctor;
828 typedef VigraFalseType isBinaryFunctor;
829 typedef VigraFalseType isTernaryFunctor;
830
831 typedef VigraFalseType isUnaryAnalyser;
832 typedef VigraFalseType isBinaryAnalyser;
833 typedef VigraFalseType isTernaryAnalyser;
834 };
835
836 /** Functor to create normal variate random numbers.
837
838 This functor encapsulates the function <tt>normal()</tt> of the given random number
839 <tt>Engine</tt> (usually <tt>RandomTT800</tt> or <tt>RandomMT19937</tt>)
840 in an STL-compatible interface.
841
842 <b>Traits defined:</b>
843
844 \verbatim FunctorTraits<UniformIntRandomFunctor<Engine> >::isInitializer \endverbatim
845 is true (<tt>VigraTrueType</tt>).
846 */
847 template <class Engine = MersenneTwister>
848 class NormalRandomFunctor
849 {
850 double mean_, stddev_;
851 Engine const & generator_;
852
853 public:
854
855 typedef double result_type; ///< STL required functor result type
856
857 /** Create functor for standard normal random numbers
858 using the given engine.
859
860 That is, mean is 0.0 and standard deviation is 1.0.
861 */
862 NormalRandomFunctor(Engine const & generator = Engine::global())
863 : mean_(0.0),
864 stddev_(1.0),
865 generator_(generator)
866 {}
867
868 /** Create functor for normal random numbers with given mean and standard deviation
869 using the given engine.
870 */
871 NormalRandomFunctor(double mean, double stddev,
872 Engine & generator = Engine::global())
873 : mean_(mean),
874 stddev_(stddev),
875 generator_(generator)
876 {
877 vigra_precondition(stddev > 0.0,
878 "NormalRandomFunctor(): standard deviation must be positive.");
879 }
880
881 /** Return a random number as specified in the constructor.
882 */
883 double operator()() const
884 {
885 return generator_.normal() * stddev_ + mean_;
886 }
887
888 };
889
890 template <class Engine>
891 class FunctorTraits<NormalRandomFunctor<Engine> >
892 {
893 public:
894 typedef UniformRandomFunctor<Engine> type;
895
896 typedef VigraTrueType isInitializer;
897
898 typedef VigraFalseType isUnaryFunctor;
899 typedef VigraFalseType isBinaryFunctor;
900 typedef VigraFalseType isTernaryFunctor;
901
902 typedef VigraFalseType isUnaryAnalyser;
903 typedef VigraFalseType isBinaryAnalyser;
904 typedef VigraFalseType isTernaryAnalyser;
905 };
906
907 //@}
908
909 } // namespace vigra
910
911 #endif // VIGRA_RANDOM_HXX

© Ullrich Köthe (ullrich.koethe@iwr.uni-heidelberg.de) Heidelberg Collaboratory for Image Processing, University of Heidelberg, Germany | html generated using doxygen and Python vigra 1.10.0 (Mon Nov 18 2013)