54 #include "RanluxEngine.h"
56 RanluxEngine::RanluxEngine(
long seed, HepInt lux)
57 : int_modulus(0x1000000),
58 mantissa_bit_24((HepFloat) ::pow(0.5,24.)),
59 mantissa_bit_12((HepFloat) ::pow(0.5,12.))
62 setSeed(seed, luxury);
63 setSeeds(&theSeed, luxury);
66 RanluxEngine::~RanluxEngine() {}
69 : int_modulus(0x1000000),
70 mantissa_bit_24((HepFloat) ::pow(0.5,24.)),
71 mantissa_bit_12((HepFloat) ::pow(0.5,12.))
73 if ((
this != &p) && (&p)) {
74 theSeed = p.getSeed();
75 setSeeds(&theSeed, p.luxury);
76 for (HepInt i=0; i<24; ++i)
77 float_seed_table[i] = p.float_seed_table[i];
80 i_lag = p.i_lag; j_lag = p.j_lag;
88 if ((
this != &p) && (&p)) {
89 theSeed = p.getSeed();
90 setSeeds(&theSeed, p.luxury);
91 for (HepInt i=0; i<24; ++i)
92 float_seed_table[i] = p.float_seed_table[i];
95 i_lag = p.i_lag; j_lag = p.j_lag;
102 void RanluxEngine::setSeed(
long seed, HepInt lux) {
110 const HepInt ecuyer_a = 53668;
111 const HepInt ecuyer_b = 40014;
112 const HepInt ecuyer_c = 12211;
113 const HepInt ecuyer_d = 2147483563;
115 const HepInt lux_levels[5] = {0,24,73,199,365};
117 long int_seed_table[24];
118 long next_seed = seed;
126 if( (lux > 4)||(lux < 0) ){
130 nskip = lux_levels[3];
134 nskip = lux_levels[luxury];
138 for(i = 0;i != 24;i++){
139 k_multiple = next_seed / ecuyer_a;
140 next_seed = ecuyer_b * (next_seed - k_multiple * ecuyer_a)
141 - k_multiple * ecuyer_c ;
142 if(next_seed < 0)next_seed += ecuyer_d;
143 int_seed_table[i] = next_seed % int_modulus;
146 for(i = 0;i != 24;i++)
147 float_seed_table[i] = int_seed_table[i] * mantissa_bit_24;
153 if( float_seed_table[23] == 0. ) carry = mantissa_bit_24;
158 void RanluxEngine::setSeeds(
const long *seeds, HepInt lux) {
160 const HepInt ecuyer_a = 53668;
161 const HepInt ecuyer_b = 40014;
162 const HepInt ecuyer_c = 12211;
163 const HepInt ecuyer_d = 2147483563;
165 const HepInt lux_levels[5] = {0,24,73,199,365};
167 long int_seed_table[24];
168 long k_multiple,next_seed;
175 setSeed(theSeed,lux);
185 if( (lux > 4)||(lux < 0) ){
189 nskip = lux_levels[3];
193 nskip = lux_levels[luxury];
196 for( i = 0;(i != 24)&&(*seedptr != 0);i++){
197 int_seed_table[i] = *seedptr % int_modulus;
202 next_seed = int_seed_table[i-1];
204 k_multiple = next_seed / ecuyer_a;
205 next_seed = ecuyer_b * (next_seed - k_multiple * ecuyer_a)
206 - k_multiple * ecuyer_c ;
207 if(next_seed < 0)next_seed += ecuyer_d;
208 int_seed_table[i] = next_seed % int_modulus;
212 for(i = 0;i != 24;i++)
213 float_seed_table[i] = int_seed_table[i] * mantissa_bit_24;
219 if( float_seed_table[23] == 0. ) carry = mantissa_bit_24;
224 void RanluxEngine::saveStatus()
const
226 ofstream outFile(
"Ranlux.conf", std::ios::out ) ;
228 if (!outFile.bad()) {
229 outFile << theSeed << endl;
230 for (HepInt i=0; i<24; ++i)
231 outFile << float_seed_table[i] <<
" ";
233 outFile << i_lag <<
" " << j_lag << endl;
234 outFile << carry <<
" " << count24 << endl;
238 void RanluxEngine::restoreStatus()
240 ifstream inFile(
"Ranlux.conf", std::ios::in);
242 if (!inFile.bad() && !inFile.eof()) {
244 for (HepInt i=0; i<24; ++i)
245 inFile >> float_seed_table[i];
246 inFile >> i_lag; inFile >> j_lag;
247 inFile >> carry; inFile >> count24;
251 void RanluxEngine::showStatus()
const
254 cout <<
"--------- Ranlux engine status ---------" << endl;
255 cout <<
" Initial seed = " << theSeed << endl;
256 cout <<
" float_seed_table[] = ";
257 for (HepInt i=0; i<24; ++i)
258 cout << float_seed_table[i] <<
" ";
260 cout <<
" i_lag = " << i_lag <<
", j_lag = " << j_lag << endl;
261 cout <<
" carry = " << carry <<
", count24 = " << count24 << endl;
262 cout <<
"----------------------------------------" << endl;
265 HepDouble RanluxEngine::flat() {
267 HepFloat next_random;
271 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
274 carry = mantissa_bit_24;
279 float_seed_table[i_lag] = uni;
282 if(i_lag < 0) i_lag = 23;
283 if(j_lag < 0) j_lag = 23;
285 if( uni < mantissa_bit_12 ){
286 uni += mantissa_bit_24 * float_seed_table[j_lag];
287 if( uni == 0) uni = mantissa_bit_24 * mantissa_bit_24;
297 for( i = 0; i != nskip ; i++){
298 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
301 carry = mantissa_bit_24;
305 float_seed_table[i_lag] = uni;
308 if(i_lag < 0)i_lag = 23;
309 if(j_lag < 0) j_lag = 23;
312 return (HepDouble) next_random;
315 void RanluxEngine::flatArray(
const HepInt size, HepDouble* vect)
317 HepFloat next_random;
322 for (index=0; index<size; ++index) {
323 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
326 carry = mantissa_bit_24;
331 float_seed_table[i_lag] = uni;
334 if(i_lag < 0) i_lag = 23;
335 if(j_lag < 0) j_lag = 23;
337 if( uni < mantissa_bit_12 ){
338 uni += mantissa_bit_24 * float_seed_table[j_lag];
339 if( uni == 0) uni = mantissa_bit_24 * mantissa_bit_24;
342 vect[index] = (HepDouble)next_random;
350 for( i = 0; i != nskip ; i++){
351 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
354 carry = mantissa_bit_24;
358 float_seed_table[i_lag] = uni;
361 if(i_lag < 0)i_lag = 23;
362 if(j_lag < 0) j_lag = 23;
369 #ifndef ST_NO_TEMPLATE_DEF_ARGS
370 RanluxEngine::flatArray(vector<HepDouble>& vec)
372 RanluxEngine::flatArray(vector<HepDouble,allocator<HepDouble> >& vec)
375 HepFloat next_random;
379 for (
unsigned int index=0; index<vec.size(); ++index) {
380 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
383 carry = mantissa_bit_24;
388 float_seed_table[i_lag] = uni;
391 if(i_lag < 0) i_lag = 23;
392 if(j_lag < 0) j_lag = 23;
394 if( uni < mantissa_bit_12 ){
395 uni += mantissa_bit_24 * float_seed_table[j_lag];
396 if( uni == 0) uni = mantissa_bit_24 * mantissa_bit_24;
399 vec[index] = (HepDouble)next_random;
407 for( i = 0; i != nskip ; i++){
408 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
411 carry = mantissa_bit_24;
415 float_seed_table[i_lag] = uni;
418 if(i_lag < 0)i_lag = 23;
419 if(j_lag < 0) j_lag = 23;