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

random.hxx VIGRA

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 #ifdef __linux__
53  #include <unistd.h> // for getpid()
54  #include <sys/syscall.h> // for SYS_gettid
55 #endif
56 
57 #ifdef __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 = static_cast<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(static_cast<UInt32>(time(0)));
132  seedData.push_back(static_cast<UInt32>(clock()));
133  seedData.push_back(++globalCount);
134 
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)));
139 
140 #ifdef _MSC_VER
141  seedData.push_back(static_cast<UInt32>(GetCurrentProcessId()));
142  seedData.push_back(static_cast<UInt32>(GetCurrentThreadId()));
143 #endif
144 
145 #ifdef __linux__
146  seedData.push_back(static_cast<UInt32>(getpid()));
147 # ifdef SYS_gettid
148  seedData.push_back(static_cast<UInt32>(syscall(SYS_gettid)));
149 # endif
150 #endif
151 
152 #ifdef __APPLE__
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)
155  // SYS_thread_selfid was introduced in MacOS 10.6
156  seedData.push_back(static_cast<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> >
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  */
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  */
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  */
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 static_cast<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  */
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>
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  */
616 
617  /** Shorthand for the TT800 random number generator class (same as RandomTT800).
618  */
620 
621  /** Shorthand for the MT19937 random number generator class.
622  */
624 
625  /** Shorthand for the MT19937 random number generator class (same as RandomMT19937).
626  */
628 
629  /** Access the global (program-wide) instance of the TT800 random number generator.
630  */
632 
633  /** Access the global (program-wide) instance of the MT19937 random number generator.
634  */
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>
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  */
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  */
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>
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>
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
UniformIntRandomFunctor(UInt32 lower, UInt32 upper, Engine const &generator=Engine::global(), bool useLowBits=true)
Definition: random.hxx:700
UInt32 uniformInt() const
Definition: random.hxx:464
void seed(RandomSeedTag)
Definition: random.hxx:416
double result_type
STL required functor result type.
Definition: random.hxx:783
UInt32 argument_type
STL required functor argument type.
Definition: random.hxx:677
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
UInt32 operator()() const
Definition: random.hxx:714
double normal() const
Definition: random.hxx:586
UniformRandomFunctor(double lower, double upper, Engine &generator=Engine::global())
Definition: random.hxx:801
UInt32 result_type
STL required functor result type.
Definition: random.hxx:678
RandomNumberGenerator(Iterator init, UInt32 length)
Definition: random.hxx:396
UniformIntRandomFunctor(Engine const &generator=Engine::global())
Definition: random.hxx:685
UInt32 uniformInt(UInt32 beyond) const
Definition: random.hxx:492
Definition: random.hxx:669
double uniform53() const
Definition: random.hxx:515
double result_type
STL required functor result type.
Definition: random.hxx:855
UniformRandomFunctor(Engine const &generator=Engine::global())
Definition: random.hxx:790
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 operator()() const
Definition: random.hxx:813
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)
Definition: random.hxx:776
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
UInt32 operator()(UInt32 beyond) const
Definition: random.hxx:738
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

© 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.11.1 (Fri May 19 2017)