ITK  4.10.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 <climits>
27 #include <ctime>
28 
29 namespace itk
30 {
31 namespace Statistics
32 {
109 {
110 public:
111 
117 
119 
123 
129  static Pointer New();
130 
137  static Pointer GetInstance();
138 
140  itkStaticConstMacro(StateVectorLength, IntegerType, 624);
141 
143  void Initialize(const IntegerType oneSeed);
144 
145  /* Initialize with clock time */
146  void Initialize();
147 
149  double GetVariateWithClosedRange();
150 
152  double GetVariateWithClosedRange(const double & n);
153 
155  double GetVariateWithOpenUpperRange();
156 
158  double GetVariateWithOpenUpperRange(const double & n);
159 
161  double GetVariateWithOpenRange();
162 
164  double GetVariateWithOpenRange(const double & n);
165 
167  IntegerType GetIntegerVariate();
168 
170  IntegerType GetIntegerVariate(const IntegerType & n);
171 
174  double Get53BitVariate();
175 
176  /* Access to a normal random number distribution
177  * TODO: Compare with vnl_sample_normal */
178  double GetNormalVariate(const double & mean = 0.0,
179  const double & variance = 1.0);
180 
181  /* Access to a uniform random number distribution in the range [a, b)
182  * TODO: Compare with vnl_sample_uniform */
183  double GetUniformVariate(const double & a, const double & b);
184 
190  virtual double GetVariate() ITK_OVERRIDE;
191 
193  double operator()();
194 
196  inline void SetSeed(const IntegerType oneSeed);
197  inline void SetSeed();
199 
201  IntegerType GetSeed() { return this->m_Seed; };
202 
203  /*
204  // Saving and loading generator state
205  void save( IntegerType* saveArray ) const; // to array of size SAVE
206  void load( IntegerType *const loadArray ); // from such array
207  */
208 
209 protected:
212  virtual void PrintSelf(std::ostream & os, Indent indent) const ITK_OVERRIDE;
213 
215  itkStaticConstMacro(M, unsigned int, 397);
216 
218  void reload();
219 
220  IntegerType hiBit(const IntegerType & u) const { return u & 0x80000000; }
221  IntegerType loBit(const IntegerType & u) const { return u & 0x00000001; }
222  IntegerType loBits(const IntegerType & u) const { return u & 0x7fffffff; }
223  IntegerType mixBits(const IntegerType & u, const IntegerType & v) const
224  {
225  return hiBit(u) | loBits(v);
226  }
227 
228  IntegerType twist(const IntegerType & m, const IntegerType & s0, const IntegerType & s1) const
229  {
230  return m ^ ( mixBits(s0, s1) >> 1 ) ^ ( -static_cast<int32_t>(loBit(s1)) & 0x9908b0df );
231  }
232 
233  static IntegerType hash(time_t t, clock_t c);
234 
235  // Internal state
236  IntegerType state[StateVectorLength];
237 
238  // Next value to get from state
239  IntegerType *m_PNext;
240 
241  // Number of values left before reload is needed
242  int m_Left;
243 
244  // Seed value
245  IntegerType m_Seed;
246 
247 private:
248 
250  static Pointer CreateInstance();
251 
252  // Static/Global Variable need to be thread-safely accessed
253  static Pointer m_StaticInstance;
255  static IntegerType m_StaticDiffer;
256 
257 }; // end of class
258 
259 // Declare inlined functions.... (must be declared in the header)
260 
261 inline void
263 {
264  this->m_Seed = seed;
265  // Initialize generator state with seed
266  // See Knuth TAOCP Vol 2, 3rd Ed, p.106 for multiplier.
267  // In previous versions, most significant bits (MSBs) of the seed affect
268  // only MSBs of the state array. Modified 9 Jan 2002 by Makoto Matsumoto.
269  IntegerType *s = state;
270  IntegerType *r = state;
271  IntegerType i = 1;
272 
273  *s++ = seed & 0xffffffffUL;
275  {
276  *s++ = ( 1812433253UL * ( *r ^ ( *r >> 30 ) ) + i ) & 0xffffffffUL;
277  r++;
278  }
279 }
280 
281 inline void
283 {
284  // Generate N new values in state
285  // Made clearer and faster by Matthew Bellew
286  // matthew dot bellew at home dot com
287 
288  // get rid of VS warning
289  int index = static_cast< int >(
291 
292  IntegerType *p = state;
293  int i;
294 
296  {
297  *p = twist(p[M], p[0], p[1]);
298  }
299  for ( i = M; --i; ++p )
300  {
301  *p = twist(p[index], p[0], p[1]);
302  }
303  *p = twist(p[index], p[0], state[0]);
304 
306  m_PNext = state;
307 }
308 
309 inline void
311 {
312  SetSeed();
313 }
314 
315 inline void
317 {
318  // Seed the generator with a simple IntegerType
319  Initialize(oneSeed);
320  reload();
321 }
322 
323 inline void
325 {
326  // use time() and clock() to generate a unlikely-to-repeat seed.
327  SetSeed( hash( time(ITK_NULLPTR), clock() ) );
328 }
329 
333 {
334  if ( m_Left == 0 ) { reload(); }
335  --m_Left;
337 
338  IntegerType s1 = *m_PNext++;
339  s1 ^= ( s1 >> 11 );
340  s1 ^= ( s1 << 7 ) & 0x9d2c5680;
341  s1 ^= ( s1 << 15 ) & 0xefc60000;
342  return ( s1 ^ ( s1 >> 18 ) );
343 }
344 
345 inline double
347 {
348  return double( GetIntegerVariate() ) * ( 1.0 / 4294967295.0 );
349 }
350 
352 inline double
354  const double & n)
355 {
356  return GetVariateWithClosedRange() * n;
357 }
358 
360 inline double
362 {
363  return double( GetIntegerVariate() ) * ( 1.0 / 4294967296.0 );
364 }
365 
367 inline double
369  const double & n)
370 {
371  return GetVariateWithOpenUpperRange() * n;
372 }
373 
375 inline double
377 {
378  return ( double( GetIntegerVariate() ) + 0.5 ) * ( 1.0 / 4294967296.0 );
379 }
380 
382 inline double
384  const double & n)
385 {
386  return GetVariateWithOpenRange() * n;
387 }
388 
391  const IntegerType & n)
392 {
393  // Find which bits are used in n
394  IntegerType used = n;
395 
396  used |= used >> 1;
397  used |= used >> 2;
398  used |= used >> 4;
399  used |= used >> 8;
400  used |= used >> 16;
401 
402  // Draw numbers until one is found in [0,n]
403  IntegerType i;
404  do
405  {
406  i = GetIntegerVariate() & used; // toss unused bits to shorten search
407  }
408  while ( i > n );
409 
410  return i;
411 }
412 
415 inline double
417 {
418  IntegerType a = GetIntegerVariate() >> 5, b = GetIntegerVariate() >> 6;
419 
420  return ( a * 67108864.0 + b ) * ( 1.0 / 9007199254740992.0 ); // by Isaku
421  // Wada
422 }
423 
425 // TODO: Compare with vnl_sample_normal
426 inline double
428  const double & mean, const double & variance)
429 {
430  // Return a real number from a normal (Gaussian) distribution with given
431  // mean and variance by Box-Muller method
432  double r = std::sqrt(-2.0 * std::log( 1.0 - GetVariateWithOpenRange() ) * variance);
433  double phi = 2.0 * itk::Math::pi
434  * GetVariateWithOpenUpperRange();
436 
437  return mean + r *std::cos(phi);
438 }
439 
441 // TODO: Compare with vnl_sample_uniform
442 inline double
444  const double & a, const double & b)
445 {
446  double u = GetVariateWithOpenUpperRange();
447 
448  return ( ( 1.0 - u ) * a + u * b );
449 }
450 
451 inline double
453 {
454  return GetVariateWithClosedRange();
455 }
456 
457 inline double
459 {
460  return GetVariate();
461 }
462 
463 /* Change log from MTRand.h */
464 // Change log:
465 //
466 // v0.1 - First release on 15 May 2000
467 // - Based on code by Makoto Matsumoto, Takuji Nishimura, and Shawn Cokus
468 // - Translated from C to C++
469 // - Made completely ANSI compliant
470 // - Designed convenient interface for initialization, seeding, and
471 // obtaining numbers in default or user-defined ranges
472 // - Added automatic seeding from /dev/urandom or time() and clock()
473 // - Provided functions for saving and loading generator state
474 //
475 // v0.2 - Fixed bug which reloaded generator one step too late
476 //
477 // v0.3 - Switched to clearer, faster reload() code from Matthew Bellew
478 //
479 // v0.4 - Removed trailing newline in saved generator format to be consistent
480 // with output format of built-in types
481 //
482 // v0.5 - Improved portability by replacing static const int's with enum's and
483 // clarifying return values in seed(); suggested by Eric Heimburg
484 // - Removed MAXINT constant; use 0xffffffffUL instead
485 //
486 // v0.6 - Eliminated seed overflow when uint32 is larger than 32 bits
487 // - Changed integer [0,n] generator to give better uniformity
488 //
489 // v0.7 - Fixed operator precedence ambiguity in reload()
490 // - Added access for real numbers in (0,1) and (0,n)
491 //
492 // v0.8 - Included time.h header to properly support time_t and clock_t
493 //
494 // v1.0 - Revised seeding to match 26 Jan 2002 update of Nishimura and Matsumoto
495 // - Allowed for seeding with arrays of any length
496 // - Added access for real numbers in [0,1) with 53-bit resolution
497 // - Added access for real numbers from normal (Gaussian) distributions
498 // - Increased overall speed by optimizing twist()
499 // - Doubled speed of integer [0,n] generation
500 // - Fixed out-of-range number generation on 64-bit machines
501 // - Improved portability by substituting literal constants for long enum's
502 // - Changed license from GNU LGPL to BSD
503 } // end namespace Statistics
504 } // end namespace itk
505 
506 #endif
Critical section locking class that can be allocated on the stack.
The "itk" namespace contains all Insight Segmentation and Registration Toolkit (ITK) classes...
Definition: itkArray.h:30
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 ITK_CONSTEXPR double pi
Definition: itkMath.h:68