| [851] | 1 | #include "machdefs.h" | 
|---|
|  | 2 | #include <stdlib.h> | 
|---|
|  | 3 | #include <stdio.h> | 
|---|
|  | 4 | #include <string.h> | 
|---|
|  | 5 | #include <math.h> | 
|---|
|  | 6 | #include <sys/time.h> | 
|---|
|  | 7 | #include "srandgen.h" | 
|---|
|  | 8 | #include "smathconst.h" | 
|---|
|  | 9 |  | 
|---|
|  | 10 | static double GAU_RANGE=6.; | 
|---|
|  | 11 |  | 
|---|
|  | 12 | /* | 
|---|
|  | 13 | ++ | 
|---|
|  | 14 | Module        Tirages aleatoires (C) | 
|---|
|  | 15 | Lib   LibsUtil | 
|---|
|  | 16 | include       nbrandom.h | 
|---|
|  | 17 | -- | 
|---|
|  | 18 | */ | 
|---|
|  | 19 |  | 
|---|
|  | 20 | /* | 
|---|
|  | 21 | ++ | 
|---|
|  | 22 | frand01() | 
|---|
|  | 23 | tirage aleatoire entre 0 et 1, retourne float | 
|---|
|  | 24 | drand01() | 
|---|
|  | 25 | tirage aleatoire entre 0 et 1, retourne double | 
|---|
|  | 26 | rand01() | 
|---|
|  | 27 | c'est le defaut: drand01() | 
|---|
|  | 28 | frandpm1() | 
|---|
|  | 29 | tirage aleatoire entre -1 et 1, retourne float | 
|---|
|  | 30 | drandpm1() | 
|---|
|  | 31 | tirage aleatoire entre -1 et 1, retourne double | 
|---|
|  | 32 | ranfpm1() | 
|---|
|  | 33 | c'est le defaut: drandpm1() | 
|---|
|  | 34 | -- | 
|---|
|  | 35 | */ | 
|---|
|  | 36 |  | 
|---|
| [913] | 37 | /*! \defgroup RandGen | 
|---|
|  | 38 | Random number generators */ | 
|---|
|  | 39 |  | 
|---|
|  | 40 | /*! \ingroup  SysTools | 
|---|
|  | 41 | \fn frand01 | 
|---|
|  | 42 | Returns a random number (float) with flat distribution between 0 ... 1 | 
|---|
|  | 43 | */ | 
|---|
|  | 44 | /*! \ingroup  SysTools | 
|---|
|  | 45 | \fn drand01 | 
|---|
|  | 46 | Returns a random number (double) with flat distribution between 0 ... 1 | 
|---|
|  | 47 | */ | 
|---|
|  | 48 | /*! \ingroup  SysTools | 
|---|
|  | 49 | \fn frandpm1() | 
|---|
|  | 50 | Returns a random number (float) with flat distribution between -1 ... 1 | 
|---|
|  | 51 | */ | 
|---|
|  | 52 | /*! \ingroup  SysTools | 
|---|
|  | 53 | \fn drandpm1() | 
|---|
|  | 54 | Returns a random number (double) with flat distribution between -1 ... 1 | 
|---|
|  | 55 | */ | 
|---|
|  | 56 |  | 
|---|
| [851] | 57 | /*=========================================================================*/ | 
|---|
|  | 58 | /* | 
|---|
|  | 59 | ++ | 
|---|
|  | 60 | void Ini_Ranf_Quick(long seed_val, int lp) | 
|---|
|  | 61 | Initialisation rapide du generateur (drand48) par un entier | 
|---|
|  | 62 | de 32 bits de type long (cf srand48). | 
|---|
|  | 63 | -- | 
|---|
|  | 64 | */ | 
|---|
| [913] | 65 |  | 
|---|
|  | 66 | /*! \ingroup  SysTools | 
|---|
|  | 67 | Fast initialisation of the random number generator \c (drand48) | 
|---|
|  | 68 | using a \c long type value (cf \c srand48 ) | 
|---|
|  | 69 | */ | 
|---|
| [851] | 70 | void Ini_Ranf_Quick(long seed_val, int lp) | 
|---|
|  | 71 | { | 
|---|
|  | 72 | if(lp) printf("Ini_Ranf_Quick: %d\n",(int) seed_val); | 
|---|
|  | 73 | srand48(seed_val); | 
|---|
|  | 74 | return; | 
|---|
|  | 75 | } | 
|---|
|  | 76 |  | 
|---|
|  | 77 | /*=========================================================================*/ | 
|---|
|  | 78 | /* | 
|---|
|  | 79 | ++ | 
|---|
|  | 80 | void Ini_Ranf(unsigned short seed_16v[3], int lp) | 
|---|
|  | 81 | Initialisation complete du generateur (drand48) par | 
|---|
|  | 82 | 48 bits (cf seed48). | 
|---|
|  | 83 | -- | 
|---|
|  | 84 | */ | 
|---|
| [913] | 85 | /*! \ingroup  SysTools | 
|---|
|  | 86 | complete initialisation of the random number generator \c (drand48) | 
|---|
|  | 87 | using a \c using 48 bits (cf \c seed48 ) | 
|---|
|  | 88 | */ | 
|---|
| [851] | 89 | void Ini_Ranf(unsigned short seed_16v[3], int lp) | 
|---|
|  | 90 | { | 
|---|
|  | 91 | if(lp) printf("Ini_Ranf: %d %d %d\n" | 
|---|
|  | 92 | ,seed_16v[0],seed_16v[1],seed_16v[2]); | 
|---|
|  | 93 | seed48(seed_16v); | 
|---|
|  | 94 | return; | 
|---|
|  | 95 | } | 
|---|
|  | 96 |  | 
|---|
|  | 97 | /*=========================================================================*/ | 
|---|
|  | 98 | /* | 
|---|
|  | 99 | ++ | 
|---|
|  | 100 | void Get_Ranf(unsigned short seed_16v[3], int lp) | 
|---|
|  | 101 | Recuperation de l'etat du generateur (drand48) sur | 
|---|
|  | 102 | de 48 bits (cf seed48). | 
|---|
|  | 103 | -- | 
|---|
|  | 104 | */ | 
|---|
| [913] | 105 | /*! \ingroup  SysTools | 
|---|
|  | 106 | Returns the status (48 bits) of the random number generator \c (drand48) | 
|---|
|  | 107 | (cf \c seed48 ) | 
|---|
|  | 108 | */ | 
|---|
| [851] | 109 | void Get_Ranf(unsigned short seed_16v[3], int lp) | 
|---|
|  | 110 | { | 
|---|
|  | 111 | unsigned short seed[3] = {0,0,0}; | 
|---|
|  | 112 | unsigned short *p; | 
|---|
|  | 113 | p = seed48(seed); | 
|---|
|  | 114 | memcpy(seed_16v,p,3*sizeof(unsigned short)); | 
|---|
|  | 115 | if(lp) printf("Get_Ranf: %d %d %d\n" | 
|---|
|  | 116 | ,seed_16v[0],seed_16v[1],seed_16v[2]); | 
|---|
|  | 117 | /* on re-initialise a ce qui etait avant */ | 
|---|
|  | 118 | seed48(seed_16v); | 
|---|
|  | 119 | return; | 
|---|
|  | 120 | } | 
|---|
|  | 121 |  | 
|---|
|  | 122 | /*=========================================================================*/ | 
|---|
|  | 123 | /* | 
|---|
|  | 124 | ++ | 
|---|
|  | 125 | void Auto_Ini_Ranf(int lp) | 
|---|
|  | 126 | Initialisation automatique (pseudo) aleatoire du generateur. | 
|---|
|  | 127 | L'initialiseur est donne par le nombre de millisecondes | 
|---|
|  | 128 | ecoulees depuis le dernier jour multiple de 23 du nombre de jours | 
|---|
|  | 129 | depuis le 0 heure le 1er Janvier 1970 UTC (cf gettimeofday). | 
|---|
|  | 130 | Pour retomber sur la meme initialisation | 
|---|
|  | 131 | il faut generer deux aleatoires a moins de 1/1000 seconde | 
|---|
|  | 132 | ou generer le deuxieme aleatoire 23 jours apres le premier | 
|---|
|  | 133 | a la meme heure (a 1/1000 de seconde pres). La fonction | 
|---|
|  | 134 | d'initialisation utilisee est Ini_Ranf_Quick(long). | 
|---|
|  | 135 | -- | 
|---|
|  | 136 | */ | 
|---|
| [913] | 137 | /*! \ingroup  SysTools | 
|---|
|  | 138 | Automatic initialisation using the present time | 
|---|
|  | 139 | */ | 
|---|
| [851] | 140 | void Auto_Ini_Ranf(int lp) | 
|---|
|  | 141 | { | 
|---|
|  | 142 | struct timeval now; | 
|---|
|  | 143 | long nj,nj23,seed=0; | 
|---|
|  | 144 | double buf; | 
|---|
|  | 145 |  | 
|---|
|  | 146 | gettimeofday (&now,0); | 
|---|
|  | 147 |  | 
|---|
|  | 148 | /* dans 32 bits signes on met environ 23 jours a 1/1000 de seconde pres! */ | 
|---|
|  | 149 | /* Nombre de jours depuis l'origine */ | 
|---|
|  | 150 | nj = (long) now.tv_sec / 86400; | 
|---|
|  | 151 | /* Nombre de jours depuis le dernier jour multiple de 23 jours */ | 
|---|
|  | 152 | nj23 = nj % 23; | 
|---|
|  | 153 | /* nombre de secondes depuis le dernier jour multiple de 23 jours */ | 
|---|
|  | 154 | buf = (double) (nj23*86400 + (now.tv_sec-nj*86400)); | 
|---|
|  | 155 | /* nombre de milliemes de secondes depuis ... */ | 
|---|
|  | 156 | buf = buf*1000. +  now.tv_usec/1000.; | 
|---|
|  | 157 | seed = (long) buf; | 
|---|
|  | 158 |  | 
|---|
|  | 159 | if(lp) { | 
|---|
|  | 160 | printf("Auto_Ini_Ranf: date %d s %d 10^-6 sec seed=%d:\n" | 
|---|
|  | 161 | ,now.tv_sec,now.tv_usec,seed); | 
|---|
|  | 162 | if(lp>1) printf("... njours=%d nj23=%d buf=%.20g\n",nj,nj23,buf); | 
|---|
|  | 163 | } | 
|---|
|  | 164 | Ini_Ranf_Quick(seed,lp); | 
|---|
|  | 165 | return; | 
|---|
|  | 166 | } | 
|---|
|  | 167 |  | 
|---|
|  | 168 | /*=========================================================================*/ | 
|---|
|  | 169 | /* | 
|---|
|  | 170 | ++ | 
|---|
|  | 171 | void SetGauRange(double range) | 
|---|
|  | 172 | Generation de distribution gaussienne: | 
|---|
|  | 173 | Changement de l'initialisation de l'excursion du tirage | 
|---|
|  | 174 | en nombre de sigmas | 
|---|
|  | 175 | -- | 
|---|
|  | 176 | */ | 
|---|
|  | 177 | void SetGauRange(double range) | 
|---|
|  | 178 | { | 
|---|
|  | 179 | GAU_RANGE = range; | 
|---|
|  | 180 | } | 
|---|
|  | 181 |  | 
|---|
|  | 182 | /*=========================================================================*/ | 
|---|
|  | 183 | /* | 
|---|
|  | 184 | ++ | 
|---|
|  | 185 | float NorRand(void) | 
|---|
|  | 186 | Generation aleatoire gaussienne normee centree | 
|---|
|  | 187 | -- | 
|---|
|  | 188 | */ | 
|---|
| [913] | 189 | /*! \ingroup  SysTools | 
|---|
|  | 190 | Normal (Gaussian) random number generator (Mean=0., Sigma=1.) | 
|---|
|  | 191 | */ | 
|---|
| [851] | 192 | float NorRand(void) | 
|---|
|  | 193 | { | 
|---|
|  | 194 | double x,A,B; | 
|---|
|  | 195 |  | 
|---|
|  | 196 | LAB10: | 
|---|
|  | 197 | A = drand01(); | 
|---|
|  | 198 | if ( A == 0. ) goto LAB10; | 
|---|
|  | 199 | B = drand01(); | 
|---|
|  | 200 | x = sqrt(-2.*log(A))*cos(DeuxPi*B); | 
|---|
|  | 201 | return( (float) x ); | 
|---|
|  | 202 | } | 
|---|
|  | 203 |  | 
|---|
|  | 204 | /*=========================================================================*/ | 
|---|
|  | 205 | /* | 
|---|
|  | 206 | ++ | 
|---|
|  | 207 | float NorRand1(void) | 
|---|
|  | 208 | Generation aleatoire gaussienne normee centree | 
|---|
|  | 209 | la distribution est limitee entre +/- GAU_RANGE (obsolete). | 
|---|
|  | 210 | -- | 
|---|
|  | 211 | */ | 
|---|
|  | 212 | float NorRand1(void) | 
|---|
|  | 213 | { | 
|---|
|  | 214 | double b, x, y, gauss; | 
|---|
|  | 215 |  | 
|---|
|  | 216 | b = 1./sqrt(2.*M_PI); | 
|---|
|  | 217 | LAB10: | 
|---|
|  | 218 | x = GAU_RANGE*drandpm1(); | 
|---|
|  | 219 | y = drand01()*b; | 
|---|
|  | 220 | gauss = b*exp(-x*x/2.); | 
|---|
|  | 221 | if ( gauss-y < 0. ) goto LAB10 ; | 
|---|
|  | 222 | return( (float) x ); | 
|---|
|  | 223 | } | 
|---|
|  | 224 |  | 
|---|
|  | 225 | /*=========================================================================*/ | 
|---|
|  | 226 | /* | 
|---|
|  | 227 | ++ | 
|---|
|  | 228 | double GauRnd(double am, double s) | 
|---|
|  | 229 | Generation aleatoire gaussienne de centre "am" et de sigma "s". | 
|---|
|  | 230 | -- | 
|---|
|  | 231 | */ | 
|---|
| [913] | 232 | /*! \ingroup  SysTools | 
|---|
|  | 233 | Normal (Gaussian) random number generator with the specified mean | 
|---|
|  | 234 | (\c am ) and sigma (\c s ) | 
|---|
|  | 235 | */ | 
|---|
| [851] | 236 | double GauRnd(double am, double s) | 
|---|
|  | 237 | { | 
|---|
|  | 238 | double x,A,B; | 
|---|
|  | 239 |  | 
|---|
|  | 240 | LAB10: | 
|---|
|  | 241 | A = drand01(); | 
|---|
|  | 242 | if ( A == 0. ) goto LAB10; | 
|---|
|  | 243 | B = drand01(); | 
|---|
|  | 244 | x = am + s * sqrt(-2.*log(A))*cos(DeuxPi*B); | 
|---|
|  | 245 | return(x); | 
|---|
|  | 246 | } | 
|---|
|  | 247 |  | 
|---|
|  | 248 | /*=========================================================================*/ | 
|---|
|  | 249 | /* | 
|---|
|  | 250 | ++ | 
|---|
|  | 251 | double GauRnd1(double am, double s) | 
|---|
|  | 252 | Generation aleatoire gaussienne de centre "am" et de | 
|---|
|  | 253 | sigma "s" la distribution est limitee entre am +/- GAU_RANGE (obsolete). | 
|---|
|  | 254 | -- | 
|---|
|  | 255 | */ | 
|---|
|  | 256 | double GauRnd1(double am, double s) | 
|---|
|  | 257 | { | 
|---|
|  | 258 | double s2, b, x, y, gauss; | 
|---|
|  | 259 |  | 
|---|
|  | 260 | s2 = 2.*s*s; | 
|---|
|  | 261 | b = 1./sqrt(2.*M_PI*s); | 
|---|
|  | 262 | LAB10: | 
|---|
|  | 263 | x = am + GAU_RANGE*s*drandpm1(); | 
|---|
|  | 264 | y = drand01()*b; | 
|---|
|  | 265 | gauss = b*exp(-(x-am)*(x-am)/s2); | 
|---|
|  | 266 | if ( gauss-y < 0. ) goto LAB10 ; | 
|---|
|  | 267 | return(x); | 
|---|
|  | 268 | } | 
|---|
|  | 269 |  | 
|---|
|  | 270 | /*==========================================================================*/ | 
|---|
|  | 271 | /* | 
|---|
|  | 272 | ++ | 
|---|
|  | 273 | void NormGau(double *x,double *y,double mx,double my,double sa,double sb,double teta); | 
|---|
|  | 274 | Tirage de 2 nombres aleatoires x et y distribues sur une gaussienne 2D | 
|---|
|  | 275 | de centre (x=mx,y=my), de sigmas grand axe et petit axe (sa,sb) | 
|---|
|  | 276 | et dont le grand axe fait un angle teta (radian) avec l'axe des x. | 
|---|
|  | 277 | -- | 
|---|
|  | 278 | */ | 
|---|
|  | 279 | /* | 
|---|
|  | 280 | ++ | 
|---|
|  | 281 | | - La densite de probabilite (normalisee a 1) sur laquelle on tire est: | 
|---|
|  | 282 | | N*exp[-0.5*{ (A/sa)**2+(C/sc)**2 }],  N=1/(2Pi*sa*sc) | 
|---|
|  | 283 | | ou A et B sont les coordonnees selon le grand axe et le petit axe | 
|---|
|  | 284 | | et teta = angle(x,A), le resultat subit ensuite une rotation d'angle teta. | 
|---|
|  | 285 | | - La matrice des covariances C des variables A,B est: | 
|---|
|  | 286 | |   | sa^2   0   | | 
|---|
|  | 287 | |   |            |  et det(C) = (1-ro^2)*sa^2*sb^2 | 
|---|
|  | 288 | |   |  0    sb^2 | | 
|---|
|  | 289 | | - La distribution x,y resultante est: | 
|---|
|  | 290 | | N*exp[-0.5*{[(dx/sx)^2-2*ro/(sx*sy)*dx*dy+(dy/sy)^2]/(1-ro^2)}] | 
|---|
|  | 291 | | ou N est donne dans NormCo et sx,sy,ro sont calcules a partir | 
|---|
|  | 292 | | de sa,sc,teta (voir fonctions paramga ou gaparam). La matrice des | 
|---|
|  | 293 | | covariances des variables x,y est donnee dans la fonction NormCo. | 
|---|
|  | 294 | -- | 
|---|
|  | 295 | */ | 
|---|
|  | 296 | void NormGau(double *x,double *y | 
|---|
|  | 297 | ,double mx,double my,double sa,double sb,double teta) | 
|---|
|  | 298 | { | 
|---|
|  | 299 | double c,s,X,Y; | 
|---|
|  | 300 |  | 
|---|
|  | 301 | LAB10: | 
|---|
|  | 302 | s = drand01(); | 
|---|
|  | 303 | if ( s == 0. ) goto LAB10; | 
|---|
|  | 304 | s = sqrt(-2.*log(s)); | 
|---|
|  | 305 | c = DeuxPi * drand01(); | 
|---|
|  | 306 |  | 
|---|
|  | 307 | X = sa*s*cos(c); | 
|---|
|  | 308 | Y = sb*s*sin(c); | 
|---|
|  | 309 |  | 
|---|
|  | 310 | c = cos(teta); s = sin(teta); | 
|---|
|  | 311 | *x = mx + c*X - s*Y; | 
|---|
|  | 312 | *y = my + s*X + c*Y; | 
|---|
|  | 313 | } | 
|---|
|  | 314 |  | 
|---|
|  | 315 | /*==========================================================================*/ | 
|---|
|  | 316 | /* | 
|---|
|  | 317 | ++ | 
|---|
|  | 318 | int NormCo(double *x,double *y,double mx,double my,double sx,double sy,double ro) | 
|---|
|  | 319 | Tirage de 2 nombres aleatoires x et y distribues sur une gaussienne 2D | 
|---|
|  | 320 | de centre (mx,my), de coefficient de correlation rho (ro) et telle que | 
|---|
|  | 321 | les sigmas finals des variables x et y soient sx,sy (ce sont | 
|---|
|  | 322 | les valeurs des distributions marginales des variables aleatoires x et y | 
|---|
|  | 323 | c'est a dire les sigmas des projections x et y de l'histogramme 2D | 
|---|
|  | 324 | de la gaussienne). Retourne 0 si ok. | 
|---|
|  | 325 | -- | 
|---|
|  | 326 | */ | 
|---|
|  | 327 | /* | 
|---|
|  | 328 | ++ | 
|---|
|  | 329 | | - La densite de probabilite (normalisee a 1) sur laquelle on tire est: | 
|---|
|  | 330 | |   N*exp[-0.5*{[(dx/sx)^2-2*ro/(sx*sy)*dx*dy+(dy/sy)^2]/(1-ro^2)}] | 
|---|
|  | 331 | |     avec dx = x-mx, dy = y-my et N = 1/[2Pi*sx*sy*sqrt(1-ro^2)] | 
|---|
|  | 332 | | - Dans ce cas la distribution marginale est (ex en X): | 
|---|
|  | 333 | |   1/(sqrt(2Pi)*sx) * exp[-0.5*{dx^2/sx^2}] | 
|---|
|  | 334 | | - La matrice des covariances C des variables x,y est: | 
|---|
|  | 335 | |   |   sx^2      ro*sx*sy | | 
|---|
|  | 336 | |   |                      |  et det(C) = (1-ro^2)*sx^2*sy^2 | 
|---|
|  | 337 | |   | ro*sx*sy      sy^2   | | 
|---|
|  | 338 | | - La matrice inverse C^(-1) est: | 
|---|
|  | 339 | |   |   1/sx^2      -ro/(sx*sy) | | 
|---|
|  | 340 | |   |                           | * 1/(1-ro^2) | 
|---|
|  | 341 | |   | -ro/(sx*sy)      1/sy^2   | | 
|---|
|  | 342 | -- | 
|---|
|  | 343 | */ | 
|---|
|  | 344 | /* | 
|---|
|  | 345 | ++ | 
|---|
|  | 346 | | - Remarque: | 
|---|
|  | 347 | | le sigma que l'on obtient quand on fait une coupe de la gaussienne 2D | 
|---|
|  | 348 | | en y=0 (ou x=0) est: SX0(y=0) = sx*sqrt(1-ro^2) different de sx | 
|---|
|  | 349 | |                      SY0(x=0) = sy*sqrt(1-ro^2) different de sy | 
|---|
|  | 350 | | La distribution qui correspond a des sigmas SX0,SY0 | 
|---|
|  | 351 | | pour les coupes en y=0,x=0 de la gaussienne 2D serait: | 
|---|
|  | 352 | |   N*exp[-0.5*{ (dx/SX0)^2-2*ro/(SX0*SY0)*dx*dy+(dy/SY0)^2 }] | 
|---|
|  | 353 | | avec N = sqrt(1-ro^2)/(2Pi*SX0*SY0) et les variances | 
|---|
|  | 354 | | des variables x,y sont toujours | 
|---|
|  | 355 | |  sx=SX0/sqrt(1-ro^2), sy=SY0/sqrt(1-ro^2) | 
|---|
|  | 356 | -- | 
|---|
|  | 357 | */ | 
|---|
|  | 358 | int NormCo(double *x,double *y | 
|---|
|  | 359 | ,double mx,double my,double sx,double sy,double ro) | 
|---|
|  | 360 | { | 
|---|
|  | 361 | double a,b,sa; | 
|---|
|  | 362 | if( ro <= -1. || ro >= 1. ) return(1); | 
|---|
|  | 363 | LAB10: | 
|---|
|  | 364 | b = drand01(); | 
|---|
|  | 365 | if ( b == 0. ) goto LAB10; | 
|---|
|  | 366 | b = sqrt(-2.*log(b)); | 
|---|
|  | 367 | a = DeuxPi * drand01(); | 
|---|
|  | 368 | sa = sin(a); | 
|---|
|  | 369 |  | 
|---|
|  | 370 | *x = mx + sx*b*(sqrt(1.-ro*ro)*cos(a)+ro*sa); | 
|---|
|  | 371 | *y = my + sy*b*sa; | 
|---|
|  | 372 |  | 
|---|
|  | 373 | return(0); | 
|---|
|  | 374 | } | 
|---|
|  | 375 |  | 
|---|
|  | 376 | /*==========================================================================*/ | 
|---|
|  | 377 | /* | 
|---|
|  | 378 | ++ | 
|---|
|  | 379 | Titre Exemple d'utilisation des aleatoires avec initialisation. | 
|---|
|  | 380 | -- | 
|---|
|  | 381 | */ | 
|---|
|  | 382 | /* | 
|---|
|  | 383 | ++ | 
|---|
|  | 384 | |   #include "nbrandom.h" | 
|---|
|  | 385 | | | 
|---|
|  | 386 | |   void main() { | 
|---|
|  | 387 | |   long i,ini=123456789; | 
|---|
|  | 388 | |   unsigned short seed[3]; | 
|---|
|  | 389 | | | 
|---|
|  | 390 | |   printf(" 1./ ==> test nitialisation par un long\n"); | 
|---|
|  | 391 | |   Ini_Ranf_Quick(ini,1); | 
|---|
|  | 392 | |   for(i=0;i<10;i++) printf("%d  -> %f\n",i,ranf01()); | 
|---|
|  | 393 | -- | 
|---|
|  | 394 | */ | 
|---|
|  | 395 | /* | 
|---|
|  | 396 | ++ | 
|---|
|  | 397 | | | 
|---|
|  | 398 | |   printf("\n 2./ ==> test initialisation par tableau de 3 unsigned short\n"); | 
|---|
|  | 399 | |   Ini_Ranf_Quick(ini,1); | 
|---|
|  | 400 | |   for(i=0;i<5;i++) printf("%d  -> %f\n",i,ranf01()); | 
|---|
|  | 401 | |   Get_Ranf(seed,1); | 
|---|
|  | 402 | |   for(i=5;i<10;i++) printf("%d  -> %f\n",i,ranf01()); | 
|---|
|  | 403 | |   Ini_Ranf(seed,1); | 
|---|
|  | 404 | |   for(i=5;i<10;i++) printf("%d  -> %f\n",i,ranf01()); | 
|---|
|  | 405 | |   Get_Ranf(seed,1); | 
|---|
|  | 406 | -- | 
|---|
|  | 407 | */ | 
|---|
|  | 408 | /* | 
|---|
|  | 409 | ++ | 
|---|
|  | 410 | | | 
|---|
|  | 411 | |   printf("\n 3./ ==> test initialisation automatique\n"); | 
|---|
|  | 412 | |   Auto_Ini_Ranf(2); | 
|---|
|  | 413 | |   for(i=0;i<5;i++) printf("%d  -> %f\n",i,ranf01()); | 
|---|
|  | 414 | |   i=0; while(i<10000000) i++; | 
|---|
|  | 415 | |   Auto_Ini_Ranf(2); | 
|---|
|  | 416 | |   for(i=0;i<5;i++) printf("%d  -> %f\n",i,ranf01()); | 
|---|
|  | 417 | |   i=0; while(i<10000000) i++; | 
|---|
|  | 418 | |   Auto_Ini_Ranf(2); | 
|---|
|  | 419 | |   for(i=0;i<5;i++) printf("%d  -> %f\n",i,ranf01()); | 
|---|
|  | 420 | |   } | 
|---|
|  | 421 | -- | 
|---|
|  | 422 | */ | 
|---|
|  | 423 | /* | 
|---|
|  | 424 | ++ | 
|---|
|  | 425 | |    1./ ==> test initialisation par un long | 
|---|
|  | 426 | |   Ini_Ranf_Quick: 123456789 | 
|---|
|  | 427 | |   0  -> 0.052468 | 
|---|
|  | 428 | |   1  -> 0.025444 | 
|---|
|  | 429 | |   2  -> 0.099272 | 
|---|
|  | 430 | |   3  -> 0.436130 | 
|---|
|  | 431 | |   4  -> 0.327740 | 
|---|
|  | 432 | |   5  -> 0.821202 | 
|---|
|  | 433 | |   6  -> 0.560493 | 
|---|
|  | 434 | |   7  -> 0.018157 | 
|---|
|  | 435 | |   8  -> 0.872758 | 
|---|
|  | 436 | |   9  -> 0.652496 | 
|---|
|  | 437 | -- | 
|---|
|  | 438 | */ | 
|---|
|  | 439 | /* | 
|---|
|  | 440 | ++ | 
|---|
|  | 441 | | | 
|---|
|  | 442 | |    2./ ==> test initialisation par tableau de 3 unsigned short | 
|---|
|  | 443 | |   Ini_Ranf_Quick: 123456789 | 
|---|
|  | 444 | |   0  -> 0.052468 | 
|---|
|  | 445 | |   1  -> 0.025444 | 
|---|
|  | 446 | |   2  -> 0.099272 | 
|---|
|  | 447 | |   3  -> 0.436130 | 
|---|
|  | 448 | |   4  -> 0.327740 | 
|---|
|  | 449 | -- | 
|---|
|  | 450 | */ | 
|---|
|  | 451 | /* | 
|---|
|  | 452 | ++ | 
|---|
|  | 453 | |   Get_Ranf: 36117 51106 21478 | 
|---|
|  | 454 | |   5  -> 0.821202 | 
|---|
|  | 455 | |   6  -> 0.560493 | 
|---|
|  | 456 | |   7  -> 0.018157 | 
|---|
|  | 457 | |   8  -> 0.872758 | 
|---|
|  | 458 | |   9  -> 0.652496 | 
|---|
|  | 459 | -- | 
|---|
|  | 460 | */ | 
|---|
|  | 461 | /* | 
|---|
|  | 462 | ++ | 
|---|
|  | 463 | |   Ini_Ranf: 36117 51106 21478 | 
|---|
|  | 464 | |   5  -> 0.821202 | 
|---|
|  | 465 | |   6  -> 0.560493 | 
|---|
|  | 466 | |   7  -> 0.018157 | 
|---|
|  | 467 | |   8  -> 0.872758 | 
|---|
|  | 468 | |   9  -> 0.652496 | 
|---|
|  | 469 | |   Get_Ranf: 16576 62373 42761 | 
|---|
|  | 470 | -- | 
|---|
|  | 471 | */ | 
|---|
|  | 472 | /* | 
|---|
|  | 473 | ++ | 
|---|
|  | 474 | | | 
|---|
|  | 475 | |    3./ ==> test initialisation automatique | 
|---|
|  | 476 | |   Auto_Ini_Ranf: date 887117206 s 868138 10^-6 sec seed=826006868: | 
|---|
|  | 477 | |   ... njours=10267 nj23=9 buf=826006868.13800001 | 
|---|
|  | 478 | |   Ini_Ranf_Quick: 826006868 | 
|---|
|  | 479 | |   0  -> 0.798860 | 
|---|
|  | 480 | |   1  -> 0.342478 | 
|---|
|  | 481 | |   2  -> 0.401300 | 
|---|
|  | 482 | |   3  -> 0.442912 | 
|---|
|  | 483 | |   4  -> 0.170912 | 
|---|
|  | 484 | -- | 
|---|
|  | 485 | */ | 
|---|
|  | 486 | /* | 
|---|
|  | 487 | ++ | 
|---|
|  | 488 | |   Auto_Ini_Ranf: date 887117207 s 188779 10^-6 sec seed=826007188: | 
|---|
|  | 489 | |   ... njours=10267 nj23=9 buf=826007188.77900004 | 
|---|
|  | 490 | |   Ini_Ranf_Quick: 826007188 | 
|---|
|  | 491 | |   0  -> 0.455599 | 
|---|
|  | 492 | |   1  -> 0.811427 | 
|---|
|  | 493 | |   2  -> 0.703880 | 
|---|
|  | 494 | |   3  -> 0.409569 | 
|---|
|  | 495 | |   4  -> 0.390399 | 
|---|
|  | 496 | -- | 
|---|
|  | 497 | */ | 
|---|
|  | 498 | /* | 
|---|
|  | 499 | ++ | 
|---|
|  | 500 | |   Auto_Ini_Ranf: date 887117207 s 489750 10^-6 sec seed=826007489: | 
|---|
|  | 501 | |   ... njours=10267 nj23=9 buf=826007489.75 | 
|---|
|  | 502 | |   Ini_Ranf_Quick: 826007489 | 
|---|
|  | 503 | |   0  -> 0.567094 | 
|---|
|  | 504 | |   1  -> 0.893156 | 
|---|
|  | 505 | |   2  -> 0.975995 | 
|---|
|  | 506 | |   3  -> 0.531331 | 
|---|
|  | 507 | |   4  -> 0.834354 | 
|---|
|  | 508 | -- | 
|---|
|  | 509 | */ | 
|---|
|  | 510 | /*==========================================================================*/ | 
|---|
|  | 511 |  | 
|---|
|  | 512 | /*==========================================================================*/ | 
|---|
|  | 513 | /* | 
|---|
|  | 514 | ++ | 
|---|
|  | 515 | Module        Tirages aleatoires selon une fonction (C) | 
|---|
|  | 516 | Lib   LibsUtil | 
|---|
|  | 517 | include       nbrandom.h | 
|---|
|  | 518 | -- | 
|---|
|  | 519 | */ | 
|---|
|  | 520 | /* | 
|---|
|  | 521 | ++ | 
|---|
|  | 522 | TIREALEA *init_tirage_alea(int nbin,double xmin,double xmax,double (*fonc) (double)) | 
|---|
|  | 523 | Initialise la structure qui va permettre le tirage aleatoire | 
|---|
|  | 524 | d'un nombre compris entre xmin et xmax selon la | 
|---|
|  | 525 | distribution fonc (histo de nbin bins) | 
|---|
|  | 526 | -- | 
|---|
|  | 527 | */ | 
|---|
|  | 528 | TIREALEA *init_tirage_alea(int nbin,double xmin,double xmax,double (*fonc) (double)) | 
|---|
|  | 529 | { | 
|---|
|  | 530 | int sof,i; | 
|---|
|  | 531 | double x; | 
|---|
|  | 532 | struct tirage_alea *t; | 
|---|
|  | 533 |  | 
|---|
|  | 534 | if ( xmax-xmin<0.) return(NULL); | 
|---|
|  | 535 |  | 
|---|
|  | 536 | if(nbin<=3) nbin=50; | 
|---|
|  | 537 |  | 
|---|
|  | 538 | sof = sizeof(struct tirage_alea); | 
|---|
|  | 539 | if( (t = (struct tirage_alea*)malloc(sof) ) == NULL ) { | 
|---|
|  | 540 | printf("impossible d'allouer *tirage_alea par malloc \n"); | 
|---|
|  | 541 | return(NULL); | 
|---|
|  | 542 | } | 
|---|
|  | 543 |  | 
|---|
|  | 544 | t->Nbin=nbin; t->Min=xmin; t->Max=xmax; t->Lbin=(xmax-xmin) /nbin; | 
|---|
|  | 545 |  | 
|---|
|  | 546 | sof = nbin * sizeof(double); | 
|---|
|  | 547 | if( (t->Tab = (double*)malloc(sof) ) == NULL ) { | 
|---|
|  | 548 | printf("impossible d'allouer *tirage_alea.Tab par malloc \n"); | 
|---|
|  | 549 | return(NULL); | 
|---|
|  | 550 | } | 
|---|
|  | 551 |  | 
|---|
|  | 552 | x = xmin + .5*t->Lbin; | 
|---|
|  | 553 | t->Tab[0] =  fonc(x); | 
|---|
|  | 554 | for(i=1;i<nbin;i++) { | 
|---|
|  | 555 | x = xmin + (i+.5)*t->Lbin; | 
|---|
|  | 556 | t->Tab[i] = t->Tab[i-1] + fonc(x); | 
|---|
|  | 557 | } | 
|---|
|  | 558 |  | 
|---|
|  | 559 | for(i=0;i<nbin-1;i++)  t->Tab[i] /= t->Tab[nbin-1]; | 
|---|
|  | 560 | t->Tab[nbin-1] = 1.; | 
|---|
|  | 561 |  | 
|---|
|  | 562 | return(t); | 
|---|
|  | 563 | } | 
|---|
|  | 564 |  | 
|---|
|  | 565 | /*==========================================================================*/ | 
|---|
|  | 566 | /* | 
|---|
|  | 567 | ++ | 
|---|
|  | 568 | double tirage_alea( TIREALEA *alea ) | 
|---|
|  | 569 | tirage aleatoire d'un nombre compris entre xmin et xmax | 
|---|
|  | 570 | selon la fonction fonc (cf init_tirage_alea). | 
|---|
|  | 571 | -- | 
|---|
|  | 572 | */ | 
|---|
|  | 573 | double tirage_alea( TIREALEA *alea ) | 
|---|
|  | 574 | { | 
|---|
|  | 575 | int i,ibin = -1; | 
|---|
|  | 576 | double z,t1,t2,x1,x2,t; | 
|---|
|  | 577 |  | 
|---|
|  | 578 | z=drand01(); | 
|---|
|  | 579 | /* protections z<=0 ou z>=1 */ | 
|---|
|  | 580 | if( z <= 0. ) return ( alea->Min ); | 
|---|
|  | 581 | if( z >= 1. ) return ( alea->Max ); | 
|---|
|  | 582 | /* cas z <= tab[0] */ | 
|---|
|  | 583 | if(z <= alea->Tab[0]) { | 
|---|
|  | 584 | t = alea->Min + (alea->Lbin/2.)/alea->Tab[0] * z; | 
|---|
|  | 585 | return (t); | 
|---|
|  | 586 | } | 
|---|
|  | 587 |  | 
|---|
|  | 588 | /* recherche du premier bin plus grand que z */ | 
|---|
|  | 589 | for(i=0;i<alea->Nbin;i++) { | 
|---|
|  | 590 | ibin=i; | 
|---|
|  | 591 | if ( z < alea->Tab[i] ) break; | 
|---|
|  | 592 | } | 
|---|
|  | 593 |  | 
|---|
|  | 594 | /* extrapolation pour trouver la valeur du tirage aleatoire */ | 
|---|
|  | 595 | if( ibin == alea->Nbin-1 ) ibin--; | 
|---|
|  | 596 | t1=alea->Tab[ibin]; | 
|---|
|  | 597 | x1 = alea->Min + (ibin+0.5) * alea->Lbin; | 
|---|
|  | 598 | t2=alea->Tab[ibin+1]; | 
|---|
|  | 599 | x2 = x1 + alea->Lbin; | 
|---|
|  | 600 | t = x1 + (x2-x1)/(t2-t1) *(z-t1); | 
|---|
|  | 601 | if ( t < alea->Min ) t = alea->Min; | 
|---|
|  | 602 | if ( t > alea->Max ) t = alea->Max; | 
|---|
|  | 603 | return(t); | 
|---|
|  | 604 | } | 
|---|
|  | 605 |  | 
|---|
|  | 606 | /*==========================================================================*/ | 
|---|
|  | 607 | /* | 
|---|
|  | 608 | ++ | 
|---|
|  | 609 | int end_tirage_alea( TIREALEA *alea ) | 
|---|
|  | 610 | De-allocation de la structure qui a permis le tirage aleatoire. | 
|---|
|  | 611 | -- | 
|---|
|  | 612 | */ | 
|---|
|  | 613 | int end_tirage_alea( TIREALEA *alea ) | 
|---|
|  | 614 | { | 
|---|
|  | 615 | if ( alea != NULL ) { free(alea); return(0);} | 
|---|
|  | 616 | else return(-1); | 
|---|
|  | 617 | } | 
|---|