00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017 #ifndef __itkMersenneTwisterRandomVariateGenerator_h
00018 #define __itkMersenneTwisterRandomVariateGenerator_h
00019
00020 #include "itkMacro.h"
00021 #include "itkObjectFactory.h"
00022 #include "itkRandomVariateGeneratorBase.h"
00023 #include "itkIntTypes.h"
00024 #include "vcl_ctime.h"
00025 #include "vnl/vnl_math.h"
00026 #include <limits.h>
00027
00028
00029 namespace itk {
00030 namespace Statistics {
00031
00097 class ITKCommon_EXPORT MersenneTwisterRandomVariateGenerator :
00098 public RandomVariateGeneratorBase
00099 {
00100 public:
00101
00103 typedef MersenneTwisterRandomVariateGenerator Self ;
00104 typedef RandomVariateGeneratorBase Superclass;
00105 typedef SmartPointer<Self> Pointer;
00106 typedef SmartPointer<const Self> ConstPointer;
00107 typedef ITK_UINT32 IntegerType;
00108
00110 itkTypeMacro(MersenneTwisterRandomVariateGenerator,
00111 RandomVariateGeneratorBase );
00112
00114 static Pointer New();
00115 static Pointer GetInstance();
00116
00118 itkStaticConstMacro(StateVectorLength,IntegerType,624);
00119
00121
00122
00123
00124
00125
00126
00128 void Initialize( const IntegerType oneSeed );
00129
00131
00132
00133
00134
00135 void Initialize();
00136
00137
00138
00140 double GetVariateWithClosedRange();
00141
00143 double GetVariateWithClosedRange( const double& n );
00144
00146 double GetVariateWithOpenUpperRange();
00147
00149 double GetVariateWithOpenUpperRange( const double& n );
00150
00152 double GetVariateWithOpenRange();
00153
00155 double GetVariateWithOpenRange( const double& n );
00156
00158 IntegerType GetIntegerVariate();
00159
00161 IntegerType GetIntegerVariate( const IntegerType& n );
00162
00165 double Get53BitVariate();
00166
00167
00168
00169 double GetNormalVariate( const double& mean = 0.0,
00170 const double& variance = 1.0 );
00171
00172
00173
00174 double GetUniformVariate( const double& a, const double& b );
00175
00181 virtual double GetVariate();
00182
00184 double operator()();
00185
00186
00187
00188 inline void SetSeed( const IntegerType oneSeed );
00189 inline void SetSeed( IntegerType * bigSeed, const IntegerType seedLength = StateVectorLength );
00190 inline void SetSeed();
00191
00192
00193
00194
00195
00196
00197
00198 protected:
00199 inline MersenneTwisterRandomVariateGenerator();
00200 virtual ~MersenneTwisterRandomVariateGenerator() {};
00201 virtual void PrintSelf(std::ostream& os, Indent indent) const {
00202 Superclass::PrintSelf(os, indent);
00203
00204
00205 os << indent << "State vector: " << state << std::endl;
00206 os << indent;
00207 register const IntegerType *s = state;
00208 register int i = StateVectorLength;
00209 for( ; i--; os << *s++ << "\t" ) {}
00210 os << std::endl;
00211
00212
00213 os << indent << "Next value to be gotten from state: " << pNext << std::endl;
00214
00215
00216 os << indent << "Values left before next reload: " << left << std::endl;
00217 }
00218
00219
00220
00221 itkStaticConstMacro ( M, unsigned int, 397 );
00222
00223 IntegerType state[StateVectorLength];
00224 IntegerType *pNext;
00225 int left;
00226
00227
00228 void reload();
00229
00230 IntegerType hiBit( const IntegerType& u ) const { return u & 0x80000000UL; }
00231 IntegerType loBit( const IntegerType& u ) const { return u & 0x00000001UL; }
00232 IntegerType loBits( const IntegerType& u ) const { return u & 0x7fffffffUL; }
00233 IntegerType mixBits( const IntegerType& u, const IntegerType& v ) const
00234 {
00235 return hiBit(u) | loBits(v);
00236 }
00237 IntegerType twist( const IntegerType& m, const IntegerType& s0, const IntegerType& s1 ) const
00238 {
00239 return m ^ (mixBits(s0,s1)>>1) ^ (-loBit(s1) & 0x9908b0dfUL);
00240 }
00241 static IntegerType hash( vcl_time_t t, vcl_clock_t c );
00242 static Pointer m_Instance;
00243 } ;
00244
00245
00246
00247
00248
00249
00250
00251 inline MersenneTwisterRandomVariateGenerator::IntegerType
00252 MersenneTwisterRandomVariateGenerator::hash( vcl_time_t t, vcl_clock_t c )
00253 {
00254
00255
00256
00257
00258 static IntegerType differ = 0;
00259
00260 IntegerType h1 = 0;
00261 unsigned char *p = (unsigned char *) &t;
00262 for( size_t i = 0; i < sizeof(t); ++i )
00263 {
00264 h1 *= UCHAR_MAX + 2U;
00265 h1 += p[i];
00266 }
00267 IntegerType h2 = 0;
00268 p = (unsigned char *) &c;
00269 for( size_t j = 0; j < sizeof(c); ++j )
00270 {
00271 h2 *= UCHAR_MAX + 2U;
00272 h2 += p[j];
00273 }
00274 return ( h1 + differ++ ) ^ h2;
00275 }
00276
00277
00278 inline void
00279 MersenneTwisterRandomVariateGenerator::Initialize( const IntegerType seed )
00280 {
00281
00282
00283
00284
00285 register IntegerType *s = state;
00286 register IntegerType *r = state;
00287 register IntegerType i = 1;
00288 *s++ = seed & 0xffffffffUL;
00289 for( i = 1; i < MersenneTwisterRandomVariateGenerator::StateVectorLength; ++i )
00290 {
00291 *s++ = ( 1812433253UL * ( *r ^ (*r >> 30) ) + i ) & 0xffffffffUL;
00292 r++;
00293 }
00294 }
00295
00296 inline void
00297 MersenneTwisterRandomVariateGenerator::reload()
00298 {
00299
00300
00301
00302
00303
00304 register int index = static_cast< int >(
00305 M-MersenneTwisterRandomVariateGenerator::StateVectorLength);
00306
00307 register IntegerType *p = state;
00308 register int i;
00309 for( i = MersenneTwisterRandomVariateGenerator::StateVectorLength - M; i--; ++p )
00310 {
00311 *p = twist( p[M], p[0], p[1] );
00312 }
00313 for( i = M; --i; ++p )
00314 {
00315 *p = twist( p[index], p[0], p[1] );
00316 }
00317 *p = twist( p[index], p[0], state[0] );
00318
00319 left = MersenneTwisterRandomVariateGenerator::StateVectorLength, pNext = state;
00320 }
00321
00322
00323
00324 #define SVL 624
00325 inline void
00326 MersenneTwisterRandomVariateGenerator::SetSeed(
00327 IntegerType * const bigSeed, const IntegerType seedLength )
00328 {
00329
00330
00331
00332
00333
00334
00335
00336 Initialize(19650218UL);
00337 register IntegerType i = 1;
00338 register IntegerType j = 0;
00339 register int k;
00340 if ( StateVectorLength > seedLength )
00341 {
00342 k = StateVectorLength;
00343 }
00344 else
00345 {
00346 k = seedLength;
00347 }
00348 for( ; k; --k )
00349 {
00350 state[i] =
00351 state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1664525UL );
00352 state[i] += ( bigSeed[j] & 0xffffffffUL ) + j;
00353 state[i] &= 0xffffffffUL;
00354 ++i; ++j;
00355 if( i >= StateVectorLength ) { state[0] = state[StateVectorLength-1]; i = 1; }
00356 if( j >= seedLength ) j = 0;
00357 }
00358 for( k = StateVectorLength - 1; k; --k )
00359 {
00360 state[i] =
00361 state[i] ^ ( (state[i-1] ^ (state[i-1] >> 30)) * 1566083941UL );
00362 state[i] -= i;
00363 state[i] &= 0xffffffffUL;
00364 ++i;
00365 if( i >= SVL )
00366 {
00367 state[0] = state[StateVectorLength-1]; i = 1;
00368 }
00369 }
00370 state[0] = 0x80000000UL;
00371 reload();
00372 }
00373
00374
00375 inline void
00376 MersenneTwisterRandomVariateGenerator::Initialize()
00377 {
00378 SetSeed();
00379 }
00380
00381
00382 inline void
00383 MersenneTwisterRandomVariateGenerator::SetSeed( const IntegerType oneSeed )
00384 {
00385
00386 Initialize(oneSeed);
00387 reload();
00388 }
00389
00390
00391 inline void
00392 MersenneTwisterRandomVariateGenerator::SetSeed()
00393 {
00394
00395
00396
00397
00398
00399
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414 SetSeed( hash( vcl_time(0), vcl_clock() ) );
00415 }
00416
00417
00418
00420 inline MersenneTwisterRandomVariateGenerator::IntegerType
00421 MersenneTwisterRandomVariateGenerator::GetIntegerVariate()
00422 {
00423 if( left == 0 ) reload();
00424 --left;
00425
00426 register IntegerType s1;
00427 s1 = *pNext++;
00428 s1 ^= (s1 >> 11);
00429 s1 ^= (s1 << 7) & 0x9d2c5680UL;
00430 s1 ^= (s1 << 15) & 0xefc60000UL;
00431 return ( s1 ^ (s1 >> 18) );
00432 }
00433
00434
00435 inline double
00436 MersenneTwisterRandomVariateGenerator::GetVariateWithClosedRange()
00437 {
00438 return double(GetIntegerVariate()) * (1.0/4294967295.0);
00439 }
00440
00442 inline double
00443 MersenneTwisterRandomVariateGenerator::GetVariateWithClosedRange(
00444 const double& n )
00445 {
00446 return rand() * n;
00447 }
00448
00450 inline double
00451 MersenneTwisterRandomVariateGenerator::GetVariateWithOpenUpperRange()
00452 {
00453 return double(GetIntegerVariate()) * (1.0/4294967296.0);
00454 }
00455
00457 inline double
00458 MersenneTwisterRandomVariateGenerator::GetVariateWithOpenUpperRange(
00459 const double& n )
00460 {
00461 return GetVariateWithOpenUpperRange() * n;
00462 }
00463
00465 inline double
00466 MersenneTwisterRandomVariateGenerator::GetVariateWithOpenRange()
00467 {
00468 return ( double(GetIntegerVariate()) + 0.5 ) * (1.0/4294967296.0);
00469 }
00470
00471
00473 inline double
00474 MersenneTwisterRandomVariateGenerator::GetVariateWithOpenRange(
00475 const double& n )
00476 {
00477 return GetVariateWithOpenRange() * n;
00478 }
00479
00480
00481 inline MersenneTwisterRandomVariateGenerator::IntegerType
00482 MersenneTwisterRandomVariateGenerator::GetIntegerVariate(
00483 const IntegerType& n )
00484 {
00485
00486
00487 IntegerType used = n;
00488 used |= used >> 1;
00489 used |= used >> 2;
00490 used |= used >> 4;
00491 used |= used >> 8;
00492 used |= used >> 16;
00493
00494
00495 IntegerType i;
00496 do
00497 {
00498 i = GetIntegerVariate() & used;
00499 } while( i > n );
00500
00501 return i;
00502 }
00503
00504
00505
00508 inline double
00509 MersenneTwisterRandomVariateGenerator::Get53BitVariate()
00510 {
00511 IntegerType a = GetIntegerVariate() >> 5, b = GetIntegerVariate() >> 6;
00512 return ( a * 67108864.0 + b ) * (1.0/9007199254740992.0);
00513 }
00514
00515
00516
00517
00518 inline double
00519 MersenneTwisterRandomVariateGenerator::GetNormalVariate(
00520 const double& mean, const double& variance )
00521 {
00522
00523
00524 double r = vcl_sqrt( -2.0 * vcl_log( 1.0-GetVariateWithOpenRange()) ) * variance;
00525 double phi = 2.0 * 3.14159265358979323846264338328
00526 * GetVariateWithOpenUpperRange();
00527 return mean + r * vcl_cos(phi);
00528 }
00529
00530
00531
00532
00533
00534 inline double
00535 MersenneTwisterRandomVariateGenerator::GetUniformVariate(
00536 const double& a, const double& b )
00537 {
00538 double u = GetVariateWithOpenUpperRange();
00539 return ((1.0 -u) * a + u * b);
00540 }
00541
00542
00543 inline double
00544 MersenneTwisterRandomVariateGenerator::GetVariate()
00545 {
00546 return GetVariateWithClosedRange();
00547 }
00548
00549
00550 inline double
00551 MersenneTwisterRandomVariateGenerator::operator()()
00552 {
00553 return GetVariate();
00554 }
00555
00556
00557 inline
00558 MersenneTwisterRandomVariateGenerator::MersenneTwisterRandomVariateGenerator()
00559 {
00560 SetSeed ( 121212 );
00561 }
00562
00563
00564
00565
00566
00567
00568
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579
00580
00581
00582
00583
00584
00585
00586
00587
00588
00589
00590
00591
00592
00593
00594
00595
00596
00597
00598
00599
00600
00601
00602
00603
00604
00605 }
00606 }
00607
00608 #endif
00609
00610