39 #include "CLHEP/Random/Random.h"
40 #include "CLHEP/Random/JamesRandom.h"
41 #include "CLHEP/Random/engineIDulong.h"
42 #include "CLHEP/Random/DoubConv.h"
54 int HepJamesRandom::numEngines = 0;
57 int HepJamesRandom::maxIndex = 215;
59 HepJamesRandom::HepJamesRandom(
long seed)
66 HepJamesRandom::HepJamesRandom()
72 int cycle = std::abs(
int(numEngines/maxIndex));
73 int curIndex = std::abs(
int(numEngines%maxIndex));
75 long mask = ((cycle & 0x007fffff) << 8);
76 HepRandom::getTheTableSeeds( seeds, curIndex );
82 HepJamesRandom::HepJamesRandom(
int rowIndex,
int colIndex)
88 int cycle = std::abs(
int(rowIndex/maxIndex));
89 int row = std::abs(
int(rowIndex%maxIndex));
90 int col = std::abs(
int(colIndex%2));
91 long mask = ((cycle & 0x000007ff) << 20);
92 HepRandom::getTheTableSeeds( seeds, row );
93 seed = (seeds[col])^mask;
98 HepJamesRandom::HepJamesRandom(std::istream& is)
104 HepJamesRandom::~HepJamesRandom() {}
106 void HepJamesRandom::saveStatus(
const char filename[] )
const
108 std::ofstream
outFile( filename, std::ios::out ) ;
112 std::vector<unsigned long> v = put();
113 for (
unsigned int i=0; i<v.size(); ++i) {
119 void HepJamesRandom::restoreStatus(
const char filename[] )
122 std::ifstream inFile( filename, std::ios::in);
123 if (!checkFile ( inFile, filename, engineName(),
"restoreStatus" )) {
124 std::cerr <<
" -- Engine state remains unchanged\n";
127 if ( possibleKeywordInput ( inFile,
"Uvec", theSeed ) ) {
128 std::vector<unsigned long> v;
130 for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
133 inFile.clear(std::ios::badbit | inFile.rdstate());
134 std::cerr <<
"\nJamesRandom state (vector) description improper."
135 <<
"\nrestoreStatus has failed."
136 <<
"\nInput stream is probably mispositioned now." << std::endl;
145 if (!inFile.bad() && !inFile.eof()) {
147 for (
int i=0; i<97; ++i)
149 inFile >> c; inFile >>
cd; inFile >>
cm;
157 void HepJamesRandom::showStatus()
const
159 std::cout << std::endl;
160 std::cout <<
"----- HepJamesRandom engine status -----" << std::endl;
161 std::cout <<
" Initial seed = " << theSeed << std::endl;
162 std::cout <<
" u[] = ";
163 for (
int i=0; i<97; ++i)
164 std::cout << u[i] <<
" ";
165 std::cout << std::endl;
166 std::cout <<
" c = " << c <<
", cd = " <<
cd <<
", cm = " <<
cm
168 std::cout <<
" i97 = " << i97 <<
", u[i97] = " << u[i97] << std::endl;
169 std::cout <<
" j97 = " << j97 <<
", u[j97] = " << u[j97] << std::endl;
170 std::cout <<
"----------------------------------------" << std::endl;
173 void HepJamesRandom::setSeed(
long seed,
int)
186 std::cout <<
"Seed for HepJamesRandom must be non-negative\n"
187 <<
"Seed value supplied was " << seed
188 <<
"\nUsing its absolute value instead\n";
192 long ij = seed/30082;
193 long kl = seed - 30082*ij;
194 long i = (ij/177) % 177 + 2;
195 long j = ij % 177 + 2;
196 long k = (kl/169) % 178 + 1;
201 for ( n = 1 ; n < 98 ; n++ ) {
204 for ( m = 1 ; m < 25 ; m++) {
205 mm = ( ( (i*j) % 179 ) * k ) % 179;
209 l = ( 53 * l + 1 ) % 169;
210 if ( (l*mm % 64 ) >= 32 )
216 c = 362436.0 / 16777216.0;
217 cd = 7654321.0 / 16777216.0;
218 cm = 16777213.0 / 16777216.0;
227 setSeed(seeds ? *seeds : 19780503
L, 0);
236 uni = u[i97] - u[j97];
237 if ( uni < 0.0 ) uni++;
240 if (i97 == 0) i97 = 96;
243 if (j97 == 0) j97 = 96;
247 if (c < 0.0) c +=
cm;
250 if (uni < 0.0) uni += 1.0;
251 }
while ( uni <= 0.0 || uni >= 1.0 );
256 void HepJamesRandom::flatArray(
const int size,
double* vect)
261 for (i=0; i<size; ++i) {
266 HepJamesRandom::operator
unsigned int() {
267 return ((
unsigned int)(
flat() * exponent_bit_32()) & 0xffffffff ) |
268 (((
unsigned int)( u[i97] * exponent_bit_32())>>16) & 0xff);
271 std::ostream & HepJamesRandom::put ( std::ostream& os )
const {
272 char beginMarker[] =
"JamesRandom-begin";
273 os << beginMarker <<
"\nUvec\n";
274 std::vector<unsigned long> v = put();
275 for (
unsigned int i=0; i<v.size(); ++i) {
281 std::vector<unsigned long> HepJamesRandom::put ()
const {
282 std::vector<unsigned long> v;
283 v.push_back (engineIDulong<HepJamesRandom>());
284 std::vector<unsigned long> t;
285 for (
int i=0; i<97; ++i) {
286 t = DoubConv::dto2longs(u[i]);
287 v.push_back(t[0]); v.push_back(t[1]);
289 t = DoubConv::dto2longs(c);
290 v.push_back(t[0]); v.push_back(t[1]);
291 t = DoubConv::dto2longs(
cd);
292 v.push_back(t[0]); v.push_back(t[1]);
293 t = DoubConv::dto2longs(
cm);
294 v.push_back(t[0]); v.push_back(t[1]);
295 v.push_back(static_cast<unsigned long>(j97));
300 std::istream & HepJamesRandom::get ( std::istream& is) {
307 if (strcmp(beginMarker,
"JamesRandom-begin")) {
308 is.clear(std::ios::badbit | is.rdstate());
309 std::cerr <<
"\nInput stream mispositioned or"
310 <<
"\nJamesRandom state description missing or"
311 <<
"\nwrong engine type found." << std::endl;
317 std::string HepJamesRandom::beginTag ( ) {
318 return "JamesRandom-begin";
321 std::istream & HepJamesRandom::getState ( std::istream& is) {
322 if ( possibleKeywordInput ( is,
"Uvec", theSeed ) ) {
323 std::vector<unsigned long> v;
325 for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
328 is.clear(std::ios::badbit | is.rdstate());
329 std::cerr <<
"\nJamesRandom state (vector) description improper."
330 <<
"\ngetState() has failed."
331 <<
"\nInput stream is probably mispositioned now." << std::endl;
344 for (
int i=0; i<97; ++i) {
347 is >> c; is >>
cd; is >>
cm;
352 if(strcmp(endMarker,
"JamesRandom-end")) {
353 is.clear(std::ios::badbit | is.rdstate());
354 std::cerr <<
"\nJamesRandom state description incomplete."
355 <<
"\nInput stream is probably mispositioned now." << std::endl;
365 bool HepJamesRandom::get (
const std::vector<unsigned long> & v) {
366 if ( (v[0] & 0xffffffffUL) != engineIDulong<HepJamesRandom>()) {
368 "\nHepJamesRandom get:state vector has wrong ID word - state unchanged\n";
374 bool HepJamesRandom::getState (
const std::vector<unsigned long> & v) {
375 if (v.size() != VECTOR_STATE_SIZE ) {
377 "\nHepJamesRandom get:state vector has wrong length - state unchanged\n";
380 std::vector<unsigned long> t(2);
381 for (
int i=0; i<97; ++i) {
382 t[0] = v[2*i+1]; t[1] = v[2*i+2];
383 u[i] = DoubConv::longs2double(t);
385 t[0] = v[195]; t[1] = v[196]; c = DoubConv::longs2double(t);
386 t[0] = v[197]; t[1] = v[198]; cd = DoubConv::longs2double(t);
387 t[0] = v[199]; t[1] = v[200]; cm = DoubConv::longs2double(t);
static const int MarkerLen
void setSeeds(const SeedVector &sv)
Set the seeds of the current generator.