Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/clhep/src/MTwistEngine.cc

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

Diff markup

Differences between /externals/clhep/src/MTwistEngine.cc (Version 11.3.0) and /externals/clhep/src/MTwistEngine.cc (Version 10.7.p3)


  1 // -*- C++ -*-                                      1 // -*- C++ -*-
  2 //                                                  2 //
  3 // -------------------------------------------      3 // -----------------------------------------------------------------------
  4 //                             HEP Random           4 //                             HEP Random
  5 //                        --- MTwistEngine ---      5 //                        --- MTwistEngine ---
  6 //                      class implementation f      6 //                      class implementation file
  7 // -------------------------------------------      7 // -----------------------------------------------------------------------
  8 // A "fast, compact, huge-period generator" ba      8 // A "fast, compact, huge-period generator" based on M. Matsumoto and 
  9 // T. Nishimura, "Mersenne Twister: A 623-dime      9 // T. Nishimura, "Mersenne Twister: A 623-dimensionally equidistributed 
 10 // uniform pseudorandom number generator", to      10 // uniform pseudorandom number generator", to appear in ACM Trans. on
 11 // Modeling and Computer Simulation.  It is a      11 // Modeling and Computer Simulation.  It is a twisted GFSR generator
 12 // with a Mersenne-prime period of 2^19937-1,      12 // with a Mersenne-prime period of 2^19937-1, uniform on open interval (0,1)
 13 // ===========================================     13 // =======================================================================
 14 // Ken Smith      - Started initial draft:         14 // Ken Smith      - Started initial draft:                    14th Jul 1998
 15 //                - Optimized to get std::pow(     15 //                - Optimized to get std::pow() out of flat() method
 16 //                - Added conversion operators     16 //                - Added conversion operators:                6th Aug 1998
 17 // J. Marraffino  - Added some explicit casts      17 // J. Marraffino  - Added some explicit casts to deal with
 18 //                  machines where sizeof(int)     18 //                  machines where sizeof(int) != sizeof(long)  22 Aug 1998
 19 // M. Fischler    - Modified constructors such     19 // M. Fischler    - Modified constructors such that no two
 20 //        seeds will match sequences, no singl     20 //        seeds will match sequences, no single/double
 21 //        seeds will match, explicit seeds giv     21 //        seeds will match, explicit seeds give 
 22 //        determined results, and default will     22 //        determined results, and default will not 
 23 //        match any of the above or other defa     23 //        match any of the above or other defaults.
 24 //                - Modified use of the variou     24 //                - Modified use of the various exponents of 2
 25 //                  to avoid per-instance spac     25 //                  to avoid per-instance space overhead and
 26 //                  correct the rounding proce     26 //                  correct the rounding procedure              16 Sep 1998
 27 // J. Marraffino  - Remove dependence on hepSt     27 // J. Marraffino  - Remove dependence on hepString class        13 May 1999
 28 // M. Fischler    - In restore, checkFile for      28 // M. Fischler    - In restore, checkFile for file not found    03 Dec 2004
 29 // M. Fischler    - Methods for distrib. insta     29 // M. Fischler    - Methods for distrib. instacne save/restore  12/8/04    
 30 // M. Fischler    - split get() into tag valid     30 // M. Fischler    - split get() into tag validation and 
 31 //                  getState() for anonymous r     31 //                  getState() for anonymous restores           12/27/04    
 32 // M. Fischler    - put/get for vectors of ulo     32 // M. Fischler    - put/get for vectors of ulongs   3/14/05
 33 // M. Fischler    - State-saving using only in     33 // M. Fischler    - State-saving using only ints, for portability 4/12/05
 34 // M. Fischler    - Improved seeding in setSee     34 // M. Fischler    - Improved seeding in setSeed  (Savanah bug #17479) 11/15/06
 35 //      - (Possible optimization - now that th     35 //      - (Possible optimization - now that the seeding is improved,
 36 //        is it still necessary for ctor to "w     36 //        is it still necessary for ctor to "warm up" by discarding
 37 //        2000 iterations?)                        37 //        2000 iterations?)
 38 //                                                 38 //        
 39 // ===========================================     39 // =======================================================================
 40                                                    40 
 41 #include "CLHEP/Random/Random.h"                   41 #include "CLHEP/Random/Random.h"
 42 #include "CLHEP/Random/MTwistEngine.h"             42 #include "CLHEP/Random/MTwistEngine.h"
 43 #include "CLHEP/Random/engineIDulong.h"            43 #include "CLHEP/Random/engineIDulong.h"
 44 #include "CLHEP/Utility/atomic_int.h"              44 #include "CLHEP/Utility/atomic_int.h"
 45                                                    45 
 46 #include <atomic>                                  46 #include <atomic>
 47 #include <cmath>                                   47 #include <cmath>
 48 #include <iostream>                                48 #include <iostream>
 49 #include <string.h>        // for strcmp           49 #include <string.h>        // for strcmp
 50 #include <vector>                                  50 #include <vector>
 51                                                    51 
 52 namespace CLHEP {                                  52 namespace CLHEP {
 53                                                    53 
 54 namespace {                                        54 namespace {
 55   // Number of instances with automatic seed s     55   // Number of instances with automatic seed selection
 56   CLHEP_ATOMIC_INT_TYPE numberOfEngines(0);        56   CLHEP_ATOMIC_INT_TYPE numberOfEngines(0);
 57                                                    57 
 58   // Maximum index into the seed table             58   // Maximum index into the seed table
 59   const int maxIndex = 215;                        59   const int maxIndex = 215;
 60 }                                                  60 }
 61                                                    61 
 62 static const int MarkerLen = 64; // Enough roo     62 static const int MarkerLen = 64; // Enough room to hold a begin or end marker. 
 63                                                    63 
 64 std::string MTwistEngine::name() const {return     64 std::string MTwistEngine::name() const {return "MTwistEngine";}
 65                                                    65 
 66 MTwistEngine::MTwistEngine()                       66 MTwistEngine::MTwistEngine() 
 67 : HepRandomEngine()                                67 : HepRandomEngine()
 68 {                                                  68 {
 69   int numEngines = numberOfEngines++;              69   int numEngines = numberOfEngines++;
 70   int cycle = std::abs(int(numEngines/maxIndex     70   int cycle = std::abs(int(numEngines/maxIndex));
 71   int curIndex = std::abs(int(numEngines%maxIn     71   int curIndex = std::abs(int(numEngines%maxIndex));
 72   long mask = ((cycle & 0x007fffff) << 8);         72   long mask = ((cycle & 0x007fffff) << 8);
 73   long seedlist[2];                                73   long seedlist[2];
 74   HepRandom::getTheTableSeeds( seedlist, curIn     74   HepRandom::getTheTableSeeds( seedlist, curIndex );
 75   seedlist[0] = (seedlist[0])^mask;                75   seedlist[0] = (seedlist[0])^mask;
 76   seedlist[1] = 0;                                 76   seedlist[1] = 0;
 77   setSeeds( seedlist, numEngines );                77   setSeeds( seedlist, numEngines );
 78   count624=0;                                      78   count624=0;
 79                                                    79 
 80   for( int i=0; i < 2000; ++i ) flat();      /     80   for( int i=0; i < 2000; ++i ) flat();      // Warm up just a bit
 81 }                                                  81 }
 82                                                    82 
 83 MTwistEngine::MTwistEngine(long seed)              83 MTwistEngine::MTwistEngine(long seed)  
 84 : HepRandomEngine()                                84 : HepRandomEngine()
 85 {                                                  85 {
 86   long seedlist[2]={seed,17587};                   86   long seedlist[2]={seed,17587};
 87   setSeeds( seedlist, 0 );                         87   setSeeds( seedlist, 0 );
 88   count624=0;                                      88   count624=0;
 89   for( int i=0; i < 2000; ++i ) flat();      /     89   for( int i=0; i < 2000; ++i ) flat();      // Warm up just a bit
 90 }                                                  90 }
 91                                                    91 
 92 MTwistEngine::MTwistEngine(int rowIndex, int c     92 MTwistEngine::MTwistEngine(int rowIndex, int colIndex) 
 93 : HepRandomEngine()                                93 : HepRandomEngine()
 94 {                                                  94 {
 95   int cycle = std::abs(int(rowIndex/maxIndex))     95   int cycle = std::abs(int(rowIndex/maxIndex));
 96   int row = std::abs(int(rowIndex%maxIndex));      96   int row = std::abs(int(rowIndex%maxIndex));
 97   int col = std::abs(int(colIndex%2));             97   int col = std::abs(int(colIndex%2));
 98   long mask = (( cycle & 0x000007ff ) << 20 );     98   long mask = (( cycle & 0x000007ff ) << 20 );
 99   long seedlist[2];                                99   long seedlist[2];
100   HepRandom::getTheTableSeeds( seedlist, row )    100   HepRandom::getTheTableSeeds( seedlist, row );
101   seedlist[0] = (seedlist[col])^mask;             101   seedlist[0] = (seedlist[col])^mask;
102   seedlist[1] = 690691;                           102   seedlist[1] = 690691;
103   setSeeds(seedlist, 4444772);                    103   setSeeds(seedlist, 4444772);
104   count624=0;                                     104   count624=0;
105   for( int i=0; i < 2000; ++i ) flat();      /    105   for( int i=0; i < 2000; ++i ) flat();      // Warm up just a bit
106 }                                                 106 }
107                                                   107 
108 MTwistEngine::MTwistEngine( std::istream& is )    108 MTwistEngine::MTwistEngine( std::istream& is )  
109 : HepRandomEngine()                               109 : HepRandomEngine()
110 {                                                 110 {
111   is >> *this;                                    111   is >> *this;
112 }                                                 112 }
113                                                   113 
114 MTwistEngine::~MTwistEngine() {}                  114 MTwistEngine::~MTwistEngine() {}
115                                                   115 
116 double MTwistEngine::flat() {                     116 double MTwistEngine::flat() {
117   unsigned int y;                                 117   unsigned int y;
118                                                   118 
119    if( count624 >= N ) {                          119    if( count624 >= N ) {
120     int i;                                        120     int i;
121                                                   121 
122     for( i=0; i < NminusM; ++i ) {                122     for( i=0; i < NminusM; ++i ) {
123       y = (mt[i] & 0x80000000) | (mt[i+1] & 0x    123       y = (mt[i] & 0x80000000) | (mt[i+1] & 0x7fffffff);
124       mt[i] = mt[i+M]       ^ (y >> 1) ^ ((y &    124       mt[i] = mt[i+M]       ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
125     }                                             125     }
126                                                   126 
127     for(    ; i < N-1    ; ++i ) {                127     for(    ; i < N-1    ; ++i ) {
128       y = (mt[i] & 0x80000000) | (mt[i+1] & 0x    128       y = (mt[i] & 0x80000000) | (mt[i+1] & 0x7fffffff);
129       mt[i] = mt[i-NminusM] ^ (y >> 1) ^ ((y &    129       mt[i] = mt[i-NminusM] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
130     }                                             130     }
131                                                   131 
132     y = (mt[i] & 0x80000000) | (mt[0] & 0x7fff    132     y = (mt[i] & 0x80000000) | (mt[0] & 0x7fffffff);
133     mt[i] = mt[M-1] ^ (y >> 1) ^ ((y & 0x1) ?     133     mt[i] = mt[M-1] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
134                                                   134 
135     count624 = 0;                                 135     count624 = 0;
136   }                                               136   }
137                                                   137 
138   y = mt[count624];                               138   y = mt[count624];
139   y ^= ( y >> 11);                                139   y ^= ( y >> 11);
140   y ^= ((y << 7 ) & 0x9d2c5680);                  140   y ^= ((y << 7 ) & 0x9d2c5680);
141   y ^= ((y << 15) & 0xefc60000);                  141   y ^= ((y << 15) & 0xefc60000);
142   y ^= ( y >> 18);                                142   y ^= ( y >> 18);
143                                                   143 
144   return                      y * twoToMinus_3    144   return                      y * twoToMinus_32()  +    // Scale to range 
145          (mt[count624++] >> 11) * twoToMinus_5    145          (mt[count624++] >> 11) * twoToMinus_53()  +    // fill remaining bits
146                       nearlyTwoToMinus_54();      146                       nearlyTwoToMinus_54();      // make sure non-zero
147 }                                                 147 }
148                                                   148 
149 void MTwistEngine::flatArray( const int size,     149 void MTwistEngine::flatArray( const int size, double *vect ) {
150   for( int i=0; i < size; ++i) vect[i] = flat(    150   for( int i=0; i < size; ++i) vect[i] = flat();
151 }                                                 151 }
152                                                   152 
153 void MTwistEngine::setSeed(long seed, int k) {    153 void MTwistEngine::setSeed(long seed, int k) {
154                                                   154 
155   // MF 11/15/06 - Change seeding algorithm to    155   // MF 11/15/06 - Change seeding algorithm to a newer one recommended 
156   //               by Matsumoto: The original     156   //               by Matsumoto: The original algorithm was 
157   //       mt[i] = (69069 * mt[i-1]) & 0xfffff    157   //       mt[i] = (69069 * mt[i-1]) & 0xffffffff and this gives
158   //       problems when the seed bit pattern     158   //       problems when the seed bit pattern has lots of zeros
159   //       (for example, 0x08000000).  Savanah    159   //       (for example, 0x08000000).  Savanah bug #17479.
160                                                   160 
161   theSeed = seed ? seed : 4357;                   161   theSeed = seed ? seed : 4357;
162   int mti;                                        162   int mti;
163   const int N1=624;                               163   const int N1=624;
164   mt[0] = (unsigned int) (theSeed&0xffffffffUL    164   mt[0] = (unsigned int) (theSeed&0xffffffffUL);
165   for (mti=1; mti<N1; mti++) {                    165   for (mti=1; mti<N1; mti++) {
166     mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt    166     mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti); 
167         /* See Knuth TAOCP Vol2. 3rd Ed. P.106    167         /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
168         /* In the previous versions, MSBs of t    168         /* In the previous versions, MSBs of the seed affect   */
169         /* only MSBs of the array mt[].           169         /* only MSBs of the array mt[].                        */
170         /* 2002/01/09 modified by Makoto Matsu    170         /* 2002/01/09 modified by Makoto Matsumoto             */
171     mt[mti] &= 0xffffffffUL;                      171     mt[mti] &= 0xffffffffUL;
172         /* for >32 bit machines */                172         /* for >32 bit machines */
173   }                                               173   }
174   for( int i=1; i < 624; ++i ) {                  174   for( int i=1; i < 624; ++i ) {
175     mt[i] ^= k;     // MF 9/16/98: distinguish    175     mt[i] ^= k;     // MF 9/16/98: distinguish starting points
176   }                                               176   }
177   // MF 11/15/06 This distinction of starting     177   // MF 11/15/06 This distinction of starting points based on values of k
178   //             is kept even though the seedi    178   //             is kept even though the seeding algorithm itself is improved.
179 }                                                 179 }
180                                                   180 
181 void MTwistEngine::setSeeds(const long *seeds,    181 void MTwistEngine::setSeeds(const long *seeds, int k) {
182   setSeed( (*seeds ? *seeds : 43571346), k );     182   setSeed( (*seeds ? *seeds : 43571346), k );
183   int i;                                          183   int i;
184   for( i=1; i < 624; ++i ) {                      184   for( i=1; i < 624; ++i ) {
185     mt[i] = ( seeds[1] + mt[i] ) & 0xffffffff;    185     mt[i] = ( seeds[1] + mt[i] ) & 0xffffffff; // MF 9/16/98 
186   }                                               186   }
187   theSeeds = seeds;                               187   theSeeds = seeds;
188 }                                                 188 }
189                                                   189 
190 void MTwistEngine::saveStatus( const char file    190 void MTwistEngine::saveStatus( const char filename[] ) const
191 {                                                 191 {
192    std::ofstream outFile( filename, std::ios::    192    std::ofstream outFile( filename, std::ios::out ) ;
193    if (!outFile.bad()) {                          193    if (!outFile.bad()) {
194      outFile << theSeed << std::endl;             194      outFile << theSeed << std::endl;
195      for (int i=0; i<624; ++i) outFile <<std::    195      for (int i=0; i<624; ++i) outFile <<std::setprecision(20) << mt[i] << " ";
196      outFile << std::endl;                        196      outFile << std::endl;
197      outFile << count624 << std::endl;            197      outFile << count624 << std::endl;
198    }                                              198    }
199 }                                                 199 }
200                                                   200 
201 void MTwistEngine::restoreStatus( const char f    201 void MTwistEngine::restoreStatus( const char filename[] )
202 {                                                 202 {
203    std::ifstream inFile( filename, std::ios::i    203    std::ifstream inFile( filename, std::ios::in);
204    if (!checkFile ( inFile, filename, engineNa    204    if (!checkFile ( inFile, filename, engineName(), "restoreStatus" )) {
205      std::cerr << "  -- Engine state remains u    205      std::cerr << "  -- Engine state remains unchanged\n";
206      return;                                      206      return;
207    }                                              207    }
208                                                   208 
209    if (!inFile.bad() && !inFile.eof()) {          209    if (!inFile.bad() && !inFile.eof()) {
210      inFile >> theSeed;                           210      inFile >> theSeed;
211      for (int i=0; i<624; ++i) inFile >> mt[i]    211      for (int i=0; i<624; ++i) inFile >> mt[i];
212      inFile >> count624;                          212      inFile >> count624;
213    }                                              213    }
214 }                                                 214 }
215                                                   215 
216 void MTwistEngine::showStatus() const             216 void MTwistEngine::showStatus() const
217 {                                                 217 {
218    std::cout << std::endl;                        218    std::cout << std::endl;
219    std::cout << "--------- MTwist engine statu    219    std::cout << "--------- MTwist engine status ---------" << std::endl;
220    std::cout << std::setprecision(20);            220    std::cout << std::setprecision(20);
221    std::cout << " Initial seed      = " << the    221    std::cout << " Initial seed      = " << theSeed << std::endl;
222    std::cout << " Current index     = " << cou    222    std::cout << " Current index     = " << count624 << std::endl;
223    std::cout << " Array status mt[] = " << std    223    std::cout << " Array status mt[] = " << std::endl;
224    // 2014/06/06  L Garren                        224    // 2014/06/06  L Garren
225    // the final line has 4 elements, not 5        225    // the final line has 4 elements, not 5
226    for (int i=0; i<620; i+=5) {                   226    for (int i=0; i<620; i+=5) {
227      std::cout << mt[i]   << " " << mt[i+1] <<    227      std::cout << mt[i]   << " " << mt[i+1] << " " << mt[i+2] << " " 
228          << mt[i+3] << " " << mt[i+4] << "\n";    228          << mt[i+3] << " " << mt[i+4] << "\n";
229    }                                              229    }
230    std::cout << mt[620]   << " " << mt[621] <<    230    std::cout << mt[620]   << " " << mt[621] << " " << mt[622] << " " 
231        << mt[623]  << std::endl;                  231        << mt[623]  << std::endl;
232    std::cout << "-----------------------------    232    std::cout << "----------------------------------------" << std::endl;
233 }                                                 233 }
234                                                   234 
235 MTwistEngine::operator double() {                 235 MTwistEngine::operator double() {
236   return flat();                                  236   return flat();
237 }                                                 237 }
238                                                   238 
239 MTwistEngine::operator float() {                  239 MTwistEngine::operator float() {
240   unsigned int y;                                 240   unsigned int y;
241                                                   241 
242   if( count624 >= N ) {                           242   if( count624 >= N ) {
243     int i;                                        243     int i;
244                                                   244 
245     for( i=0; i < NminusM; ++i ) {                245     for( i=0; i < NminusM; ++i ) {
246       y = (mt[i] & 0x80000000) | (mt[i+1] & 0x    246       y = (mt[i] & 0x80000000) | (mt[i+1] & 0x7fffffff);
247       mt[i] = mt[i+M]       ^ (y >> 1) ^ ((y &    247       mt[i] = mt[i+M]       ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
248     }                                             248     }
249                                                   249 
250     for(    ; i < N-1    ; ++i ) {                250     for(    ; i < N-1    ; ++i ) {
251       y = (mt[i] & 0x80000000) | (mt[i+1] & 0x    251       y = (mt[i] & 0x80000000) | (mt[i+1] & 0x7fffffff);
252       mt[i] = mt[i-NminusM] ^ (y >> 1) ^ ((y &    252       mt[i] = mt[i-NminusM] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
253     }                                             253     }
254                                                   254 
255     y = (mt[i] & 0x80000000) | (mt[0] & 0x7fff    255     y = (mt[i] & 0x80000000) | (mt[0] & 0x7fffffff);
256     mt[i] = mt[M-1] ^ (y >> 1) ^ ((y & 0x1) ?     256     mt[i] = mt[M-1] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
257                                                   257 
258     count624 = 0;                                 258     count624 = 0;
259   }                                               259   }
260                                                   260 
261   y = mt[count624++];                             261   y = mt[count624++];
262   y ^= ( y >> 11);                                262   y ^= ( y >> 11);
263   y ^= ((y << 7 ) & 0x9d2c5680);                  263   y ^= ((y << 7 ) & 0x9d2c5680);
264   y ^= ((y << 15) & 0xefc60000);                  264   y ^= ((y << 15) & 0xefc60000);
265   y ^= ( y >> 18);                                265   y ^= ( y >> 18);
266                                                   266 
267   return (float)(y * twoToMinus_32());            267   return (float)(y * twoToMinus_32());
268 }                                                 268 }
269                                                   269 
270 MTwistEngine::operator unsigned int() {           270 MTwistEngine::operator unsigned int() {
271   unsigned int y;                                 271   unsigned int y;
272                                                   272 
273   if( count624 >= N ) {                           273   if( count624 >= N ) {
274     int i;                                        274     int i;
275                                                   275 
276     for( i=0; i < NminusM; ++i ) {                276     for( i=0; i < NminusM; ++i ) {
277       y = (mt[i] & 0x80000000) | (mt[i+1] & 0x    277       y = (mt[i] & 0x80000000) | (mt[i+1] & 0x7fffffff);
278       mt[i] = mt[i+M]       ^ (y >> 1) ^ ((y &    278       mt[i] = mt[i+M]       ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
279     }                                             279     }
280                                                   280 
281     for(    ; i < N-1    ; ++i ) {                281     for(    ; i < N-1    ; ++i ) {
282       y = (mt[i] & 0x80000000) | (mt[i+1] & 0x    282       y = (mt[i] & 0x80000000) | (mt[i+1] & 0x7fffffff);
283       mt[i] = mt[i-NminusM] ^ (y >> 1) ^ ((y &    283       mt[i] = mt[i-NminusM] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
284     }                                             284     }
285                                                   285 
286     y = (mt[i] & 0x80000000) | (mt[0] & 0x7fff    286     y = (mt[i] & 0x80000000) | (mt[0] & 0x7fffffff);
287     mt[i] = mt[M-1] ^ (y >> 1) ^ ((y & 0x1) ?     287     mt[i] = mt[M-1] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
288                                                   288 
289     count624 = 0;                                 289     count624 = 0;
290   }                                               290   }
291                                                   291 
292   y = mt[count624++];                             292   y = mt[count624++];
293   y ^= ( y >> 11);                                293   y ^= ( y >> 11);
294   y ^= ((y << 7 ) & 0x9d2c5680);                  294   y ^= ((y << 7 ) & 0x9d2c5680);
295   y ^= ((y << 15) & 0xefc60000);                  295   y ^= ((y << 15) & 0xefc60000);
296   y ^= ( y >> 18);                                296   y ^= ( y >> 18);
297                                                   297 
298   return y;                                       298   return y;
299 }                                                 299 }
300                                                   300 
301 std::ostream & MTwistEngine::put ( std::ostrea    301 std::ostream & MTwistEngine::put ( std::ostream& os ) const
302 {                                                 302 {
303    char beginMarker[] = "MTwistEngine-begin";     303    char beginMarker[] = "MTwistEngine-begin";
304    char endMarker[]   = "MTwistEngine-end";       304    char endMarker[]   = "MTwistEngine-end";
305                                                   305 
306    long pr = os.precision(20);                 << 306    int pr = os.precision(20);
307    os << " " << beginMarker << " ";               307    os << " " << beginMarker << " ";
308    os << theSeed << " ";                          308    os << theSeed << " ";
309    for (int i=0; i<624; ++i) {                    309    for (int i=0; i<624; ++i) {
310      os << mt[i] << "\n";                         310      os << mt[i] << "\n";
311    }                                              311    }
312    os << count624 << " ";                         312    os << count624 << " ";
313    os << endMarker << "\n";                       313    os << endMarker << "\n";
314    os.precision(pr);                              314    os.precision(pr);
315    return os;                                     315    return os;
316 }                                                 316 }
317                                                   317 
318 std::vector<unsigned long> MTwistEngine::put (    318 std::vector<unsigned long> MTwistEngine::put () const {
319   std::vector<unsigned long> v;                   319   std::vector<unsigned long> v;
320   v.push_back (engineIDulong<MTwistEngine>());    320   v.push_back (engineIDulong<MTwistEngine>());
321   for (int i=0; i<624; ++i) {                     321   for (int i=0; i<624; ++i) {
322      v.push_back(static_cast<unsigned long>(mt    322      v.push_back(static_cast<unsigned long>(mt[i]));
323   }                                               323   }
324   v.push_back(count624);                          324   v.push_back(count624); 
325   return v;                                       325   return v;
326 }                                                 326 }
327                                                   327 
328 std::istream &  MTwistEngine::get ( std::istre    328 std::istream &  MTwistEngine::get ( std::istream& is )
329 {                                                 329 {
330   char beginMarker [MarkerLen];                   330   char beginMarker [MarkerLen];
331   is >> std::ws;                                  331   is >> std::ws;
332   is.width(MarkerLen);  // causes the next rea    332   is.width(MarkerLen);  // causes the next read to the char* to be <=
333       // that many bytes, INCLUDING A TERMINAT    333       // that many bytes, INCLUDING A TERMINATION \0 
334       // (Stroustrup, section 21.3.2)             334       // (Stroustrup, section 21.3.2)
335   is >> beginMarker;                              335   is >> beginMarker;
336   if (strcmp(beginMarker,"MTwistEngine-begin")    336   if (strcmp(beginMarker,"MTwistEngine-begin")) {
337      is.clear(std::ios::badbit | is.rdstate())    337      is.clear(std::ios::badbit | is.rdstate());
338      std::cerr << "\nInput stream mispositione    338      std::cerr << "\nInput stream mispositioned or"
339          << "\nMTwistEngine state description     339          << "\nMTwistEngine state description missing or"
340          << "\nwrong engine type found." << st    340          << "\nwrong engine type found." << std::endl;
341      return is;                                   341      return is;
342    }                                              342    }
343   return getState(is);                            343   return getState(is);
344 }                                                 344 }
345                                                   345 
346 std::string MTwistEngine::beginTag ( )  {         346 std::string MTwistEngine::beginTag ( )  { 
347   return "MTwistEngine-begin";                    347   return "MTwistEngine-begin"; 
348 }                                                 348 }
349                                                   349 
350 std::istream &  MTwistEngine::getState ( std::    350 std::istream &  MTwistEngine::getState ( std::istream& is )
351 {                                                 351 {
352   char endMarker   [MarkerLen];                   352   char endMarker   [MarkerLen];
353   is >> theSeed;                                  353   is >> theSeed;
354   for (int i=0; i<624; ++i)  is >> mt[i];         354   for (int i=0; i<624; ++i)  is >> mt[i];
355   is >> count624;                                 355   is >> count624;
356   is >> std::ws;                                  356   is >> std::ws;
357   is.width(MarkerLen);                            357   is.width(MarkerLen);  
358   is >> endMarker;                                358   is >> endMarker;
359   if (strcmp(endMarker,"MTwistEngine-end")) {     359   if (strcmp(endMarker,"MTwistEngine-end")) {
360      is.clear(std::ios::badbit | is.rdstate())    360      is.clear(std::ios::badbit | is.rdstate());
361      std::cerr << "\nMTwistEngine state descri    361      std::cerr << "\nMTwistEngine state description incomplete."
362          << "\nInput stream is probably mispos    362          << "\nInput stream is probably mispositioned now." << std::endl;
363      return is;                                   363      return is;
364    }                                              364    }
365    return is;                                     365    return is;
366 }                                                 366 }
367                                                   367 
368 bool MTwistEngine::get (const std::vector<unsi    368 bool MTwistEngine::get (const std::vector<unsigned long> & v) {
369   if ((v[0] & 0xffffffffUL) != engineIDulong<M    369   if ((v[0] & 0xffffffffUL) != engineIDulong<MTwistEngine>()) {
370     std::cerr <<                                  370     std::cerr << 
371       "\nMTwistEngine get:state vector has wro    371       "\nMTwistEngine get:state vector has wrong ID word - state unchanged\n";
372     return false;                                 372     return false;
373   }                                               373   }
374   return getState(v);                             374   return getState(v);
375 }                                                 375 }
376                                                   376 
377 bool MTwistEngine::getState (const std::vector    377 bool MTwistEngine::getState (const std::vector<unsigned long> & v) {
378   if (v.size() != VECTOR_STATE_SIZE ) {           378   if (v.size() != VECTOR_STATE_SIZE ) {
379     std::cerr <<                                  379     std::cerr << 
380       "\nMTwistEngine get:state vector has wro    380       "\nMTwistEngine get:state vector has wrong length - state unchanged\n";
381     return false;                                 381     return false;
382   }                                               382   }
383   for (int i=0; i<624; ++i) {                     383   for (int i=0; i<624; ++i) {
384      mt[i]=(unsigned int)v[i+1];               << 384      mt[i]=v[i+1];
385   }                                               385   }
386   count624 = (int)v[625];                      << 386   count624 = v[625];
387   return true;                                    387   return true;
388 }                                                 388 }
389                                                   389 
390 }  // namespace CLHEP                             390 }  // namespace CLHEP
391                                                   391