00001
00003
00004
00005
00006
00007
00008
00009
00010 #include "sp_random.h"
00011
00012 #include <cmath>
00013
00014
00015
00016
00017 namespace faudes {
00018
00019
00020
00021 #define MODULUS 2147483647
00022 #define MULTIPLIER 48271
00023 #define CHECK 399268537
00024 #define STREAMS 256
00025 #define A256 22925
00026 #define DEFAULT 123456789
00027
00028 static long ran_seed[STREAMS] = {DEFAULT};
00029 static int ran_stream = 0;
00030 static int ran_initialized = 0;
00031
00032
00033
00034 void ran_plant_seeds(long x)
00035 {
00036 const long Q = MODULUS / A256;
00037
00038 const long R = MODULUS % A256;
00039 int j;
00040 int s;
00041
00042 ran_initialized = 1;
00043 s = ran_stream;
00044 ran_select_stream(0);
00045 ran_put_seed(x);
00046 ran_stream = s;
00047 for (j = 1; j < STREAMS; j++) {
00048 x = A256 * (ran_seed[j - 1] % Q) - R * (ran_seed[j - 1] / Q);
00049 if (x > 0)
00050 ran_seed[j] = x;
00051 else
00052 ran_seed[j] = x + MODULUS;
00053 }
00054 }
00055
00056
00057 void ran_put_seed(long seed)
00058 {
00059 ran_seed[ran_stream] = seed;
00060 }
00061
00062
00063 void ran_select_stream(int index)
00064 {
00065 ran_stream = ((unsigned int) index) % STREAMS;
00066 if ((ran_initialized == 0) && (ran_stream != 0))
00067 ran_plant_seeds(DEFAULT);
00068 }
00069
00070
00071 void ran_init(long seed){
00072 ran_select_stream(0);
00073 ran_put_seed(seed);
00074 }
00075
00076
00077
00078 double ran(void){
00079 const long Q = MODULUS / MULTIPLIER;
00080 const long R = MODULUS % MULTIPLIER;
00081 long t;
00082
00083 t = MULTIPLIER * (ran_seed[ran_stream] % Q) - R * (ran_seed[ran_stream] / Q);
00084 if (t > 0)
00085 ran_seed[ran_stream] = t;
00086 else
00087 ran_seed[ran_stream] = t + MODULUS;
00088 return ((double) ran_seed[ran_stream] / MODULUS);
00089
00090 }
00091
00092
00093
00094 double ran_uniform(double a, double b){
00095 double q = ran();
00096 q=a*(1-q)+b*q;
00097 return q;
00098 }
00099
00100
00101 long ran_uniform_int(long a, long b){
00102 double q = ran();
00103 long i =(long) floor(((double) a)*(1-q)+((double)b)*q);
00104 if(i>=b) i=b-1;
00105 if(i< a) i=a;
00106 return i;
00107 }
00108
00109
00110 double ran_exponential(double mu){
00111 double q=0;
00112 while(q==0){
00113 q=ran();
00114 }
00115 return -mu*log(q);
00116 }
00117
00118
00119 double ran_exponential(double mu, tpTime::Type tossLB, tpTime::Type tossUB){
00120 if(tossLB==tossUB){
00121 FD_DS("Ran_exponential(): empty interval");
00122 return tpTime::UnDef;
00123 }
00124 else{
00125 double lb= -expm1(-(static_cast<double> (tossLB))/ mu);
00126 double ub= -expm1(-(static_cast<double> (tossUB))/ mu);
00127 double u=ran_uniform(lb,ub);
00128 double ret=(-mu*(log(1-u)));
00129
00130 return ret;
00131 }
00132 }
00133
00134
00135 double ran_gauss(double mu, double sigma, tpTime::Type tossLB, tpTime::Type tossUB){
00136 if(tossLB==tossUB){
00137 FD_DS("Ran_gauss(): empty interval");
00138 return tpTime::UnDef;
00139 }
00140 else{
00141
00142 double ztossLB=(static_cast<double>(tossLB)-mu)/sigma;
00143 double ztossUB=(static_cast<double>(tossUB)-mu)/sigma;
00144
00145 double zlb=ran_gaussian_cdf_P(ztossLB);
00146 double zub=ran_gaussian_cdf_P(ztossUB);
00147 double u=ran_uniform(zlb,zub);
00148
00149
00150
00151
00152 double zret;
00153 static const double a[] =
00154 {
00155 -3.969683028665376e+01,
00156 2.209460984245205e+02,
00157 -2.759285104469687e+02,
00158 1.383577518672690e+02,
00159 -3.066479806614716e+01,
00160 2.506628277459239e+00
00161 };
00162
00163 static const double b[] =
00164 {
00165 -5.447609879822406e+01,
00166 1.615858368580409e+02,
00167 -1.556989798598866e+02,
00168 6.680131188771972e+01,
00169 -1.328068155288572e+01
00170 };
00171
00172 static const double c[] =
00173 {
00174 -7.784894002430293e-03,
00175 -3.223964580411365e-01,
00176 -2.400758277161838e+00,
00177 -2.549732539343734e+00,
00178 4.374664141464968e+00,
00179 2.938163982698783e+00
00180 };
00181
00182 static const double d[] =
00183 {
00184 7.784695709041462e-03,
00185 3.224671290700398e-01,
00186 2.445134137142996e+00,
00187 3.754408661907416e+00
00188 };
00189 double q,r;
00190 if(u<0 || u>1) zret=0.0;
00191 else if (u==0){
00192 FD_DS("Ran_gauss(): u="<<u<<"ret=HUGE_VAL");
00193 return -HUGE_VAL;
00194 }
00195 else if (u==1){
00196 FD_DS("Ran_gauss(): u="<<u<<"ret=-HUGE_VAL");
00197 return HUGE_VAL;
00198 }
00199 else if (u<0.02425){
00200
00201 q = sqrt(-2*log(u));
00202 zret=(((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5]) /
00203 ((((d[0]*q+d[1])*q+d[2])*q+d[3])*q+1);
00204 }
00205 else if(u>0.97575){
00206
00207 q = sqrt(-2*log(1-u));
00208 zret= -(((((c[0]*q+c[1])*q+c[2])*q+c[3])*q+c[4])*q+c[5]) /
00209 ((((d[0]*q+d[1])*q+d[2])*q+d[3])*q+1);
00210 }
00211 else{
00212
00213 q = u - 0.5;
00214 r = q*q;
00215 zret=(((((a[0]*r+a[1])*r+a[2])*r+a[3])*r+a[4])*r+a[5])*q /
00216 (((((b[0]*r+b[1])*r+b[2])*r+b[3])*r+b[4])*r+1);
00217 }
00218
00219 double ret=(zret*sigma)+mu;
00220
00221 return ret;
00222 }
00223 }
00224
00225
00226
00227 double ran_gaussian_cdf_P(double x){
00228 const double PI = 3.141592654;
00229 const double b1 = 0.319381530;
00230 const double b2 = -0.356563782;
00231 const double b3 = 1.781477937;
00232 const double b4 = -1.821255978;
00233 const double b5 = 1.330274429;
00234 const double p = 0.2316419;
00235
00236 if(x >= 0.0) {
00237 double t = 1.0 / (1.0 + p*x);
00238 return (1.0 - (1/sqrt(2*PI))*exp(-x*x/2.0 )*t*
00239 (t*(t*(t*(t*b5 + b4) + b3) + b2) + b1));
00240 }
00241 else {
00242 double t = 1.0 / ( 1.0 - p * x );
00243 return ( (1/sqrt(2*PI))*exp(-x*x/2.0 )*t*
00244 (t*(t*(t*(t*b5 + b4) + b3) + b2) + b1));
00245 }
00246
00247
00248 }
00249
00250
00251 }