40 #include "CLHEP/Random/Random.h"
41 #include "CLHEP/Random/RanecuEngine.h"
42 #include "CLHEP/Random/engineIDulong.h"
43 #include "CLHEP/Utility/atomic_int.h"
53 CLHEP_ATOMIC_INT_TYPE numberOfEngines(0);
58 static const double prec = 4.6566128E-10;
62 void RanecuEngine::further_randomize (
int seq1,
int col,
int index,
int modulus)
64 table[seq1][col] -= (index&0x3FFFFFFF);
65 while (table[seq1][col] <= 0) table[seq1][col] += (modulus-1);
68 RanecuEngine::RanecuEngine()
71 int numEngines = numberOfEngines++;
72 int cycle = std::abs(
int(numEngines/maxSeq));
73 seq = std::abs(
int(numEngines%maxSeq));
76 long mask = ((cycle & 0x007fffff) << 8);
77 for (
int i=0; i<2; ++i) {
78 for (
int j=0; j<maxSeq; ++j) {
79 HepRandom::getTheTableSeeds(table[j],j);
83 theSeeds = &table[seq][0];
86 RanecuEngine::RanecuEngine(
int index)
89 int cycle = std::abs(
int(index/maxSeq));
90 seq = std::abs(
int(index%maxSeq));
92 long mask = ((cycle & 0x000007ff) << 20);
93 for (
int j=0; j<maxSeq; ++j) {
94 HepRandom::getTheTableSeeds(table[j],j);
98 theSeeds = &table[seq][0];
99 further_randomize (seq, 0, index, shift1);
102 RanecuEngine::RanecuEngine(std::istream& is)
108 RanecuEngine::~RanecuEngine() {}
110 void RanecuEngine::setSeed(
long index,
int dum)
112 seq = std::abs(
int(index%maxSeq));
114 HepRandom::getTheTableSeeds(table[seq],seq);
115 theSeeds = &table[seq][0];
116 further_randomize (seq, 0, index, shift1);
117 further_randomize (seq, 1, dum, shift2);
123 seq = std::abs(
int(pos%maxSeq));
127 table[seq][0] = std::abs(seeds[0])%shift1;
128 table[seq][1] = std::abs(seeds[1])%shift2;
129 theSeeds = &table[seq][0];
132 void RanecuEngine::setIndex(
long index)
134 seq = std::abs(
int(index%maxSeq));
136 theSeeds = &table[seq][0];
139 void RanecuEngine::saveStatus(
const char filename[] )
const
141 std::ofstream outFile( filename, std::ios::out ) ;
143 if (!outFile.bad()) {
145 std::vector<unsigned long> v = put();
146 for (
unsigned int i=0; i<v.size(); ++i) {
147 outFile << v[i] <<
"\n";
152 void RanecuEngine::restoreStatus(
const char filename[] )
154 std::ifstream inFile( filename, std::ios::in);
155 if (!checkFile ( inFile, filename, engineName(),
"restoreStatus" )) {
156 std::cerr <<
" -- Engine state remains unchanged\n";
159 if ( possibleKeywordInput ( inFile,
"Uvec", theSeed ) ) {
160 std::vector<unsigned long> v;
162 for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
165 inFile.clear(std::ios::badbit | inFile.rdstate());
166 std::cerr <<
"\nJamesRandom state (vector) description improper."
167 <<
"\nrestoreStatus has failed."
168 <<
"\nInput stream is probably mispositioned now." << std::endl;
177 if (!inFile.bad() && !inFile.eof()) {
179 for (
int i=0; i<2; ++i)
180 inFile >> table[theSeed][i];
185 void RanecuEngine::showStatus()
const
187 std::cout << std::endl;
188 std::cout <<
"--------- Ranecu engine status ---------" << std::endl;
189 std::cout <<
" Initial seed (index) = " << theSeed << std::endl;
190 std::cout <<
" Current couple of seeds = "
191 << table[theSeed][0] <<
", "
192 << table[theSeed][1] << std::endl;
193 std::cout <<
"----------------------------------------" << std::endl;
198 const int index = seq;
199 long seed1 = table[index][0];
200 long seed2 = table[index][1];
202 int k1 = (int)(seed1/ecuyer_b);
203 int k2 = (int)(seed2/ecuyer_e);
205 seed1 = ecuyer_a*(seed1-k1*ecuyer_b)-k1*ecuyer_c;
206 if (seed1 < 0) seed1 += shift1;
207 seed2 = ecuyer_d*(seed2-k2*ecuyer_e)-k2*ecuyer_f;
208 if (seed2 < 0) seed2 += shift2;
210 table[index][0] = seed1;
211 table[index][1] = seed2;
213 long diff = seed1-seed2;
215 if (diff <= 0) diff += (shift1-1);
216 return (
double)(diff*
prec);
219 void RanecuEngine::flatArray(
const int size,
double* vect)
221 const int index = seq;
222 long seed1 = table[index][0];
223 long seed2 = table[index][1];
227 for (i=0; i<size; ++i)
229 k1 = (int)(seed1/ecuyer_b);
230 k2 = (int)(seed2/ecuyer_e);
232 seed1 = ecuyer_a*(seed1-k1*ecuyer_b)-k1*ecuyer_c;
233 if (seed1 < 0) seed1 += shift1;
234 seed2 = ecuyer_d*(seed2-k2*ecuyer_e)-k2*ecuyer_f;
235 if (seed2 < 0) seed2 += shift2;
237 long diff = seed1-seed2;
238 if (diff <= 0) diff += (shift1-1);
240 vect[i] = (double)(diff*prec);
242 table[index][0] = seed1;
243 table[index][1] = seed2;
246 RanecuEngine::operator
unsigned int() {
247 const int index = seq;
248 long seed1 = table[index][0];
249 long seed2 = table[index][1];
251 int k1 = (int)(seed1/ecuyer_b);
252 int k2 = (int)(seed2/ecuyer_e);
254 seed1 = ecuyer_a*(seed1-k1*ecuyer_b)-k1*ecuyer_c;
255 if (seed1 < 0) seed1 += shift1;
256 seed2 = ecuyer_d*(seed2-k2*ecuyer_e)-k2*ecuyer_f;
257 if (seed2 < 0) seed2 += shift2;
259 table[index][0] = seed1;
260 table[index][1] = seed2;
261 long diff = seed1-seed2;
262 if( diff <= 0 ) diff += (shift1-1);
264 return ((diff << 1) | (seed1&1))& 0xffffffff;
267 std::ostream & RanecuEngine::put( std::ostream& os )
const
269 char beginMarker[] =
"RanecuEngine-begin";
270 os << beginMarker <<
"\nUvec\n";
271 std::vector<unsigned long> v = put();
272 for (
unsigned int i=0; i<v.size(); ++i) {
278 std::vector<unsigned long> RanecuEngine::put ()
const {
279 std::vector<unsigned long> v;
280 v.push_back (engineIDulong<RanecuEngine>());
281 v.push_back(static_cast<unsigned long>(theSeed));
282 v.push_back(static_cast<unsigned long>(table[theSeed][0]));
283 v.push_back(static_cast<unsigned long>(table[theSeed][1]));
287 std::istream & RanecuEngine::get ( std::istream& is )
296 if (strcmp(beginMarker,
"RanecuEngine-begin")) {
297 is.clear(std::ios::badbit | is.rdstate());
298 std::cerr <<
"\nInput stream mispositioned or"
299 <<
"\nRanecuEngine state description missing or"
300 <<
"\nwrong engine type found." << std::endl;
306 std::string RanecuEngine::beginTag ( ) {
307 return "RanecuEngine-begin";
310 std::istream & RanecuEngine::getState ( std::istream& is )
312 if ( possibleKeywordInput ( is,
"Uvec", theSeed ) ) {
313 std::vector<unsigned long> v;
315 for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
318 is.clear(std::ios::badbit | is.rdstate());
319 std::cerr <<
"\nRanecuEngine state (vector) description improper."
320 <<
"\ngetState() has failed."
321 <<
"\nInput stream is probably mispositioned now." << std::endl;
332 for (
int i=0; i<2; ++i) {
333 is >> table[theSeed][i];
338 if (strcmp(endMarker,
"RanecuEngine-end")) {
339 is.clear(std::ios::badbit | is.rdstate());
340 std::cerr <<
"\nRanecuEngine state description incomplete."
341 <<
"\nInput stream is probably mispositioned now." << std::endl;
349 bool RanecuEngine::get (
const std::vector<unsigned long> & v) {
350 if ((v[0] & 0xffffffffUL) != engineIDulong<RanecuEngine>()) {
352 "\nRanecuEngine get:state vector has wrong ID word - state unchanged\n";
358 bool RanecuEngine::getState (
const std::vector<unsigned long> & v) {
359 if (v.size() != VECTOR_STATE_SIZE ) {
361 "\nRanecuEngine get:state vector has wrong length - state unchanged\n";
365 table[theSeed][0] = v[2];
366 table[theSeed][1] = v[3];
static const int MarkerLen
const char * name(G4int ptype)
static const G4double pos
void setSeeds(const SeedVector &sv)
Set the seeds of the current generator.