ITK  4.13.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 {
123 {
124 public:
125 
131 
133 
137 
146  static Pointer New();
147 
156  static Pointer GetInstance();
157 
159  itkStaticConstMacro(StateVectorLength, IntegerType, 624);
160 
162  void Initialize(const IntegerType oneSeed);
163 
164  /* Initialize with clock time */
165  void Initialize();
166 
168  double GetVariateWithClosedRange();
169 
171  double GetVariateWithClosedRange(const double & n);
172 
174  double GetVariateWithOpenUpperRange();
175 
177  double GetVariateWithOpenUpperRange(const double & n);
178 
180  double GetVariateWithOpenRange();
181 
183  double GetVariateWithOpenRange(const double & n);
184 
186  IntegerType GetIntegerVariate();
187 
189  IntegerType GetIntegerVariate(const IntegerType & n);
190 
193  double Get53BitVariate();
194 
195  /* Access to a normal random number distribution
196  * TODO: Compare with vnl_sample_normal */
197  double GetNormalVariate(const double & mean = 0.0,
198  const double & variance = 1.0);
199 
200  /* Access to a uniform random number distribution in the range [a, b)
201  * TODO: Compare with vnl_sample_uniform */
202  double GetUniformVariate(const double & a, const double & b);
203 
209  virtual double GetVariate() ITK_OVERRIDE;
210 
212  double operator()();
213 
218  inline void SetSeed(const IntegerType oneSeed);
219  inline void SetSeed();
221 
226  IntegerType GetSeed();
227 
233  static IntegerType GetNextSeed();
234 
235  /*
236  // Saving and loading generator state
237  void save( IntegerType* saveArray ) const; // to array of size SAVE
238  void load( IntegerType *const loadArray ); // from such array
239  */
240 
241 protected:
243  virtual ~MersenneTwisterRandomVariateGenerator() ITK_OVERRIDE;
244  virtual void PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE;
245 
247  itkStaticConstMacro(M, unsigned int, 397);
248 
250  void reload();
251 
252  IntegerType hiBit(const IntegerType & u) const { return u & 0x80000000; }
253  IntegerType loBit(const IntegerType & u) const { return u & 0x00000001; }
254  IntegerType loBits(const IntegerType & u) const { return u & 0x7fffffff; }
255  IntegerType mixBits(const IntegerType & u, const IntegerType & v) const
256  {
257  return hiBit(u) | loBits(v);
258  }
259 
260  IntegerType twist(const IntegerType & m, const IntegerType & s0, const IntegerType & s1) const
261  {
262  return m ^ ( mixBits(s0, s1) >> 1 ) ^ ( -static_cast<int32_t>(loBit(s1)) & 0x9908b0df );
263  }
264 
265  static IntegerType hash(time_t t, clock_t c);
266 
267  // Internal state
268  IntegerType state[StateVectorLength];
269 
270  // Next value to get from state
272 
273  // Number of values left before reload is needed
274  int m_Left;
275 
276  // Seed value
278 
279 private:
280 
282  static Pointer CreateInstance();
283 
284  // Local lock to enable concurrent access to singleton
286 
287  // Static/Global Variable need to be thread-safely accessed
291 
292 }; // end of class
293 
294 // Declare inlined functions.... (must be declared in the header)
295 
296 inline void
298 {
300  this->m_Seed = seed;
301  // Initialize generator state with seed
302  // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
303  // In previous versions, most significant bits (MSBs) of the seed affect
304  // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto.
305  IntegerType *s = state;
306  IntegerType *r = state;
307  IntegerType i = 1;
308 
309  *s++ = seed & 0xffffffffUL;
311  {
312  *s++ = ( 1812433253UL * ( *r ^ ( *r >> 30 ) ) + i ) & 0xffffffffUL;
313  r++;
314  }
315  reload();
316 }
317 
318 inline void
320 {
321  // Generate N new values in state
322  // Made clearer and faster by Matthew Bellew
323  // matthew dot bellew at home dot com
324 
325  // get rid of VS warning
326  int index = static_cast< int >(
328 
329  IntegerType *p = state;
330  int i;
331 
333  {
334  *p = twist(p[M], p[0], p[1]);
335  }
336  for ( i = M; --i; ++p )
337  {
338  *p = twist(p[index], p[0], p[1]);
339  }
340  *p = twist(p[index], p[0], state[0]);
341 
343  m_PNext = state;
344 }
345 
346 inline void
348 {
349  SetSeed();
350 }
351 
352 inline void
354 {
355  // Seed the generator with a simple IntegerType
356  Initialize(oneSeed);
357 }
358 
359 inline void
361 {
362  // use time() and clock() to generate a unlikely-to-repeat seed.
363  SetSeed( hash( time(ITK_NULLPTR), clock() ) );
364 }
365 
366 
369 {
371  volatile IntegerType seed = this->m_Seed;
372  return seed;
373 }
374 
378 {
379  if ( m_Left == 0 ) { reload(); }
380  --m_Left;
382 
383  IntegerType s1 = *m_PNext++;
384  s1 ^= ( s1 >> 11 );
385  s1 ^= ( s1 << 7 ) & 0x9d2c5680;
386  s1 ^= ( s1 << 15 ) & 0xefc60000;
387  return ( s1 ^ ( s1 >> 18 ) );
388 }
389 
390 inline double
392 {
393  return double( GetIntegerVariate() ) * ( 1.0 / 4294967295.0 );
394 }
395 
397 inline double
399  const double & n)
400 {
401  return GetVariateWithClosedRange() * n;
402 }
403 
405 inline double
407 {
408  return double( GetIntegerVariate() ) * ( 1.0 / 4294967296.0 );
409 }
410 
412 inline double
414  const double & n)
415 {
416  return GetVariateWithOpenUpperRange() * n;
417 }
418 
420 inline double
422 {
423  return ( double( GetIntegerVariate() ) + 0.5 ) * ( 1.0 / 4294967296.0 );
424 }
425 
427 inline double
429  const double & n)
430 {
431  return GetVariateWithOpenRange() * n;
432 }
433 
436  const IntegerType & n)
437 {
438  // Find which bits are used in n
439  IntegerType used = n;
440 
441  used |= used >> 1;
442  used |= used >> 2;
443  used |= used >> 4;
444  used |= used >> 8;
445  used |= used >> 16;
446 
447  // Draw numbers until one is found in [0,n]
448  IntegerType i;
449  do
450  {
451  i = GetIntegerVariate() & used; // toss unused bits to shorten search
452  }
453  while ( i > n );
454 
455  return i;
456 }
457 
460 inline double
462 {
463  IntegerType a = GetIntegerVariate() >> 5, b = GetIntegerVariate() >> 6;
464 
465  return ( a * 67108864.0 + b ) * ( 1.0 / 9007199254740992.0 ); // by Isaku
466  // Wada
467 }
468 
470 // TODO: Compare with vnl_sample_normal
471 inline double
473  const double & mean, const double & variance)
474 {
475  // Return a real number from a normal (Gaussian) distribution with given
476  // mean and variance by Box-Muller method
477  double r = std::sqrt(-2.0 * std::log( 1.0 - GetVariateWithOpenRange() ) * variance);
478  double phi = 2.0 * itk::Math::pi
481 
482  return mean + r *std::cos(phi);
483 }
484 
486 // TODO: Compare with vnl_sample_uniform
487 inline double
489  const double & a, const double & b)
490 {
491  double u = GetVariateWithOpenUpperRange();
492 
493  return ( ( 1.0 - u ) * a + u * b );
494 }
495 
496 inline double
498 {
499  return GetVariateWithClosedRange();
500 }
501 
502 inline double
504 {
505  return GetVariate();
506 }
507 
508 /* Change log from MTRand.h */
509 // Change log:
510 //
511 // v0.1 - First release on 15 May 2000
512 // - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
513 // - Translated from C to C++
514 // - Made completely ANSI compliant
515 // - Designed convenient interface for initialization, seeding, and
516 // obtaining numbers in default or user-defined ranges
517 // - Added automatic seeding from /dev/urandom or time() and clock()
518 // - Provided functions for saving and loading generator state
519 //
520 // v0.2 - Fixed bug which reloaded generator one step too late
521 //
522 // v0.3 - Switched to clearer, faster reload() code from Matthew Bellew
523 //
524 // v0.4 - Removed trailing newline in saved generator format to be consistent
525 // with output format of built-in types
526 //
527 // v0.5 - Improved portability by replacing static const int's with enum's and
528 // clarifying return values in seed(); suggested by Eric Heimburg
529 // - Removed MAXINT constant; use 0xffffffffUL instead
530 //
531 // v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits
532 // - Changed integer [0,n] generator to give better uniformity
533 //
534 // v0.7 - Fixed operator precedence ambiguity in reload()
535 // - Added access for real numbers in (0,1) and (0,n)
536 //
537 // v0.8 - Included time.h header to properly support time_t and clock_t
538 //
539 // v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto
540 // - Allowed for seeding with arrays of any length
541 // - Added access for real numbers in [0,1) with 53-bit resolution
542 // - Added access for real numbers from normal (Gaussian) distributions
543 // - Increased overall speed by optimizing twist()
544 // - Doubled speed of integer [0,n] generation
545 // - Fixed out-of-range number generation on 64-bit machines
546 // - Improved portability by substituting literal constants for long enum's
547 // - Changed license from GNU LGPL to BSD
548 } // end namespace Statistics
549 } // end namespace itk
550 
551 #endif
Critical section locking class that can be allocated on the stack.
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)