42 #include "CLHEP/Random/Random.h"
43 #include "CLHEP/Random/MTwistEngine.h"
44 #include "CLHEP/Random/engineIDulong.h"
45 #include "CLHEP/Utility/atomic_int.h"
54 CLHEP_ATOMIC_INT_TYPE numberOfEngines(0);
57 const int maxIndex = 215;
64 MTwistEngine::MTwistEngine()
67 int numEngines = numberOfEngines++;
68 int cycle = std::abs(
int(numEngines/maxIndex));
69 int curIndex = std::abs(
int(numEngines%maxIndex));
70 long mask = ((cycle & 0x007fffff) << 8);
72 HepRandom::getTheTableSeeds( seedlist, curIndex );
73 seedlist[0] = (seedlist[0])^mask;
78 for(
int i=0; i < 2000; ++i )
flat();
81 MTwistEngine::MTwistEngine(
long seed)
84 long seedlist[2]={
seed,17587};
87 for(
int i=0; i < 2000; ++i )
flat();
90 MTwistEngine::MTwistEngine(
int rowIndex,
int colIndex)
93 int cycle = std::abs(
int(rowIndex/maxIndex));
94 int row = std::abs(
int(rowIndex%maxIndex));
95 int col = std::abs(
int(colIndex%2));
96 long mask = (( cycle & 0x000007ff ) << 20 );
98 HepRandom::getTheTableSeeds( seedlist, row );
99 seedlist[0] = (seedlist[col])^mask;
100 seedlist[1] = 690691;
103 for(
int i=0; i < 2000; ++i )
flat();
106 MTwistEngine::MTwistEngine( std::istream& is )
112 MTwistEngine::~MTwistEngine() {}
117 if( count624 >= N ) {
120 for( i=0; i < NminusM; ++i ) {
121 y = (mt[i] & 0x80000000) | (mt[i+1] & 0x7fffffff);
122 mt[i] = mt[i+M] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
125 for( ; i < N-1 ; ++i ) {
126 y = (mt[i] & 0x80000000) | (mt[i+1] & 0x7fffffff);
127 mt[i] = mt[i-NminusM] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
130 y = (mt[i] & 0x80000000) | (mt[0] & 0x7fffffff);
131 mt[i] = mt[M-1] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
138 y ^= ((y << 7 ) & 0x9d2c5680);
139 y ^= ((y << 15) & 0xefc60000);
142 return y * twoToMinus_32() +
143 (mt[count624++] >> 11) * twoToMinus_53() +
144 nearlyTwoToMinus_54();
147 void MTwistEngine::flatArray(
const int size,
double *vect ) {
148 for(
int i=0; i < size; ++i) vect[i] =
flat();
151 void MTwistEngine::setSeed(
long seed,
int k) {
159 theSeed = seed ? seed : 4357;
162 mt[0] = (
unsigned int) (theSeed&0xffffffffUL);
163 for (mti=1; mti<N1; mti++) {
164 mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
169 mt[mti] &= 0xffffffffUL;
172 for(
int i=1; i < 624; ++i ) {
180 setSeed( (*seeds ? *seeds : 43571346), k );
182 for( i=1; i < 624; ++i ) {
183 mt[i] = ( seeds[1] + mt[i] ) & 0xffffffff;
188 void MTwistEngine::saveStatus(
const char filename[] )
const
190 std::ofstream outFile( filename, std::ios::out ) ;
191 if (!outFile.bad()) {
192 outFile << theSeed << std::endl;
193 for (
int i=0; i<624; ++i) outFile <<std::setprecision(20) << mt[i] <<
" ";
194 outFile << std::endl;
195 outFile << count624 << std::endl;
199 void MTwistEngine::restoreStatus(
const char filename[] )
201 std::ifstream inFile( filename, std::ios::in);
202 if (!checkFile ( inFile, filename, engineName(),
"restoreStatus" )) {
203 std::cerr <<
" -- Engine state remains unchanged\n";
207 if (!inFile.bad() && !inFile.eof()) {
209 for (
int i=0; i<624; ++i) inFile >> mt[i];
214 void MTwistEngine::showStatus()
const
216 std::cout << std::endl;
217 std::cout <<
"--------- MTwist engine status ---------" << std::endl;
218 std::cout << std::setprecision(20);
219 std::cout <<
" Initial seed = " << theSeed << std::endl;
220 std::cout <<
" Current index = " << count624 << std::endl;
221 std::cout <<
" Array status mt[] = " << std::endl;
224 for (
int i=0; i<620; i+=5) {
225 std::cout << mt[i] <<
" " << mt[i+1] <<
" " << mt[i+2] <<
" "
226 << mt[i+3] <<
" " << mt[i+4] <<
"\n";
228 std::cout << mt[620] <<
" " << mt[621] <<
" " << mt[622] <<
" "
229 << mt[623] << std::endl;
230 std::cout <<
"----------------------------------------" << std::endl;
233 MTwistEngine::operator float() {
236 if( count624 >= N ) {
239 for( i=0; i < NminusM; ++i ) {
240 y = (mt[i] & 0x80000000) | (mt[i+1] & 0x7fffffff);
241 mt[i] = mt[i+M] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
244 for( ; i < N-1 ; ++i ) {
245 y = (mt[i] & 0x80000000) | (mt[i+1] & 0x7fffffff);
246 mt[i] = mt[i-NminusM] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
249 y = (mt[i] & 0x80000000) | (mt[0] & 0x7fffffff);
250 mt[i] = mt[M-1] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
257 y ^= ((y << 7 ) & 0x9d2c5680);
258 y ^= ((y << 15) & 0xefc60000);
261 return (
float)(y * twoToMinus_32());
264 MTwistEngine::operator
unsigned int() {
267 if( count624 >= N ) {
270 for( i=0; i < NminusM; ++i ) {
271 y = (mt[i] & 0x80000000) | (mt[i+1] & 0x7fffffff);
272 mt[i] = mt[i+M] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
275 for( ; i < N-1 ; ++i ) {
276 y = (mt[i] & 0x80000000) | (mt[i+1] & 0x7fffffff);
277 mt[i] = mt[i-NminusM] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
280 y = (mt[i] & 0x80000000) | (mt[0] & 0x7fffffff);
281 mt[i] = mt[M-1] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
288 y ^= ((y << 7 ) & 0x9d2c5680);
289 y ^= ((y << 15) & 0xefc60000);
295 std::ostream & MTwistEngine::put ( std::ostream& os )
const
297 char beginMarker[] =
"MTwistEngine-begin";
298 char endMarker[] =
"MTwistEngine-end";
300 int pr = os.precision(20);
301 os <<
" " << beginMarker <<
" ";
302 os << theSeed <<
" ";
303 for (
int i=0; i<624; ++i) {
306 os << count624 <<
" ";
307 os << endMarker <<
"\n";
312 std::vector<unsigned long> MTwistEngine::put ()
const {
313 std::vector<unsigned long> v;
314 v.push_back (engineIDulong<MTwistEngine>());
315 for (
int i=0; i<624; ++i) {
316 v.push_back(static_cast<unsigned long>(mt[i]));
318 v.push_back(count624);
322 std::istream & MTwistEngine::get ( std::istream& is )
330 if (strcmp(beginMarker,
"MTwistEngine-begin")) {
331 is.clear(std::ios::badbit | is.rdstate());
332 std::cerr <<
"\nInput stream mispositioned or"
333 <<
"\nMTwistEngine state description missing or"
334 <<
"\nwrong engine type found." << std::endl;
340 std::string MTwistEngine::beginTag ( ) {
341 return "MTwistEngine-begin";
344 std::istream & MTwistEngine::getState ( std::istream& is )
348 for (
int i=0; i<624; ++i) is >> mt[i];
353 if (strcmp(endMarker,
"MTwistEngine-end")) {
354 is.clear(std::ios::badbit | is.rdstate());
355 std::cerr <<
"\nMTwistEngine state description incomplete."
356 <<
"\nInput stream is probably mispositioned now." << std::endl;
362 bool MTwistEngine::get (
const std::vector<unsigned long> & v) {
363 if ((v[0] & 0xffffffffUL) != engineIDulong<MTwistEngine>()) {
365 "\nMTwistEngine get:state vector has wrong ID word - state unchanged\n";
371 bool MTwistEngine::getState (
const std::vector<unsigned long> & v) {
372 if (v.size() != VECTOR_STATE_SIZE ) {
374 "\nMTwistEngine get:state vector has wrong length - state unchanged\n";
377 for (
int i=0; i<624; ++i) {
static const int MarkerLen
const char * name(G4int ptype)
void setSeeds(const SeedVector &sv)
Set the seeds of the current generator.