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.0.p3)


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