TRandom1.cxx

Go to the documentation of this file.
00001 // @(#)root/mathcore:$Id: TRandom1.cxx 22866 2008-03-27 15:32:50Z rdm $
00002 // Author: Rene Brun from CLHEP & CERNLIB  04/05/2006
00003 
00004 //////////////////////////////////////////////////////////////////////////
00005 //
00006 // TRandom1
00007 //
00008 // The Ranlux Random number generator class
00009 //
00010 // The algorithm for this random engine has been taken from the original
00011 // implementation in FORTRAN by Fred James as part of CLHEP.
00012 //
00013 // The initialisation is carried out using a Multiplicative Congruential
00014 // generator using formula constants of L'Ecuyer as described in "F.James,
00015 // Comp. Phys. Comm. 60 (1990) 329-344".
00016 //
00017 //////////////////////////////////////////////////////////////////////////
00018 
00019 #include "TRandom1.h"
00020 #include "TRandom3.h"
00021 #include "TMath.h"
00022 #include <stdlib.h>
00023 
00024 // Number of instances with automatic seed selection
00025 int TRandom1::fgNumEngines = 0;
00026 
00027 // Maximum index into the seed table
00028 int TRandom1::fgMaxIndex = 215;
00029 #ifndef __CINT__
00030 const UInt_t fgSeedTable[215][2] = {
00031                              {           9876, 54321            },
00032                              {     1299961164, 253987020        },
00033                              {      669708517, 2079157264       },
00034                              {      190904760, 417696270        },
00035                              {     1289741558, 1376336092       },
00036                              {     1803730167, 324952955        },
00037                              {      489854550, 582847132        },
00038                              {     1348037628, 1661577989       },
00039                              {      350557787, 1155446919       },
00040                              {      591502945, 634133404        },
00041                              {     1901084678, 862916278        },
00042                              {     1988640932, 1785523494       },
00043                              {     1873836227, 508007031        },
00044                              {     1146416592, 967585720        },
00045                              {     1837193353, 1522927634       },
00046                              {       38219936, 921609208        },
00047                              {      349152748, 112892610        },
00048                              {      744459040, 1735807920       },
00049                              {     1983990104, 728277902        },
00050                              {      309164507, 2126677523       },
00051                              {      362993787, 1897782044       },
00052                              {      556776976, 462072869        },
00053                              {     1584900822, 2019394912       },
00054                              {     1249892722, 791083656        },
00055                              {     1686600998, 1983731097       },
00056                              {     1127381380, 198976625        },
00057                              {     1999420861, 1810452455       },
00058                              {     1972906041, 664182577        },
00059                              {       84636481, 1291886301       },
00060                              {     1186362995, 954388413        },
00061                              {     2141621785, 61738584         },
00062                              {     1969581251, 1557880415       },
00063                              {     1150606439, 136325185        },
00064                              {       95187861, 1592224108       },
00065                              {      940517655, 1629971798       },
00066                              {      215350428, 922659102        },
00067                              {      786161212, 1121345074       },
00068                              {     1450830056, 1922787776       },
00069                              {     1696578057, 2025150487       },
00070                              {     1803414346, 1851324780       },
00071                              {     1017898585, 1452594263       },
00072                              {     1184497978, 82122239         },
00073                              {      633338765, 1829684974       },
00074                              {      430889421, 230039326        },
00075                              {      492544653, 76320266         },
00076                              {      389386975, 1314148944       },
00077                              {     1720322786, 709120323        },
00078                              {     1868768216, 1992898523       },
00079                              {      443210610, 811117710        },
00080                              {     1191938868, 1548484733       },
00081                              {      616890172, 159787986        },
00082                              {      935835339, 1231440405       },
00083                              {     1058009367, 1527613300       },
00084                              {     1463148129, 1970575097       },
00085                              {     1795336935, 434768675        },
00086                              {      274019517, 605098487        },
00087                              {      483689317, 217146977        },
00088                              {     2070804364, 340596558        },
00089                              {      930226308, 1602100969       },
00090                              {      989324440, 801809442        },
00091                              {      410606853, 1893139948       },
00092                              {     1583588576, 1219225407       },
00093                              {     2102034391, 1394921405       },
00094                              {     2005037790, 2031006861       },
00095                              {     1244218766, 923231061        },
00096                              {       49312790, 775496649        },
00097                              {      721012176, 321339902        },
00098                              {     1719909107, 1865748178       },
00099                              {     1156177430, 1257110891       },
00100                              {      307561322, 1918244397       },
00101                              {      906041433, 360476981        },
00102                              {     1591375755, 268492659        },
00103                              {      461522398, 227343256        },
00104                              {     2145930725, 2020665454       },
00105                              {     1938419274, 1331283701       },
00106                              {      174405412, 524140103        },
00107                              {      494343653,  18063908        },
00108                              {     1025534808, 181709577        },
00109                              {     2048959776, 1913665637       },
00110                              {      950636517, 794796256        },
00111                              {     1828843197, 1335757744       },
00112                              {      211109723, 983900607        },
00113                              {      825474095, 1046009991       },
00114                              {      374915657, 381856628        },
00115                              {     1241296328, 698149463        },
00116                              {     1260624655, 1024538273       },
00117                              {      900676210, 1628865823       },
00118                              {      697951025, 500570753        },
00119                              {     1007920268, 1708398558       },
00120                              {      264596520, 624727803        },
00121                              {     1977924811, 674673241        },
00122                              {     1440257718, 271184151        },
00123                              {     1928778847, 993535203        },
00124                              {     1307807366, 1801502463       },
00125                              {     1498732610, 300876954        },
00126                              {     1617712402, 1574250679       },
00127                              {     1261800762, 1556667280       },
00128                              {      949929273, 560721070        },
00129                              {     1766170474, 1953522912       },
00130                              {     1849939248, 19435166         },
00131                              {      887262858, 1219627824       },
00132                              {      483086133, 603728993        },
00133                              {     1330541052, 1582596025       },
00134                              {     1850591475, 723593133        },
00135                              {     1431775678, 1558439000       },
00136                              {      922493739, 1356554404       },
00137                              {     1058517206, 948567762        },
00138                              {      709067283, 1350890215       },
00139                              {     1044787723, 2144304941       },
00140                              {      999707003, 513837520        },
00141                              {     2140038663, 1850568788       },
00142                              {     1803100150, 127574047        },
00143                              {      867445693, 1149173981       },
00144                              {      408583729, 914837991        },
00145                              {     1166715497, 602315845        },
00146                              {      430738528, 1743308384       },
00147                              {     1388022681, 1760110496       },
00148                              {     1664028066, 654300326        },
00149                              {     1767741172, 1338181197       },
00150                              {     1625723550, 1742482745       },
00151                              {      464486085, 1507852127       },
00152                              {      754082421, 1187454014       },
00153                              {     1315342834, 425995190        },
00154                              {      960416608, 2004255418       },
00155                              {     1262630671, 671761697        },
00156                              {       59809238, 103525918        },
00157                              {     1205644919, 2107823293       },
00158                              {     1615183160, 1152411412       },
00159                              {     1024474681, 2118672937       },
00160                              {     1703877649, 1235091369       },
00161                              {     1821417852, 1098463802       },
00162                              {     1738806466, 1529062843       },
00163                              {      620780646, 1654833544       },
00164                              {     1070174101, 795158254        },
00165                              {      658537995, 1693620426       },
00166                              {     2055317555, 508053916        },
00167                              {     1647371686, 1282395762       },
00168                              {       29067379, 409683067        },
00169                              {     1763495989, 1917939635       },
00170                              {     1602690753, 810926582        },
00171                              {      885787576, 513818500        },
00172                              {     1853512561, 1195205756       },
00173                              {     1798585498, 1970460256       },
00174                              {     1819261032, 1306536501       },
00175                              {     1133245275, 37901            },
00176                              {      689459799, 1334389069       },
00177                              {     1730609912, 1854586207       },
00178                              {     1556832175, 1228729041       },
00179                              {      251375753, 683687209        },
00180                              {     2083946182, 1763106152       },
00181                              {     2142981854, 1365385561       },
00182                              {      763711891, 1735754548       },
00183                              {     1581256466, 173689858        },
00184                              {     2121337132, 1247108250       },
00185                              {     1004003636, 891894307        },
00186                              {      569816524, 358675254        },
00187                              {      626626425, 116062841        },
00188                              {      632086003, 861268491        },
00189                              {     1008211580, 779404957        },
00190                              {     1134217766, 1766838261       },
00191                              {     1423829292, 1706666192       },
00192                              {      942037869, 1549358884       },
00193                              {     1959429535, 480779114        },
00194                              {      778311037, 1940360875       },
00195                              {     1531372185, 2009078158       },
00196                              {      241935492, 1050047003       },
00197                              {      272453504, 1870883868       },
00198                              {      390441332, 1057903098       },
00199                              {     1230238834, 1548117688       },
00200                              {     1242956379, 1217296445       },
00201                              {      515648357, 1675011378       },
00202                              {      364477932, 355212934        },
00203                              {     2096008713, 1570161804       },
00204                              {     1409752526, 214033983        },
00205                              {     1288158292, 1760636178       },
00206                              {      407562666, 1265144848       },
00207                              {     1071056491, 1582316946       },
00208                              {     1014143949, 911406955        },
00209                              {      203080461, 809380052        },
00210                              {      125647866, 1705464126       },
00211                              {     2015685843, 599230667        },
00212                              {     1425476020, 668203729        },
00213                              {     1673735652, 567931803        },
00214                              {     1714199325, 181737617        },
00215                              {     1389137652, 678147926        },
00216                              {      288547803, 435433694        },
00217                              {      200159281, 654399753        },
00218                              {     1580828223, 1298308945       },
00219                              {     1832286107, 169991953        },
00220                              {      182557704, 1046541065       },
00221                              {     1688025575, 1248944426       },
00222                              {     1508287706, 1220577001       },
00223                              {       36721212, 1377275347       },
00224                              {     1968679856, 1675229747       },
00225                              {      279109231, 1835333261       },
00226                              {     1358617667, 1416978076       },
00227                              {      740626186, 2103913602       },
00228                              {     1882655908, 251341858        },
00229                              {      648016670, 1459615287       },
00230                              {      780255321, 154906988        },
00231                              {      857296483, 203375965        },
00232                              {     1631676846, 681204578        },
00233                              {     1906971307, 1623728832       },
00234                              {     1541899600, 1168449797       },
00235                              {     1267051693, 1020078717       },
00236                              {     1998673940, 1298394942       },
00237                              {     1914117058, 1381290704       },
00238                              {      426068513, 1381618498       },
00239                              {      139365577, 1598767734       },
00240                              {     2129910384, 952266588        },
00241                              {      661788054, 19661356         },
00242                              {     1104640222, 240506063        },
00243                              {      356133630, 1676634527       },
00244                              {      242242374, 1863206182       },
00245                              {      957935844, 1490681416       }};
00246 #endif
00247 
00248 ClassImp(TRandom1)
00249 
00250 //______________________________________________________________________________
00251 TRandom1::TRandom1(UInt_t seed, Int_t lux)
00252         : fIntModulus(0x1000000),
00253           fMantissaBit24( TMath::Power(0.5,24.) ),
00254           fMantissaBit12( TMath::Power(0.5,12.) )
00255 {
00256 // Luxury level is set in the same way as the original FORTRAN routine.
00257 //  level 0  (p=24): equivalent to the original RCARRY of Marsaglia
00258 //           and Zaman, very long period, but fails many tests.
00259 //  level 1  (p=48): considerable improvement in quality over level 0,
00260 //           now passes the gap test, but still fails spectral test.
00261 //  level 2  (p=97): passes all known tests, but theoretically still
00262 //           defective.
00263 //  level 3  (p=223): DEFAULT VALUE.  Any theoretically possible
00264 //           correlations have very small chance of being observed.
00265 //  level 4  (p=389): highest possible luxury, all 24 bits chaotic.
00266    UInt_t seedlist[2]={0,0};
00267 
00268    fTheSeeds = &fSeed;
00269    fLuxury = lux;
00270    SetSeed2(seed, fLuxury);
00271 
00272    // setSeeds() wants a zero terminated array!
00273    seedlist[0]=fSeed;
00274    seedlist[1]=0;
00275    SetSeeds(seedlist, fLuxury);
00276 }
00277 
00278 //______________________________________________________________________________
00279 TRandom1::TRandom1()
00280         : fIntModulus(0x1000000),
00281           fMantissaBit24( TMath::Power(0.5,24.) ),
00282           fMantissaBit12( TMath::Power(0.5,12.) )
00283 {
00284    //default constructor
00285    fTheSeeds = &fSeed;
00286    UInt_t seed;
00287    UInt_t seedlist[2]={0,0};
00288 
00289    fLuxury = 3;
00290    int cycle = abs(int(fgNumEngines/fgMaxIndex));
00291    int curIndex = abs(int(fgNumEngines%fgMaxIndex));
00292    fgNumEngines +=1;
00293    UInt_t mask = ((cycle & 0x007fffff) << 8);
00294    GetTableSeeds( seedlist, curIndex );
00295    seed = seedlist[0]^mask;
00296    SetSeed2(seed, fLuxury);
00297 
00298    // setSeeds() wants a zero terminated array!
00299    seedlist[0]=fSeed; //<=============
00300    seedlist[1]=0;
00301    SetSeeds(seedlist, fLuxury);
00302 }
00303 
00304 //______________________________________________________________________________
00305 TRandom1::TRandom1(int rowIndex, int colIndex, int lux)
00306         : fIntModulus(0x1000000),
00307           fMantissaBit24( TMath::Power(0.5,24.) ),
00308           fMantissaBit12( TMath::Power(0.5,12.) )
00309 {
00310    //constructor
00311    fTheSeeds = &fSeed;
00312    UInt_t seed;
00313    UInt_t seedlist[2]={0,0};
00314 
00315    fLuxury = lux;
00316    int cycle = abs(int(rowIndex/fgMaxIndex));
00317    int row = abs(int(rowIndex%fgMaxIndex));
00318    int col = abs(int(colIndex%2));
00319    UInt_t mask = (( cycle & 0x000007ff ) << 20 );
00320    GetTableSeeds( seedlist, row );
00321    seed = ( seedlist[col] )^mask;
00322    SetSeed2(seed, fLuxury);
00323 
00324    // setSeeds() wants a zero terminated array!
00325    seedlist[0]=fSeed;
00326    seedlist[1]=0;
00327    SetSeeds(seedlist, fLuxury);
00328 }
00329 
00330 //______________________________________________________________________________
00331 TRandom1::~TRandom1()
00332 {
00333    //destructor
00334 }
00335 
00336 //______________________________________________________________________________
00337 void TRandom1::GetTableSeeds(UInt_t* seeds, Int_t index)
00338 {
00339    //static function returning the table of seeds
00340    if ((index >= 0) && (index < 215)) {
00341       seeds[0] = fgSeedTable[index][0];
00342       seeds[1] = fgSeedTable[index][1];
00343    }
00344    else seeds = 0;
00345 }
00346 
00347 //______________________________________________________________________________
00348 Double_t TRandom1::Rndm(Int_t)
00349 {
00350    //return a random number in ]0,1]
00351    float next_random;
00352    float uni;
00353    int i;
00354 
00355    uni = fFloatSeedTable[fJlag] - fFloatSeedTable[fIlag] - fCarry;
00356    if(uni < 0. ) {
00357       uni += 1.0;
00358       fCarry = fMantissaBit24;
00359    } else {
00360       fCarry = 0.;
00361    }
00362 
00363    fFloatSeedTable[fIlag] = uni;
00364    fIlag --;
00365    fJlag --;
00366    if(fIlag < 0) fIlag = 23;
00367    if(fJlag < 0) fJlag = 23;
00368 
00369    if( uni < fMantissaBit12 ){
00370       uni += fMantissaBit24 * fFloatSeedTable[fJlag];
00371       if( uni == 0) uni = fMantissaBit24 * fMantissaBit24;
00372    }
00373    next_random = uni;
00374    fCount24 ++;
00375 
00376 // every 24th number generation, several random numbers are generated
00377 // and wasted depending upon the fLuxury level.
00378 
00379    if(fCount24 == 24 ) {
00380       fCount24 = 0;
00381       for( i = 0; i != fNskip ; i++) {
00382          uni = fFloatSeedTable[fJlag] - fFloatSeedTable[fIlag] - fCarry;
00383          if(uni < 0. ) {
00384             uni += 1.0;
00385             fCarry = fMantissaBit24;
00386          } else {
00387             fCarry = 0.;
00388          }
00389          fFloatSeedTable[fIlag] = uni;
00390          fIlag --;
00391          fJlag --;
00392          if(fIlag < 0)fIlag = 23;
00393          if(fJlag < 0) fJlag = 23;
00394       }
00395    }
00396    return (double) next_random;
00397 }
00398 
00399 //______________________________________________________________________________
00400 void TRandom1::RndmArray(const Int_t size, Float_t *vect)
00401 {
00402    //return an array of random numbers in ]0,1]
00403    for (Int_t i=0;i<size;i++) vect[i] = Rndm();
00404 }
00405 
00406 //______________________________________________________________________________
00407 void TRandom1::RndmArray(const Int_t size, Double_t *vect)
00408 {
00409    //return an array of random numbers in ]0,1]
00410    float next_random;
00411    float uni;
00412    int i;
00413    int index;
00414 
00415    for (index=0; index<size; ++index) {
00416       uni = fFloatSeedTable[fJlag] - fFloatSeedTable[fIlag] - fCarry;
00417       if(uni < 0. ) {
00418          uni += 1.0;
00419          fCarry = fMantissaBit24;
00420       } else {
00421          fCarry = 0.;
00422       }
00423 
00424       fFloatSeedTable[fIlag] = uni;
00425       fIlag --;
00426       fJlag --;
00427       if(fIlag < 0) fIlag = 23;
00428       if(fJlag < 0) fJlag = 23;
00429 
00430       if( uni < fMantissaBit12 ){
00431          uni += fMantissaBit24 * fFloatSeedTable[fJlag];
00432          if( uni == 0) uni = fMantissaBit24 * fMantissaBit24;
00433       }
00434       next_random = uni;
00435       vect[index] = (double)next_random;
00436       fCount24 ++;
00437 
00438 // every 24th number generation, several random numbers are generated
00439 // and wasted depending upon the fLuxury level.
00440 
00441       if(fCount24 == 24 ) {
00442          fCount24 = 0;
00443          for( i = 0; i != fNskip ; i++) {
00444             uni = fFloatSeedTable[fJlag] - fFloatSeedTable[fIlag] - fCarry;
00445             if(uni < 0. ) {
00446                uni += 1.0;
00447                fCarry = fMantissaBit24;
00448             } else {
00449                fCarry = 0.;
00450             }
00451             fFloatSeedTable[fIlag] = uni;
00452             fIlag --;
00453             fJlag --;
00454             if(fIlag < 0)fIlag = 23;
00455             if(fJlag < 0) fJlag = 23;
00456          }
00457       }
00458    }
00459 }
00460 
00461 
00462 //______________________________________________________________________________
00463 void TRandom1::SetSeeds(const UInt_t *seeds, int lux)
00464 {
00465    //set seeds
00466    const int ecuyer_a = 53668;
00467    const int ecuyer_b = 40014;
00468    const int ecuyer_c = 12211;
00469    const int ecuyer_d = 2147483563;
00470 
00471    const int lux_levels[5] = {0,24,73,199,365};
00472    int i;
00473    UInt_t int_seed_table[24];
00474    Long64_t k_multiple,next_seed;
00475    const UInt_t *seedptr;
00476 
00477    fTheSeeds = seeds;
00478    seedptr   = seeds;
00479 
00480    if(seeds == 0) {
00481       SetSeed2(fSeed,lux);
00482       fTheSeeds = &fSeed;
00483       return;
00484    }
00485 
00486    fSeed = *seeds;
00487 
00488 // number of additional random numbers that need to be 'thrown away'
00489 // every 24 numbers is set using fLuxury level variable.
00490 
00491    if( (lux > 4)||(lux < 0) ) {
00492       if(lux >= 24) {
00493          fNskip = lux - 24;
00494       } else {
00495          fNskip = lux_levels[3]; // corresponds to default fLuxury level
00496       }
00497    } else {
00498       fLuxury = lux;
00499       fNskip  = lux_levels[fLuxury];
00500    }
00501 
00502    for( i = 0;(i != 24)&&(*seedptr != 0);i++) {
00503       int_seed_table[i] = *seedptr % fIntModulus;
00504       seedptr++;
00505    }
00506 
00507    if(i != 24){
00508       next_seed = int_seed_table[i-1];
00509       for(;i != 24;i++) {
00510          k_multiple = next_seed / ecuyer_a;
00511          next_seed = ecuyer_b * (next_seed - k_multiple * ecuyer_a)
00512          - k_multiple * ecuyer_c ;
00513          if(next_seed < 0)next_seed += ecuyer_d;
00514          int_seed_table[i] = next_seed % fIntModulus;
00515       }
00516    }
00517 
00518    for(i = 0;i != 24;i++)
00519       fFloatSeedTable[i] = int_seed_table[i] * fMantissaBit24;
00520 
00521    fIlag = 23;
00522    fJlag = 9;
00523    fCarry = 0. ;
00524 
00525    if( fFloatSeedTable[23] == 0. ) fCarry = fMantissaBit24;
00526 
00527    fCount24 = 0;
00528 }
00529 
00530 //______________________________________________________________________________
00531 void TRandom1::SetSeed2(UInt_t seed, int lux)
00532 {
00533 // The initialisation is carried out using a Multiplicative
00534 // Congruential generator using formula constants of L'Ecuyer
00535 // as described in "A review of pseudorandom number generators"
00536 // (Fred James) published in Computer Physics Communications 60 (1990)
00537 // pages 329-344
00538 //
00539 // modified for the case of seed = 0. In that case a random 64 bits seed based on
00540 // TUUID (using TRandom3(0) ) is generated in order to have a unique seed
00541 //
00542 
00543    const int ecuyer_a = 53668;
00544    const int ecuyer_b = 40014;
00545    const int ecuyer_c = 12211;
00546    const int ecuyer_d = 2147483563;
00547 
00548    const int lux_levels[5] = {0,24,73,199,365};
00549 
00550    UInt_t int_seed_table[24];
00551 
00552    // case of seed == 0
00553    // use a random seed based on TRandom3(0) which is base don the UUID
00554    if (seed == 0) {
00555       TRandom3 r3(0);
00556       seed =  static_cast<UInt_t> (4294967296.*r3.Rndm());
00557    }
00558 
00559 
00560    Long64_t next_seed = seed;
00561    Long64_t k_multiple;
00562    int i;
00563 
00564    // number of additional random numbers that need to be 'thrown away'
00565    // every 24 numbers is set using fLuxury level variable.
00566 
00567    fSeed = seed;
00568    if( (lux > 4)||(lux < 0) ) {
00569       if(lux >= 24) {
00570          fNskip = lux - 24;
00571       } else {
00572          fNskip = lux_levels[3]; // corresponds to default fLuxury level
00573       }
00574    } else {
00575       fLuxury = lux;
00576       fNskip  = lux_levels[fLuxury];
00577    }
00578 
00579 
00580    for(i = 0;i != 24;i++) {
00581       k_multiple = next_seed / ecuyer_a;
00582       next_seed = ecuyer_b * (next_seed - k_multiple * ecuyer_a)
00583       - k_multiple * ecuyer_c ;
00584       if(next_seed < 0)next_seed += ecuyer_d;
00585       int_seed_table[i] = next_seed % fIntModulus;
00586    }
00587 
00588    for(i = 0;i != 24;i++)
00589       fFloatSeedTable[i] = int_seed_table[i] * fMantissaBit24;
00590 
00591    fIlag = 23;
00592    fJlag = 9;
00593    fCarry = 0. ;
00594 
00595    if( fFloatSeedTable[23] == 0. ) fCarry = fMantissaBit24;
00596 
00597    fCount24 = 0;
00598 }
00599 
00600 void TRandom1::SetSeed(UInt_t seed)
00601 {
00602    // Set RanLux seed using default luxury level
00603    SetSeed2(seed);
00604 }

Generated on Tue Jul 5 14:34:28 2011 for ROOT_528-00b_version by  doxygen 1.5.1