40 #include "CLHEP/Random/Random.h"
41 #include "CLHEP/Random/RanluxEngine.h"
42 #include "CLHEP/Random/engineIDulong.h"
54 int RanluxEngine::numEngines = 0;
57 int RanluxEngine::maxIndex = 215;
59 RanluxEngine::RanluxEngine(
long seed,
int lux)
62 long seedlist[2]={0,0};
65 setSeed(seed, luxury);
73 RanluxEngine::RanluxEngine()
77 long seedlist[2]={0,0};
80 int cycle = std::abs(
int(numEngines/maxIndex));
81 int curIndex = std::abs(
int(numEngines%maxIndex));
83 long mask = ((cycle & 0x007fffff) << 8);
84 HepRandom::getTheTableSeeds( seedlist, curIndex );
85 seed = seedlist[0]^mask;
86 setSeed(seed, luxury);
94 RanluxEngine::RanluxEngine(
int rowIndex,
int colIndex,
int lux)
98 long seedlist[2]={0,0};
101 int cycle = std::abs(
int(rowIndex/maxIndex));
102 int row = std::abs(
int(rowIndex%maxIndex));
103 int col = std::abs(
int(colIndex%2));
104 long mask = (( cycle & 0x000007ff ) << 20 );
105 HepRandom::getTheTableSeeds( seedlist, row );
106 seed = ( seedlist[col] )^mask;
107 setSeed(seed, luxury);
115 RanluxEngine::RanluxEngine( std::istream& is )
121 RanluxEngine::~RanluxEngine() {}
123 void RanluxEngine::setSeed(
long seed,
int lux) {
131 const int ecuyer_a = 53668;
132 const int ecuyer_b = 40014;
133 const int ecuyer_c = 12211;
134 const int ecuyer_d = 2147483563;
136 const int lux_levels[5] = {0,24,73,199,365};
138 long int_seed_table[24];
139 long next_seed = seed;
147 if( (lux > 4)||(lux < 0) ){
151 nskip = lux_levels[3];
155 nskip = lux_levels[luxury];
159 for(i = 0;i != 24;i++){
160 k_multiple = next_seed / ecuyer_a;
161 next_seed = ecuyer_b * (next_seed - k_multiple * ecuyer_a)
162 - k_multiple * ecuyer_c ;
163 if(next_seed < 0)next_seed += ecuyer_d;
164 int_seed_table[i] = next_seed % int_modulus;
167 for(i = 0;i != 24;i++)
168 float_seed_table[i] = int_seed_table[i] * mantissa_bit_24();
174 if( float_seed_table[23] == 0. ) carry = mantissa_bit_24();
181 const int ecuyer_a = 53668;
182 const int ecuyer_b = 40014;
183 const int ecuyer_c = 12211;
184 const int ecuyer_d = 2147483563;
186 const int lux_levels[5] = {0,24,73,199,365};
188 long int_seed_table[24];
189 long k_multiple,next_seed;
196 setSeed(theSeed,lux);
206 if( (lux > 4)||(lux < 0) ){
210 nskip = lux_levels[3];
214 nskip = lux_levels[luxury];
217 for( i = 0;(i != 24)&&(*seedptr != 0);i++){
218 int_seed_table[i] = *seedptr % int_modulus;
223 next_seed = int_seed_table[i-1];
225 k_multiple = next_seed / ecuyer_a;
226 next_seed = ecuyer_b * (next_seed - k_multiple * ecuyer_a)
227 - k_multiple * ecuyer_c ;
228 if(next_seed < 0)next_seed += ecuyer_d;
229 int_seed_table[i] = next_seed % int_modulus;
233 for(i = 0;i != 24;i++)
234 float_seed_table[i] = int_seed_table[i] * mantissa_bit_24();
240 if( float_seed_table[23] == 0. ) carry = mantissa_bit_24();
245 void RanluxEngine::saveStatus(
const char filename[] )
const
247 std::ofstream
outFile( filename, std::ios::out ) ;
250 std::vector<unsigned long> v = put();
251 for (
unsigned int i=0; i<v.size(); ++i) {
257 void RanluxEngine::restoreStatus(
const char filename[] )
259 std::ifstream inFile( filename, std::ios::in);
260 if (!checkFile ( inFile, filename, engineName(),
"restoreStatus" )) {
261 std::cerr <<
" -- Engine state remains unchanged\n";
264 if ( possibleKeywordInput ( inFile,
"Uvec", theSeed ) ) {
265 std::vector<unsigned long> v;
267 for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
270 inFile.clear(std::ios::badbit | inFile.rdstate());
271 std::cerr <<
"\nRanluxEngine state (vector) description improper."
272 <<
"\nrestoreStatus has failed."
273 <<
"\nInput stream is probably mispositioned now." << std::endl;
282 if (!inFile.bad() && !inFile.eof()) {
284 for (
int i=0; i<24; ++i)
285 inFile >> float_seed_table[i];
286 inFile >> i_lag; inFile >> j_lag;
287 inFile >> carry; inFile >> count24;
288 inFile >> luxury; inFile >> nskip;
292 void RanluxEngine::showStatus()
const
294 std::cout << std::endl;
295 std::cout <<
"--------- Ranlux engine status ---------" << std::endl;
296 std::cout <<
" Initial seed = " << theSeed << std::endl;
297 std::cout <<
" float_seed_table[] = ";
298 for (
int i=0; i<24; ++i)
299 std::cout << float_seed_table[i] <<
" ";
300 std::cout << std::endl;
301 std::cout <<
" i_lag = " << i_lag <<
", j_lag = " << j_lag << std::endl;
302 std::cout <<
" carry = " << carry <<
", count24 = " << count24 << std::endl;
303 std::cout <<
" luxury = " << luxury <<
" nskip = " << nskip << std::endl;
304 std::cout <<
"----------------------------------------" << std::endl;
313 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
316 carry = mantissa_bit_24();
321 float_seed_table[i_lag] = uni;
324 if(i_lag < 0) i_lag = 23;
325 if(j_lag < 0) j_lag = 23;
327 if( uni < mantissa_bit_12() ){
328 uni += mantissa_bit_24() * float_seed_table[j_lag];
329 if( uni == 0) uni = mantissa_bit_24() * mantissa_bit_24();
339 for( i = 0; i != nskip ; i++){
340 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
343 carry = mantissa_bit_24();
347 float_seed_table[i_lag] = uni;
350 if(i_lag < 0)i_lag = 23;
351 if(j_lag < 0) j_lag = 23;
354 return (
double) next_random;
357 void RanluxEngine::flatArray(
const int size,
double* vect)
364 for (index=0; index<size; ++index) {
365 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
368 carry = mantissa_bit_24();
373 float_seed_table[i_lag] = uni;
376 if(i_lag < 0) i_lag = 23;
377 if(j_lag < 0) j_lag = 23;
379 if( uni < mantissa_bit_12() ){
380 uni += mantissa_bit_24() * float_seed_table[j_lag];
381 if( uni == 0) uni = mantissa_bit_24() * mantissa_bit_24();
384 vect[index] = (double)next_random;
392 for( i = 0; i != nskip ; i++){
393 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
396 carry = mantissa_bit_24();
400 float_seed_table[i_lag] = uni;
403 if(i_lag < 0)i_lag = 23;
404 if(j_lag < 0) j_lag = 23;
410 RanluxEngine::operator
unsigned int() {
411 return ((
unsigned int)(
flat() * exponent_bit_32()) & 0xffffffff) |
412 (((
unsigned int)(float_seed_table[i_lag]*exponent_bit_32())>>16) & 0xff);
417 std::ostream & RanluxEngine::put ( std::ostream& os )
const
419 char beginMarker[] =
"RanluxEngine-begin";
420 os << beginMarker <<
"\nUvec\n";
421 std::vector<unsigned long> v = put();
422 for (
unsigned int i=0; i<v.size(); ++i) {
428 std::vector<unsigned long> RanluxEngine::put ()
const {
429 std::vector<unsigned long> v;
430 v.push_back (engineIDulong<RanluxEngine>());
431 for (
int i=0; i<24; ++i) {
433 (static_cast<unsigned long>(float_seed_table[i]/mantissa_bit_24()));
435 v.push_back(static_cast<unsigned long>(i_lag));
436 v.push_back(static_cast<unsigned long>(j_lag));
437 v.push_back(static_cast<unsigned long>(carry/mantissa_bit_24()));
438 v.push_back(static_cast<unsigned long>(count24));
439 v.push_back(static_cast<unsigned long>(luxury));
440 v.push_back(static_cast<unsigned long>(nskip));
444 std::istream & RanluxEngine::get ( std::istream& is )
452 if (strcmp(beginMarker,
"RanluxEngine-begin")) {
453 is.clear(std::ios::badbit | is.rdstate());
454 std::cerr <<
"\nInput stream mispositioned or"
455 <<
"\nRanluxEngine state description missing or"
456 <<
"\nwrong engine type found." << std::endl;
462 std::string RanluxEngine::beginTag ( ) {
463 return "RanluxEngine-begin";
466 std::istream & RanluxEngine::getState ( std::istream& is )
468 if ( possibleKeywordInput ( is,
"Uvec", theSeed ) ) {
469 std::vector<unsigned long> v;
471 for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
474 is.clear(std::ios::badbit | is.rdstate());
475 std::cerr <<
"\nRanluxEngine state (vector) description improper."
476 <<
"\ngetState() has failed."
477 <<
"\nInput stream is probably mispositioned now." << std::endl;
489 for (
int i=0; i<24; ++i) {
490 is >> float_seed_table[i];
492 is >> i_lag; is >> j_lag;
493 is >> carry; is >> count24;
494 is >> luxury; is >> nskip;
498 if (strcmp(endMarker,
"RanluxEngine-end")) {
499 is.clear(std::ios::badbit | is.rdstate());
500 std::cerr <<
"\nRanluxEngine state description incomplete."
501 <<
"\nInput stream is probably mispositioned now." << std::endl;
507 bool RanluxEngine::get (
const std::vector<unsigned long> & v) {
508 if ((v[0] & 0xffffffffUL) != engineIDulong<RanluxEngine>()) {
510 "\nRanluxEngine get:state vector has wrong ID word - state unchanged\n";
516 bool RanluxEngine::getState (
const std::vector<unsigned long> & v) {
517 if (v.size() != VECTOR_STATE_SIZE ) {
519 "\nRanluxEngine get:state vector has wrong length - state unchanged\n";
522 for (
int i=0; i<24; ++i) {
523 float_seed_table[i] = v[i+1]*mantissa_bit_24();
527 carry = v[27]*mantissa_bit_24();
static const int MarkerLen
void setSeeds(const SeedVector &sv)
Set the seeds of the current generator.