00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040 #include "SprRanluxEngine.hh"
00041 #include "SprSeedTable.hh"
00042 #include <cmath>
00043 #include <cstdlib>
00044
00045
00046 using namespace std;
00047
00048
00049 const int SprRanluxEngine::int_modulus = 0x1000000;
00050 const double SprRanluxEngine::mantissa_bit_24 = pow(0.5,24.);
00051 const double SprRanluxEngine::mantissa_bit_12 = pow(0.5,12.);
00052
00053
00054 int SprRanluxEngine::numEngines = 0;
00055
00056
00057 const int SprRanluxEngine::maxIndex = 215;
00058
00059 SprRanluxEngine::SprRanluxEngine(long seed, int lux) {
00060 luxury = lux;
00061 setSeed(seed, luxury);
00062 }
00063
00064 SprRanluxEngine::~SprRanluxEngine() {}
00065
00066 void SprRanluxEngine::setSeed(long seed, int lux) {
00067
00068
00069 if (seed == 0) {
00070 div_t temp = div(numEngines, maxIndex);
00071 numEngines++;
00072 seed = seedTable[abs(temp.rem)][0] ^ ((abs(temp.quot) & 0x007fffff) << 8);
00073 }
00074
00075
00076
00077
00078
00079
00080
00081 const int ecuyer_a = 53668;
00082 const int ecuyer_b = 40014;
00083 const int ecuyer_c = 12211;
00084 const int ecuyer_d = 2147483563;
00085
00086 const int lux_levels[5] = {0,24,73,199,365};
00087
00088
00089
00090
00091 theSeed = seed;
00092 if( (lux > 4)||(lux < 0) ){
00093 if(lux >= 24){
00094 nskip = lux - 24;
00095 }else{
00096 nskip = lux_levels[3];
00097 }
00098 }else{
00099 luxury = lux;
00100 nskip = lux_levels[luxury];
00101 }
00102
00103
00104 long next_seed = seed;
00105 for(int i = 0;i < 24;i++){
00106 long k_multiple = next_seed / ecuyer_a;
00107 next_seed = ecuyer_b * (next_seed - k_multiple * ecuyer_a)
00108 - k_multiple * ecuyer_c ;
00109 if(next_seed < 0)next_seed += ecuyer_d;
00110 float_seed_table[i] = (next_seed % int_modulus) * mantissa_bit_24;
00111 }
00112
00113 i_lag = 23;
00114 j_lag = 9;
00115 carry = 0. ;
00116
00117 if( float_seed_table[23] == 0. ) carry = mantissa_bit_24;
00118
00119 count24 = 0;
00120 }
00121
00122 double SprRanluxEngine::flat() {
00123
00124 float next_random;
00125 float uni;
00126 int i;
00127
00128 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
00129 if(uni < 0. ){
00130 uni += 1.0;
00131 carry = mantissa_bit_24;
00132 }else{
00133 carry = 0.;
00134 }
00135
00136 float_seed_table[i_lag] = uni;
00137 i_lag --;
00138 j_lag --;
00139 if(i_lag < 0) i_lag = 23;
00140 if(j_lag < 0) j_lag = 23;
00141
00142 if( uni < mantissa_bit_12 ){
00143 uni += mantissa_bit_24 * float_seed_table[j_lag];
00144 if( uni == 0) uni = mantissa_bit_24 * mantissa_bit_24;
00145 }
00146 next_random = uni;
00147 count24 ++;
00148
00149
00150
00151
00152 if(count24 == 24 ){
00153 count24 = 0;
00154 for( i = 0; i != nskip ; i++){
00155 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
00156 if(uni < 0. ){
00157 uni += 1.0;
00158 carry = mantissa_bit_24;
00159 }else{
00160 carry = 0.;
00161 }
00162 float_seed_table[i_lag] = uni;
00163 i_lag --;
00164 j_lag --;
00165 if(i_lag < 0)i_lag = 23;
00166 if(j_lag < 0) j_lag = 23;
00167 }
00168 }
00169 return (double) next_random;
00170 }
00171
00172 void SprRanluxEngine::flatArray(int size, double* vect)
00173 {
00174 float next_random;
00175 float uni;
00176 int i;
00177 int index;
00178
00179 for (index=0; index<size; ++index) {
00180 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
00181 if(uni < 0. ){
00182 uni += 1.0;
00183 carry = mantissa_bit_24;
00184 }else{
00185 carry = 0.;
00186 }
00187
00188 float_seed_table[i_lag] = uni;
00189 i_lag --;
00190 j_lag --;
00191 if(i_lag < 0) i_lag = 23;
00192 if(j_lag < 0) j_lag = 23;
00193
00194 if( uni < mantissa_bit_12 ){
00195 uni += mantissa_bit_24 * float_seed_table[j_lag];
00196 if( uni == 0) uni = mantissa_bit_24 * mantissa_bit_24;
00197 }
00198 next_random = uni;
00199 vect[index] = (double)next_random;
00200 count24 ++;
00201
00202
00203
00204
00205 if(count24 == 24 ){
00206 count24 = 0;
00207 for( i = 0; i != nskip ; i++){
00208 uni = float_seed_table[j_lag] - float_seed_table[i_lag] - carry;
00209 if(uni < 0. ){
00210 uni += 1.0;
00211 carry = mantissa_bit_24;
00212 }else{
00213 carry = 0.;
00214 }
00215 float_seed_table[i_lag] = uni;
00216 i_lag --;
00217 j_lag --;
00218 if(i_lag < 0)i_lag = 23;
00219 if(j_lag < 0) j_lag = 23;
00220 }
00221 }
00222 }
00223 }