/Users/huttone/Devel/sedflux-new/sedflux/trunk/ew/utils/eh_rand.c

Go to the documentation of this file.
00001 //---
00002 //
00003 // This file is part of sedflux.
00004 //
00005 // sedflux is free software; you can redistribute it and/or modify
00006 // it under the terms of the GNU General Public License as published by
00007 // the Free Software Foundation; either version 2 of the License, or
00008 // (at your option) any later version.
00009 //
00010 // sedflux is distributed in the hope that it will be useful,
00011 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00012 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00013 // GNU General Public License for more details.
00014 //
00015 // You should have received a copy of the GNU General Public License
00016 // along with sedflux; if not, write to the Free Software
00017 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00018 //
00019 //---
00020 
00021 #include <eh_utils.h>
00022 
00023 #define IA 16807
00024 #define IM 2147483647
00025 #define AM (1.0/IM)
00026 #define IQ 127773
00027 #define IR 2836
00028 #define MASK 123459876
00029 
00030 double eh_ran0(long *idum)
00031 {
00032         long k;
00033         double ans;
00034 
00035         *idum ^= MASK;
00036         k=(*idum)/IQ;
00037         *idum=IA*(*idum-k*IQ)-IR*k;
00038         if (*idum < 0) *idum += IM;
00039         ans=AM*(*idum);
00040         *idum ^= MASK;
00041         return ans;
00042 }
00043 #undef IA
00044 #undef IM
00045 #undef AM
00046 #undef IQ
00047 #undef IR
00048 #undef MASK
00049 
00050 #define IA 16807
00051 #define IM 2147483647
00052 #define AM (1.0/IM)
00053 #define IQ 127773
00054 #define IR 2836
00055 #define NTAB 32
00056 #define NDIV (1+(IM-1)/NTAB)
00057 #define EPS 1.2e-7
00058 #define RNMX (1.0-EPS)
00059 
00060 double eh_ran1(long *idum)
00061 {
00062         int j;
00063         long k;
00064         static long iy=0;
00065         static long iv[NTAB];
00066         double temp;
00067 
00068         if (*idum <= 0 || !iy) {
00069                 if (-(*idum) < 1) *idum=1;
00070                 else *idum = -(*idum);
00071                 for (j=NTAB+7;j>=0;j--) {
00072                         k=(*idum)/IQ;
00073                         *idum=IA*(*idum-k*IQ)-IR*k;
00074                         if (*idum < 0) *idum += IM;
00075                         if (j < NTAB) iv[j] = *idum;
00076                 }
00077                 iy=iv[0];
00078         }
00079         k=(*idum)/IQ;
00080         *idum=IA*(*idum-k*IQ)-IR*k;
00081         if (*idum < 0) *idum += IM;
00082         j=iy/NDIV;
00083         iy=iv[j];
00084         iv[j] = *idum;
00085         if ((temp=AM*iy) > RNMX) return RNMX;
00086         else return temp;
00087 }
00088 #undef IA
00089 #undef IM
00090 #undef AM
00091 #undef IQ
00092 #undef IR
00093 #undef NTAB
00094 #undef NDIV
00095 #undef EPS
00096 #undef RNMX
00097 
00098 #define IM1 2147483563
00099 #define IM2 2147483399
00100 #define AM (1.0/IM1)
00101 #define IMM1 (IM1-1)
00102 #define IA1 40014
00103 #define IA2 40692
00104 #define IQ1 53668
00105 #define IQ2 52774
00106 #define IR1 12211
00107 #define IR2 3791
00108 #define NTAB 32
00109 #define NDIV (1+IMM1/NTAB)
00110 #define EPS 1.2e-7
00111 #define RNMX (1.0-EPS)
00112 
00113 double eh_ran2(long *idum)
00114 {
00115         int j;
00116         long k;
00117         static long idum2=123456789;
00118         static long iy=0;
00119         static long iv[NTAB];
00120         double temp;
00121 
00122         if (*idum <= 0) {
00123                 if (-(*idum) < 1) *idum=1;
00124                 else *idum = -(*idum);
00125                 idum2=(*idum);
00126                 for (j=NTAB+7;j>=0;j--) {
00127                         k=(*idum)/IQ1;
00128                         *idum=IA1*(*idum-k*IQ1)-k*IR1;
00129                         if (*idum < 0) *idum += IM1;
00130                         if (j < NTAB) iv[j] = *idum;
00131                 }
00132                 iy=iv[0];
00133         }
00134         k=(*idum)/IQ1;
00135         *idum=IA1*(*idum-k*IQ1)-k*IR1;
00136         if (*idum < 0) *idum += IM1;
00137         k=idum2/IQ2;
00138         idum2=IA2*(idum2-k*IQ2)-k*IR2;
00139         if (idum2 < 0) idum2 += IM2;
00140         j=iy/NDIV;
00141         iy=iv[j]-idum2;
00142         iv[j] = *idum;
00143         if (iy < 1) iy += IMM1;
00144         if ((temp=AM*iy) > RNMX) return RNMX;
00145         else return temp;
00146 }
00147 #undef IM1
00148 #undef IM2
00149 #undef AM
00150 #undef IMM1
00151 #undef IA1
00152 #undef IA2
00153 #undef IQ1
00154 #undef IQ2
00155 #undef IR1
00156 #undef IR2
00157 #undef NTAB
00158 #undef NDIV
00159 #undef EPS
00160 #undef RNMX
00161 
00162 #define MBIG 1000000000
00163 #define MSEED 161803398
00164 #define MZ 0
00165 #define FAC (1.0/MBIG)
00166 
00167 double eh_ran3(long *idum)
00168 {
00169         static int inext,inextp;
00170         static long ma[56];
00171         static int iff=0;
00172         long mj,mk;
00173         int i,ii,k;
00174 
00175         if (*idum < 0 || iff == 0) {
00176                 iff=1;
00177                 mj=MSEED-(*idum < 0 ? -*idum : *idum);
00178                 mj %= MBIG;
00179                 ma[55]=mj;
00180                 mk=1;
00181                 for (i=1;i<=54;i++) {
00182                         ii=(21*i) % 55;
00183                         ma[ii]=mk;
00184                         mk=mj-mk;
00185                         if (mk < MZ) mk += MBIG;
00186                         mj=ma[ii];
00187                 }
00188                 for (k=1;k<=4;k++)
00189                         for (i=1;i<=55;i++) {
00190                                 ma[i] -= ma[1+(i+30) % 55];
00191                                 if (ma[i] < MZ) ma[i] += MBIG;
00192                         }
00193                 inext=0;
00194                 inextp=31;
00195                 *idum=1;
00196         }
00197         if (++inext == 56) inext=1;
00198         if (++inextp == 56) inextp=1;
00199         mj=ma[inext]-ma[inextp];
00200         if (mj < MZ) mj += MBIG;
00201         ma[inext]=mj;
00202         return mj*FAC;
00203 }
00204 #undef MBIG
00205 #undef MSEED
00206 #undef MZ
00207 #undef FAC
00208 
00209 double eh_ran4(long *idum)
00210 {
00211         void eh_psdes(unsigned long *lword, unsigned long *irword);
00212         unsigned long irword,itemp,lword;
00213         static long idums = 0;
00214 #if defined(vax) || defined(_vax_) || defined(__vax__) || defined(VAX)
00215         static unsigned long jflone = 0x00004080;
00216         static unsigned long jflmsk = 0xffff007f;
00217 #else
00218         static unsigned long jflone = 0x3f800000;
00219         static unsigned long jflmsk = 0x007fffff;
00220 #endif
00221 
00222         if (*idum < 0) {
00223                 idums = -(*idum);
00224                 *idum=1;
00225         }
00226         irword=(*idum);
00227         lword=idums;
00228         eh_psdes(&lword,&irword);
00229         itemp=jflone | (jflmsk & irword);
00230         ++(*idum);
00231         return (*(double *)&itemp)-1.0;
00232 }
00233 
00234 #define NITER 4
00235 
00236 void eh_psdes(unsigned long *lword, unsigned long *irword)
00237 {
00238         unsigned long i,ia,ib,iswap,itmph=0,itmpl=0;
00239         static unsigned long c1[NITER]={
00240                 0xbaa96887L, 0x1e17d32cL, 0x03bcdc3cL, 0x0f33d1b2L};
00241         static unsigned long c2[NITER]={
00242                 0x4b0f3b58L, 0xe874f0c3L, 0x6955c5a6L, 0x55a7ca46L};
00243 
00244         for (i=0;i<NITER;i++) {
00245                 ia=(iswap=(*irword)) ^ c1[i];
00246                 itmpl = ia & 0xffff;
00247                 itmph = ia >> 16;
00248                 ib=itmpl*itmpl+ ~(itmph*itmph);
00249                 *irword=(*lword) ^ (((ia = (ib >> 16) |
00250                         ((ib & 0xffff) << 16)) ^ c2[i])+itmpl*itmph);
00251                 *lword=iswap;
00252         }
00253 }
00254 #undef NITER
00255 
00256 #include <math.h>
00257 
00258 #define PI 3.14159265359
00259 
00260 // Return a random number between 0 and 1 using the pdf,
00261 //   p(x) = a*cos(x*a) ( a = pi/2 )
00262 double eh_cosdev(long *idum)
00263 {
00264    double n;
00265    
00266    n=(double)eh_ran1(idum);
00267    
00268    return asin(n)*2/PI;
00269 }
00270 
00271 #undef PI
00272 
00273 
00274 double eh_reject(double (*p)(double),double (*f)(double),double (*F)(double))
00275 {
00276    double eh_ran1(long *idum);
00277    double x, n;
00278    static long seed[1];
00279    
00280    x = (*F)((double)eh_ran1(seed));
00281    n = (double)eh_ran1(seed)*(*f)(x);
00282    
00283    if ( n > (*p)(x) )
00284       x = eh_reject(p,f,F);
00285    
00286    return x;
00287 
00288 }
00289 
00290 #include <math.h>
00291 
00292 double eh_expdev(long *idum)
00293 {
00294    double eh_ran1(long *idum);
00295    double dum;
00296    
00297    do
00298       dum=eh_ran1(idum);
00299    while (dum == 0.0 );
00300    
00301    return -log(dum);
00302 }
00303 
00304 #include <math.h>
00305 
00306 double eh_gasdev(long *idum)
00307 {
00308    double eh_ran1(long *idum);
00309    static int iset=0;
00310    static double gset;
00311    double fac,rsq, v1, v2;
00312    
00313    if ( iset == 0 )
00314    {
00315       do
00316       {
00317          v1 = 2.0*eh_ran1(idum)-1.0;
00318          v2 = 2.0*eh_ran1(idum)-1.0;
00319          rsq = v1*v1 +v2*v2;
00320       } while ( rsq >= 1.0 || rsq == 0.0 );
00321       fac = sqrt(-2.0*log(rsq)/rsq);
00322       gset=v1*fac;
00323       iset=1;
00324       return v2*fac;
00325    }
00326    else
00327    {
00328       iset = 0;
00329       return gset;
00330    }
00331 }
00332 
00333 #include <math.h>
00334 
00335 // Picks a random number with a pdf,
00336 //        f(x) = a^x     ( |a| <= 1 )
00337 //
00338 double eh_powdev(double a,long *idum)
00339 {
00340    double eh_ran2(long *idum);
00341    double dum;
00342    
00343    do
00344       dum=eh_ran2(idum);
00345    while (dum == 1.0 );
00346    
00347    return log(1-dum)/log(a);
00348 }
00349 
00350 double eh_maxpowdev(double a,double n,long *idum)
00351 {
00352    double eh_ran2(long *idum);
00353    double dum;
00354    
00355    do
00356       dum=eh_ran2(idum);
00357    while (dum == 1.0 );
00358    
00359    return log(1-pow(dum,1./n))/log(a);
00360 }
00361 
00379 double eh_rand_exponential( GRand *rand , double mu )
00380 {
00381    double dum;
00382 
00383    do
00384    {
00385       dum = g_rand_double( rand );
00386    }
00387    while ( dum == 0. );
00388 
00389    return - mu * log( dum );
00390 }
00391 
00402 double eh_rand_max_exponential( GRand *rand , double mu , double n )
00403 {
00404    double dum;
00405 
00406    do
00407    {
00408       dum = g_rand_double( rand );
00409    }
00410    while ( pow(dum,1./n) == 1. );
00411 
00412 
00413    return - mu * log( 1 - pow(dum,1./n) );
00414 }
00415 
00431 double eh_log_normal( GRand* rand , double mu , double sigma )
00432 {
00433    return exp( eh_rand_normal(rand,mu,sigma) );
00434 }
00435 
00447 double eh_max_log_normal( GRand *rand , double mu , double sigma , double n )
00448 {
00449    double eh_ran2( long *idum);
00450    double dum;
00451 
00452    do
00453    {
00454 //      dum=eh_ran2(idum);
00455       dum = g_rand_double( rand );
00456 //      dum = ((double)random())/((double)G_MAXINT);
00457    }
00458    while ( fabs(2*(pow(dum,1./n)-.5)) >= 1.-1e-12 );
00459 
00460    return exp( eh_erf_inv( 2.*(pow(dum,1./n)-.5) )*sqrt(2)*sigma + mu );
00461 }
00462 
00479 double eh_rand_weibull( GRand *rand , double eta , double beta )
00480 {
00481    double dum;
00482 
00483    do
00484    {
00485       dum = g_rand_double( rand );
00486    }
00487    while ( dum == 0 );
00488 
00489    return eta*pow( -log(dum) , 1./beta );
00490 }
00491 
00503 double eh_rand_max_weibull( GRand *rand , double eta , double beta , double n )
00504 {
00505    double dum;
00506    double z;
00507    double ans;
00508 
00509    do
00510    {
00511       dum = g_rand_double( rand );
00512       z = pow( dum , 1./n );
00513    }
00514    while ( dum==1. );
00515 //   while ( fabs(z) >= 1. );
00516 
00517    if ( n<1. )
00518       ans = eta*pow( z*( 1 + .5*z*( 1 + .6666667*z ) ) , 1./beta );
00519 //      return b*pow( -( z*( 1. + z*( -.5 + z*(.33333  - .25*z))) ) , 1./a );
00520    else
00521       ans = eta*pow( -log( 1 - pow(dum,1./n) ) , 1./beta );
00522 
00523    return ans;
00524 }
00525 
00537 double eh_rand_user( GRand *rand , double *x , double *F , gssize len )
00538 {
00539    double ans, u = g_rand_double( rand );
00540    interpolate( F , x , len ,  &u , &ans , 1 );
00541    return ans;
00542 }
00543 
00559 double eh_rand_normal( GRand* rand , double mu , double sigma )
00560 {
00561    static gboolean iset=FALSE;
00562    static double gset;
00563    double fac,rsq, v1, v2;
00564 
00565    eh_require( sigma>0 );
00566    
00567    if ( iset == 0 )
00568    {
00569       do
00570       {
00571          if ( rand )
00572          {
00573             v1 = 2.0*g_rand_double( rand )-1.;
00574             v2 = 2.0*g_rand_double( rand )-1.;
00575          }
00576          else
00577          {
00578             v1 = 2.0*g_random_double( )-1.;
00579             v2 = 2.0*g_random_double( )-1.;
00580          }
00581          rsq = v1*v1 +v2*v2;
00582       } while ( rsq >= 1.0 || rsq == 0.0 );
00583       fac = sqrt(-2.0*log(rsq)/rsq);
00584       gset=v1*fac;
00585       iset=TRUE;
00586       return v2*fac*sigma+mu;
00587    }
00588    else
00589    {
00590       iset = FALSE;
00591       return gset*sigma+mu;
00592    }
00593 }
00594 
00595 double eh_get_fuzzy_dbl( double min , double max )
00596 {
00597    return g_random_double_range( min , max );
00598 }
00599 
00600 double eh_get_fuzzy_dbl_norm( double mean , double std )
00601 {
00602    return eh_rand_normal( NULL , mean , std );
00603 }
00604 
00605 double eh_get_fuzzy_dbl_log_norm( double mean , double std )
00606 {
00607    return eh_log_normal( NULL , mean , std );
00608 }
00609 
00610 gint32 eh_get_fuzzy_int( gint32 min , gint32 max )
00611 {
00612    return g_random_int_range( min , max );
00613 }
00614 
00615 /* @} */

Generated on Fri Jan 4 18:04:16 2008 for sedflux by  doxygen 1.5.2