42 #include "CLHEP/Random/Random.h"
43 #include "CLHEP/Random/MTwistEngine.h"
44 #include "CLHEP/Random/engineIDulong.h"
54 int MTwistEngine::numEngines = 0;
55 int MTwistEngine::maxIndex = 215;
57 MTwistEngine::MTwistEngine()
60 int cycle = std::abs(
int(numEngines/maxIndex));
61 int curIndex = std::abs(
int(numEngines%maxIndex));
62 long mask = ((cycle & 0x007fffff) << 8);
64 HepRandom::getTheTableSeeds( seedlist, curIndex );
65 seedlist[0] = (seedlist[0])^mask;
70 for(
int i=0; i < 2000; ++i )
flat();
73 MTwistEngine::MTwistEngine(
long seed)
76 long seedlist[2]={seed,17587};
79 for(
int i=0; i < 2000; ++i )
flat();
82 MTwistEngine::MTwistEngine(
int rowIndex,
int colIndex)
85 int cycle = std::abs(
int(rowIndex/maxIndex));
86 int row = std::abs(
int(rowIndex%maxIndex));
87 int col = std::abs(
int(colIndex%2));
88 long mask = (( cycle & 0x000007ff ) << 20 );
90 HepRandom::getTheTableSeeds( seedlist, row );
91 seedlist[0] = (seedlist[col])^mask;
95 for(
int i=0; i < 2000; ++i )
flat();
98 MTwistEngine::MTwistEngine( std::istream& is )
104 MTwistEngine::~MTwistEngine() {}
109 if( count624 >= N ) {
112 for( i=0; i < NminusM; ++i ) {
113 y = (mt[i] & 0x80000000) | (mt[i+1] & 0x7fffffff);
114 mt[i] = mt[i+M] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
117 for( ; i < N-1 ; ++i ) {
118 y = (mt[i] & 0x80000000) | (mt[i+1] & 0x7fffffff);
119 mt[i] = mt[i-NminusM] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
122 y = (mt[i] & 0x80000000) | (mt[0] & 0x7fffffff);
123 mt[i] = mt[M-1] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
130 y ^= ((y << 7 ) & 0x9d2c5680);
131 y ^= ((y << 15) & 0xefc60000);
134 return y * twoToMinus_32() +
135 (mt[count624++] >> 11) * twoToMinus_53() +
136 nearlyTwoToMinus_54();
139 void MTwistEngine::flatArray(
const int size,
double *vect ) {
140 for(
int i=0; i < size; ++i) vect[i] =
flat();
143 void MTwistEngine::setSeed(
long seed,
int k) {
151 theSeed = seed ? seed : 4357;
154 mt[0] = (
unsigned int) (theSeed&0xffffffffUL);
155 for (mti=1; mti<N1; mti++) {
156 mt[mti] = (1812433253UL * (mt[mti-1] ^ (mt[mti-1] >> 30)) + mti);
161 mt[mti] &= 0xffffffffUL;
164 for(
int i=1; i < 624; ++i ) {
172 setSeed( (*seeds ? *seeds : 43571346), k );
174 for( i=1; i < 624; ++i ) {
175 mt[i] = ( seeds[1] + mt[i] ) & 0xffffffff;
180 void MTwistEngine::saveStatus(
const char filename[] )
const
182 std::ofstream
outFile( filename, std::ios::out ) ;
184 outFile << theSeed << std::endl;
185 for (
int i=0; i<624; ++i)
outFile <<std::setprecision(20) << mt[i] <<
" ";
187 outFile << count624 << std::endl;
191 void MTwistEngine::restoreStatus(
const char filename[] )
193 std::ifstream inFile( filename, std::ios::in);
194 if (!checkFile ( inFile, filename, engineName(),
"restoreStatus" )) {
195 std::cerr <<
" -- Engine state remains unchanged\n";
199 if (!inFile.bad() && !inFile.eof()) {
201 for (
int i=0; i<624; ++i) inFile >> mt[i];
206 void MTwistEngine::showStatus()
const
208 std::cout << std::endl;
209 std::cout <<
"--------- MTwist engine status ---------" << std::endl;
210 std::cout << std::setprecision(20);
211 std::cout <<
" Initial seed = " << theSeed << std::endl;
212 std::cout <<
" Current index = " << count624 << std::endl;
213 std::cout <<
" Array status mt[] = " << std::endl;
214 for (
int i=0; i<624; i+=5) {
215 std::cout << mt[i] <<
" " << mt[i+1] <<
" " << mt[i+2] <<
" "
216 << mt[i+3] <<
" " << mt[i+4] << std::endl;
218 std::cout <<
"----------------------------------------" << std::endl;
221 MTwistEngine::operator float() {
224 if( count624 >= N ) {
227 for( i=0; i < NminusM; ++i ) {
228 y = (mt[i] & 0x80000000) | (mt[i+1] & 0x7fffffff);
229 mt[i] = mt[i+M] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
232 for( ; i < N-1 ; ++i ) {
233 y = (mt[i] & 0x80000000) | (mt[i+1] & 0x7fffffff);
234 mt[i] = mt[i-NminusM] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
237 y = (mt[i] & 0x80000000) | (mt[0] & 0x7fffffff);
238 mt[i] = mt[M-1] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
245 y ^= ((y << 7 ) & 0x9d2c5680);
246 y ^= ((y << 15) & 0xefc60000);
249 return (
float)(y * twoToMinus_32());
252 MTwistEngine::operator
unsigned int() {
255 if( count624 >= N ) {
258 for( i=0; i < NminusM; ++i ) {
259 y = (mt[i] & 0x80000000) | (mt[i+1] & 0x7fffffff);
260 mt[i] = mt[i+M] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
263 for( ; i < N-1 ; ++i ) {
264 y = (mt[i] & 0x80000000) | (mt[i+1] & 0x7fffffff);
265 mt[i] = mt[i-NminusM] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
268 y = (mt[i] & 0x80000000) | (mt[0] & 0x7fffffff);
269 mt[i] = mt[M-1] ^ (y >> 1) ^ ((y & 0x1) ? 0x9908b0df : 0x0 );
276 y ^= ((y << 7 ) & 0x9d2c5680);
277 y ^= ((y << 15) & 0xefc60000);
283 std::ostream & MTwistEngine::put ( std::ostream& os )
const
285 char beginMarker[] =
"MTwistEngine-begin";
286 char endMarker[] =
"MTwistEngine-end";
288 int pr = os.precision(20);
289 os <<
" " << beginMarker <<
" ";
290 os << theSeed <<
" ";
291 for (
int i=0; i<624; ++i) {
294 os << count624 <<
" ";
295 os << endMarker <<
"\n";
300 std::vector<unsigned long> MTwistEngine::put ()
const {
301 std::vector<unsigned long> v;
302 v.push_back (engineIDulong<MTwistEngine>());
303 for (
int i=0; i<624; ++i) {
304 v.push_back(static_cast<unsigned long>(mt[i]));
306 v.push_back(count624);
310 std::istream & MTwistEngine::get ( std::istream& is )
318 if (strcmp(beginMarker,
"MTwistEngine-begin")) {
319 is.clear(std::ios::badbit | is.rdstate());
320 std::cerr <<
"\nInput stream mispositioned or"
321 <<
"\nMTwistEngine state description missing or"
322 <<
"\nwrong engine type found." << std::endl;
328 std::string MTwistEngine::beginTag ( ) {
329 return "MTwistEngine-begin";
332 std::istream & MTwistEngine::getState ( std::istream& is )
336 for (
int i=0; i<624; ++i) is >> mt[i];
341 if (strcmp(endMarker,
"MTwistEngine-end")) {
342 is.clear(std::ios::badbit | is.rdstate());
343 std::cerr <<
"\nMTwistEngine state description incomplete."
344 <<
"\nInput stream is probably mispositioned now." << std::endl;
350 bool MTwistEngine::get (
const std::vector<unsigned long> & v) {
351 if ((v[0] & 0xffffffffUL) != engineIDulong<MTwistEngine>()) {
353 "\nMTwistEngine get:state vector has wrong ID word - state unchanged\n";
359 bool MTwistEngine::getState (
const std::vector<unsigned long> & v) {
360 if (v.size() != VECTOR_STATE_SIZE ) {
362 "\nMTwistEngine get:state vector has wrong length - state unchanged\n";
365 for (
int i=0; i<624; ++i) {
static const int MarkerLen
void setSeeds(const SeedVector &sv)
Set the seeds of the current generator.