ITK  4.12.0
Insight Segmentation and Registration Toolkit
itkMersenneTwisterRandomVariateGenerator.h
Go to the documentation of this file.
1 /*=========================================================================
2  *
3  * Copyright Insight Software Consortium
4  *
5  * Licensed under the Apache License, Version 2.0 (the "License");
6  * you may not use this file except in compliance with the License.
7  * You may obtain a copy of the License at
8  *
9  * http://www.apache.org/licenses/LICENSE-2.0.txt
10  *
11  * Unless required by applicable law or agreed to in writing, software
12  * distributed under the License is distributed on an "AS IS" BASIS,
13  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14  * See the License for the specific language governing permissions and
15  * limitations under the License.
16  *
17  *=========================================================================*/
18 #ifndef itkMersenneTwisterRandomVariateGenerator_h
19 #define itkMersenneTwisterRandomVariateGenerator_h
20 
21 #include "itkMacro.h"
22 #include "itkObjectFactory.h"
24 #include "itkIntTypes.h"
25 #include "itkMath.h"
26 #include "itkMutexLockHolder.h"
27 #include <climits>
28 #include <ctime>
29 
30 namespace itk
31 {
32 namespace Statistics
33 {
115 {
116 public:
117 
123 
125 
129 
138  static Pointer New();
139 
148  static Pointer GetInstance();
149 
151  itkStaticConstMacro(StateVectorLength, IntegerType, 624);
152 
154  void Initialize(const IntegerType oneSeed);
155 
156  /* Initialize with clock time */
157  void Initialize();
158 
160  double GetVariateWithClosedRange();
161 
163  double GetVariateWithClosedRange(const double & n);
164 
166  double GetVariateWithOpenUpperRange();
167 
169  double GetVariateWithOpenUpperRange(const double & n);
170 
172  double GetVariateWithOpenRange();
173 
175  double GetVariateWithOpenRange(const double & n);
176 
178  IntegerType GetIntegerVariate();
179 
181  IntegerType GetIntegerVariate(const IntegerType & n);
182 
185  double Get53BitVariate();
186 
187  /* Access to a normal random number distribution
188  * TODO: Compare with vnl_sample_normal */
189  double GetNormalVariate(const double & mean = 0.0,
190  const double & variance = 1.0);
191 
192  /* Access to a uniform random number distribution in the range [a, b)
193  * TODO: Compare with vnl_sample_uniform */
194  double GetUniformVariate(const double & a, const double & b);
195 
201  virtual double GetVariate() ITK_OVERRIDE;
202 
204  double operator()();
205 
210  inline void SetSeed(const IntegerType oneSeed);
211  inline void SetSeed();
213 
218  IntegerType GetSeed();
219 
225  static IntegerType GetNextSeed();
226 
227  /*
228  // Saving and loading generator state
229  void save( IntegerType* saveArray ) const; // to array of size SAVE
230  void load( IntegerType *const loadArray ); // from such array
231  */
232 
233 protected:
235  virtual ~MersenneTwisterRandomVariateGenerator();
236  virtual void PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE;
237 
239  itkStaticConstMacro(M, unsigned int, 397);
240 
242  void reload();
243 
244  IntegerType hiBit(const IntegerType & u) const { return u & 0x80000000; }
245  IntegerType loBit(const IntegerType & u) const { return u & 0x00000001; }
246  IntegerType loBits(const IntegerType & u) const { return u & 0x7fffffff; }
247  IntegerType mixBits(const IntegerType & u, const IntegerType & v) const
248  {
249  return hiBit(u) | loBits(v);
250  }
251 
252  IntegerType twist(const IntegerType & m, const IntegerType & s0, const IntegerType & s1) const
253  {
254  return m ^ ( mixBits(s0, s1) >> 1 ) ^ ( -static_cast<int32_t>(loBit(s1)) & 0x9908b0df );
255  }
256 
257  static IntegerType hash(time_t t, clock_t c);
258 
259  // Internal state
260  IntegerType state[StateVectorLength];
261 
262  // Next value to get from state
264 
265  // Number of values left before reload is needed
266  int m_Left;
267 
268  // Seed value
270 
271 private:
272 
274  static Pointer CreateInstance();
275 
276  // Local lock to enable concurrent access to singleton
278 
279  // Static/Global Variable need to be thread-safely accessed
283 
284 }; // end of class
285 
286 // Declare inlined functions.... (must be declared in the header)
287 
288 inline void
290 {
292  this->m_Seed = seed;
293  // Initialize generator state with seed
294  // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
295  // In previous versions, most significant bits (MSBs) of the seed affect
296  // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto.
297  IntegerType *s = state;
298  IntegerType *r = state;
299  IntegerType i = 1;
300 
301  *s++ = seed & 0xffffffffUL;
303  {
304  *s++ = ( 1812433253UL * ( *r ^ ( *r >> 30 ) ) + i ) & 0xffffffffUL;
305  r++;
306  }
307  reload();
308 }
309 
310 inline void
312 {
313  // Generate N new values in state
314  // Made clearer and faster by Matthew Bellew
315  // matthew dot bellew at home dot com
316 
317  // get rid of VS warning
318  int index = static_cast< int >(
320 
321  IntegerType *p = state;
322  int i;
323 
325  {
326  *p = twist(p[M], p[0], p[1]);
327  }
328  for ( i = M; --i; ++p )
329  {
330  *p = twist(p[index], p[0], p[1]);
331  }
332  *p = twist(p[index], p[0], state[0]);
333 
335  m_PNext = state;
336 }
337 
338 inline void
340 {
341  SetSeed();
342 }
343 
344 inline void
346 {
347  // Seed the generator with a simple IntegerType
348  Initialize(oneSeed);
349 }
350 
351 inline void
353 {
354  // use time() and clock() to generate a unlikely-to-repeat seed.
355  SetSeed( hash( time(ITK_NULLPTR), clock() ) );
356 }
357 
358 
361 {
363  volatile IntegerType seed = this->m_Seed;
364  return seed;
365 }
366 
370 {
371  if ( m_Left == 0 ) { reload(); }
372  --m_Left;
374 
375  IntegerType s1 = *m_PNext++;
376  s1 ^= ( s1 >> 11 );
377  s1 ^= ( s1 << 7 ) & 0x9d2c5680;
378  s1 ^= ( s1 << 15 ) & 0xefc60000;
379  return ( s1 ^ ( s1 >> 18 ) );
380 }
381 
382 inline double
384 {
385  return double( GetIntegerVariate() ) * ( 1.0 / 4294967295.0 );
386 }
387 
389 inline double
391  const double & n)
392 {
393  return GetVariateWithClosedRange() * n;
394 }
395 
397 inline double
399 {
400  return double( GetIntegerVariate() ) * ( 1.0 / 4294967296.0 );
401 }
402 
404 inline double
406  const double & n)
407 {
408  return GetVariateWithOpenUpperRange() * n;
409 }
410 
412 inline double
414 {
415  return ( double( GetIntegerVariate() ) + 0.5 ) * ( 1.0 / 4294967296.0 );
416 }
417 
419 inline double
421  const double & n)
422 {
423  return GetVariateWithOpenRange() * n;
424 }
425 
428  const IntegerType & n)
429 {
430  // Find which bits are used in n
431  IntegerType used = n;
432 
433  used |= used >> 1;
434  used |= used >> 2;
435  used |= used >> 4;
436  used |= used >> 8;
437  used |= used >> 16;
438 
439  // Draw numbers until one is found in [0,n]
440  IntegerType i;
441  do
442  {
443  i = GetIntegerVariate() & used; // toss unused bits to shorten search
444  }
445  while ( i > n );
446 
447  return i;
448 }
449 
452 inline double
454 {
455  IntegerType a = GetIntegerVariate() >> 5, b = GetIntegerVariate() >> 6;
456 
457  return ( a * 67108864.0 + b ) * ( 1.0 / 9007199254740992.0 ); // by Isaku
458  // Wada
459 }
460 
462 // TODO: Compare with vnl_sample_normal
463 inline double
465  const double & mean, const double & variance)
466 {
467  // Return a real number from a normal (Gaussian) distribution with given
468  // mean and variance by Box-Muller method
469  double r = std::sqrt(-2.0 * std::log( 1.0 - GetVariateWithOpenRange() ) * variance);
470  double phi = 2.0 * itk::Math::pi
473 
474  return mean + r *std::cos(phi);
475 }
476 
478 // TODO: Compare with vnl_sample_uniform
479 inline double
481  const double & a, const double & b)
482 {
483  double u = GetVariateWithOpenUpperRange();
484 
485  return ( ( 1.0 - u ) * a + u * b );
486 }
487 
488 inline double
490 {
491  return GetVariateWithClosedRange();
492 }
493 
494 inline double
496 {
497  return GetVariate();
498 }
499 
500 /* Change log from MTRand.h */
501 // Change log:
502 //
503 // v0.1 - First release on 15 May 2000
504 // - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
505 // - Translated from C to C++
506 // - Made completely ANSI compliant
507 // - Designed convenient interface for initialization, seeding, and
508 // obtaining numbers in default or user-defined ranges
509 // - Added automatic seeding from /dev/urandom or time() and clock()
510 // - Provided functions for saving and loading generator state
511 //
512 // v0.2 - Fixed bug which reloaded generator one step too late
513 //
514 // v0.3 - Switched to clearer, faster reload() code from Matthew Bellew
515 //
516 // v0.4 - Removed trailing newline in saved generator format to be consistent
517 // with output format of built-in types
518 //
519 // v0.5 - Improved portability by replacing static const int's with enum's and
520 // clarifying return values in seed(); suggested by Eric Heimburg
521 // - Removed MAXINT constant; use 0xffffffffUL instead
522 //
523 // v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits
524 // - Changed integer [0,n] generator to give better uniformity
525 //
526 // v0.7 - Fixed operator precedence ambiguity in reload()
527 // - Added access for real numbers in (0,1) and (0,n)
528 //
529 // v0.8 - Included time.h header to properly support time_t and clock_t
530 //
531 // v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto
532 // - Allowed for seeding with arrays of any length
533 // - Added access for real numbers in [0,1) with 53-bit resolution
534 // - Added access for real numbers from normal (Gaussian) distributions
535 // - Increased overall speed by optimizing twist()
536 // - Doubled speed of integer [0,n] generation
537 // - Fixed out-of-range number generation on 64-bit machines
538 // - Improved portability by substituting literal constants for long enum's
539 // - Changed license from GNU LGPL to BSD
540 } // end namespace Statistics
541 } // end namespace itk
542 
543 #endif
Critical section locking class that can be allocated on the stack.
virtual void PrintSelf(std::ostream &os, Indent indent) const override
virtual void Initialize()
static Pointer New()
A container to store a Mutex. This holder class for ensuring that locks are released in the event of ...
static ITK_CONSTEXPR_VAR double pi
Definition: itkMath.h:66
KWIML_INT_uint32_t uint32_t
Definition: itkIntTypes.h:87
IntegerType mixBits(const IntegerType &u, const IntegerType &v) const
Defines common interfaces for random variate generators.
IntegerType twist(const IntegerType &m, const IntegerType &s0, const IntegerType &s1) const
double GetNormalVariate(const double &mean=0.0, const double &variance=1.0)
Control indentation during Print() invocation.
Definition: itkIndent.h:49
static IntegerType hash(time_t t, clock_t c)