40 #include "CLHEP/Random/Random.h"
41 #include "CLHEP/Random/RanecuEngine.h"
42 #include "CLHEP/Random/engineIDulong.h"
51 static const double prec = 4.6566128E-10;
55 void RanecuEngine::further_randomize (
int seq1,
int col,
int index,
int modulus)
57 table[seq1][col] -= (index&0x3FFFFFFF);
58 while (table[seq1][col] <= 0) table[seq1][col] += (modulus-1);
62 int RanecuEngine::numEngines = 0;
64 RanecuEngine::RanecuEngine()
67 int cycle = std::abs(
int(numEngines/maxSeq));
68 seq = std::abs(
int(numEngines%maxSeq));
71 long mask = ((cycle & 0x007fffff) << 8);
72 for (
int i=0; i<2; ++i) {
73 for (
int j=0; j<maxSeq; ++j) {
74 HepRandom::getTheTableSeeds(table[j],j);
78 theSeeds = &table[seq][0];
81 RanecuEngine::RanecuEngine(
int index)
84 int cycle = std::abs(
int(index/maxSeq));
85 seq = std::abs(
int(index%maxSeq));
87 long mask = ((cycle & 0x000007ff) << 20);
88 for (
int j=0; j<maxSeq; ++j) {
89 HepRandom::getTheTableSeeds(table[j],j);
93 theSeeds = &table[seq][0];
94 further_randomize (seq, 0, index, shift1);
97 RanecuEngine::RanecuEngine(std::istream& is)
103 RanecuEngine::~RanecuEngine() {}
105 void RanecuEngine::setSeed(
long index,
int dum)
107 seq = std::abs(
int(index%maxSeq));
109 HepRandom::getTheTableSeeds(table[seq],seq);
110 theSeeds = &table[seq][0];
111 further_randomize (seq, 0, index, shift1);
112 further_randomize (seq, 1, dum, shift2);
118 seq = std::abs(
int(pos%maxSeq));
122 table[seq][0] = std::abs(seeds[0])%shift1;
123 table[seq][1] = std::abs(seeds[1])%shift2;
124 theSeeds = &table[seq][0];
127 void RanecuEngine::setIndex(
long index)
129 seq = std::abs(
int(index%maxSeq));
131 theSeeds = &table[seq][0];
134 void RanecuEngine::saveStatus(
const char filename[] )
const
136 std::ofstream
outFile( filename, std::ios::out ) ;
140 std::vector<unsigned long> v = put();
141 for (
unsigned int i=0; i<v.size(); ++i) {
147 void RanecuEngine::restoreStatus(
const char filename[] )
149 std::ifstream inFile( filename, std::ios::in);
150 if (!checkFile ( inFile, filename, engineName(),
"restoreStatus" )) {
151 std::cerr <<
" -- Engine state remains unchanged\n";
154 if ( possibleKeywordInput ( inFile,
"Uvec", theSeed ) ) {
155 std::vector<unsigned long> v;
157 for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
160 inFile.clear(std::ios::badbit | inFile.rdstate());
161 std::cerr <<
"\nJamesRandom state (vector) description improper."
162 <<
"\nrestoreStatus has failed."
163 <<
"\nInput stream is probably mispositioned now." << std::endl;
172 if (!inFile.bad() && !inFile.eof()) {
174 for (
int i=0; i<2; ++i)
175 inFile >> table[theSeed][i];
180 void RanecuEngine::showStatus()
const
182 std::cout << std::endl;
183 std::cout <<
"--------- Ranecu engine status ---------" << std::endl;
184 std::cout <<
" Initial seed (index) = " << theSeed << std::endl;
185 std::cout <<
" Current couple of seeds = "
186 << table[theSeed][0] <<
", "
187 << table[theSeed][1] << std::endl;
188 std::cout <<
"----------------------------------------" << std::endl;
193 const int index = seq;
194 long seed1 = table[index][0];
195 long seed2 = table[index][1];
197 int k1 = (int)(seed1/ecuyer_b);
198 int k2 = (int)(seed2/ecuyer_e);
200 seed1 = ecuyer_a*(seed1-k1*ecuyer_b)-k1*ecuyer_c;
201 if (seed1 < 0) seed1 += shift1;
202 seed2 = ecuyer_d*(seed2-k2*ecuyer_e)-k2*ecuyer_f;
203 if (seed2 < 0) seed2 += shift2;
205 table[index][0] = seed1;
206 table[index][1] = seed2;
208 long diff = seed1-seed2;
210 if (diff <= 0) diff += (shift1-1);
211 return (
double)(diff*
prec);
214 void RanecuEngine::flatArray(
const int size,
double* vect)
216 const int index = seq;
217 long seed1 = table[index][0];
218 long seed2 = table[index][1];
222 for (i=0; i<size; ++i)
224 k1 = (int)(seed1/ecuyer_b);
225 k2 = (int)(seed2/ecuyer_e);
227 seed1 = ecuyer_a*(seed1-k1*ecuyer_b)-k1*ecuyer_c;
228 if (seed1 < 0) seed1 += shift1;
229 seed2 = ecuyer_d*(seed2-k2*ecuyer_e)-k2*ecuyer_f;
230 if (seed2 < 0) seed2 += shift2;
232 long diff = seed1-seed2;
233 if (diff <= 0) diff += (shift1-1);
235 vect[i] = (double)(diff*prec);
237 table[index][0] = seed1;
238 table[index][1] = seed2;
241 RanecuEngine::operator
unsigned int() {
242 const int index = seq;
243 long seed1 = table[index][0];
244 long seed2 = table[index][1];
246 int k1 = (int)(seed1/ecuyer_b);
247 int k2 = (int)(seed2/ecuyer_e);
249 seed1 = ecuyer_a*(seed1-k1*ecuyer_b)-k1*ecuyer_c;
250 if (seed1 < 0) seed1 += shift1;
251 seed2 = ecuyer_d*(seed2-k2*ecuyer_e)-k2*ecuyer_f;
252 if (seed2 < 0) seed2 += shift2;
254 table[index][0] = seed1;
255 table[index][1] = seed2;
256 long diff = seed1-seed2;
257 if( diff <= 0 ) diff += (shift1-1);
259 return ((diff << 1) | (seed1&1))& 0xffffffff;
262 std::ostream & RanecuEngine::put( std::ostream& os )
const
264 char beginMarker[] =
"RanecuEngine-begin";
265 os << beginMarker <<
"\nUvec\n";
266 std::vector<unsigned long> v = put();
267 for (
unsigned int i=0; i<v.size(); ++i) {
273 std::vector<unsigned long> RanecuEngine::put ()
const {
274 std::vector<unsigned long> v;
275 v.push_back (engineIDulong<RanecuEngine>());
276 v.push_back(static_cast<unsigned long>(theSeed));
277 v.push_back(static_cast<unsigned long>(table[theSeed][0]));
278 v.push_back(static_cast<unsigned long>(table[theSeed][1]));
282 std::istream & RanecuEngine::get ( std::istream& is )
291 if (strcmp(beginMarker,
"RanecuEngine-begin")) {
292 is.clear(std::ios::badbit | is.rdstate());
293 std::cerr <<
"\nInput stream mispositioned or"
294 <<
"\nRanecuEngine state description missing or"
295 <<
"\nwrong engine type found." << std::endl;
301 std::string RanecuEngine::beginTag ( ) {
302 return "RanecuEngine-begin";
305 std::istream & RanecuEngine::getState ( std::istream& is )
307 if ( possibleKeywordInput ( is,
"Uvec", theSeed ) ) {
308 std::vector<unsigned long> v;
310 for (
unsigned int ivec=0; ivec < VECTOR_STATE_SIZE; ++ivec) {
313 is.clear(std::ios::badbit | is.rdstate());
314 std::cerr <<
"\nRanecuEngine state (vector) description improper."
315 <<
"\ngetState() has failed."
316 <<
"\nInput stream is probably mispositioned now." << std::endl;
327 for (
int i=0; i<2; ++i) {
328 is >> table[theSeed][i];
333 if (strcmp(endMarker,
"RanecuEngine-end")) {
334 is.clear(std::ios::badbit | is.rdstate());
335 std::cerr <<
"\nRanecuEngine state description incomplete."
336 <<
"\nInput stream is probably mispositioned now." << std::endl;
344 bool RanecuEngine::get (
const std::vector<unsigned long> & v) {
345 if ((v[0] & 0xffffffffUL) != engineIDulong<RanecuEngine>()) {
347 "\nRanecuEngine get:state vector has wrong ID word - state unchanged\n";
353 bool RanecuEngine::getState (
const std::vector<unsigned long> & v) {
354 if (v.size() != VECTOR_STATE_SIZE ) {
356 "\nRanecuEngine get:state vector has wrong length - state unchanged\n";
360 table[theSeed][0] = v[2];
361 table[theSeed][1] = v[3];
static const int MarkerLen
static const G4double pos
void setSeeds(const SeedVector &sv)
Set the seeds of the current generator.