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