⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 randomlib.c

📁 Fit a multivariate gaussian mixture by a cross-entropy method. Cross-Entropy is a powerfull tool to
💻 C
📖 第 1 页 / 共 5 页
字号:
    if(s+2.609438 >= 5.0*z) goto S70;/*     Step 3*/    t = log(z);    if(s > t) goto S70;/* *   Step 4 * *    JJV added checker to see if log(alpha/(b+w)) will  *    JJV overflow.  If so, we count the log as -INF, and *    JJV consequently evaluate conditional as true, i.e. *    JJV the algorithm rejects the trial and starts over *    JJV May not need this here since alpha > 2.0 */    if(alpha/(b+w) < minlog) goto S40;    if(r+alpha*log(alpha/(b+w)) < t) goto S40;S70:/*     Step 5*/    if(!(aa == a)) goto S80;    genbet = w/(b+w);    goto S90;S80:    genbet = b/(b+w);S90:    goto S230;S100:/*     Algorithm BC     Initialize*/    if(qsame) goto S110;    a = max(aa,bb);    b = min(aa,bb);    alpha = a+b;    beta = 1.0/b;    delta = 1.0+a-b;    k1 = delta*(1.38889E-2+4.16667E-2*b)/(a*beta-0.777778);    k2 = 0.25+(0.5+0.25/delta)*b;S110:S120:    u1 = ranf();/*     Step 1*/    u2 = ranf();    if(u1 >= 0.5) goto S130;/*     Step 2*/    y = u1*u2;    z = u1*y;    if(0.25*u2+z-y >= k1) goto S120;    goto S170;S130:/*     Step 3*/    z = pow(u1,2.0)*u2;    if(!(z <= 0.25)) goto S160;    v = beta*log(u1/(1.0-u1));/* *    JJV instead of checking v > expmax at top, I will check *    JJV if a < 1, then check the appropriate values */    if(a > 1.0) goto S135;/*   JJV a < 1 so it can help out if exp(v) would overflow */    if(v > expmax) goto S132;    w = a*exp(v);    goto S200;S132:    w = v + log(a);    if(w > expmax) goto S140;    w = exp(w);    goto S200;S135:/*   JJV in this case a > 1 */    if(v > expmax) goto S140;    w = exp(v);    if(w > infnty/a) goto S140;    w *= a;    goto S200;S140:    w = infnty;    goto S200;/* * JJV old code *    if(!(v > expmax)) goto S140; *    w = infnty; *    goto S150; *S140: *    w = a*exp(v); *S150: *    goto S200; */S160:    if(z >= k2) goto S120;S170:/*     Step 4     Step 5*/    v = beta*log(u1/(1.0-u1));/*   JJV same kind of checking as above */    if(a > 1.0) goto S175;/* JJV a < 1 so it can help out if exp(v) would overflow */    if(v > expmax) goto S172;    w = a*exp(v);    goto S190;S172:    w = v + log(a);    if(w > expmax) goto S180;    w = exp(w);    goto S190;S175:/* JJV in this case a > 1.0 */    if(v > expmax) goto S180;    w = exp(v);    if(w > infnty/a) goto S180;    w *= a;    goto S190;S180:    w = infnty;/* *   JJV old code *    if(!(v > expmax)) goto S180; *    w = infnty; *    goto S190; *S180: *    w = a*exp(v); */S190:/* * JJV here we also check to see if log overlows; if so, we treat it * JJV as -INF, which means condition is true, i.e. restart */    if(alpha/(b+w) < minlog) goto S120;    if(alpha*(log(alpha/(b+w))+v)-1.3862944 < log(z)) goto S120;S200:/*     Step 6*/    if(!(a == aa)) goto S210;    genbet = w/(b+w);    goto S220;S210:    genbet = b/(b+w);S230:S220:    return genbet;#undef expmax#undef infnty#undef minlog}float genchi(float df)/***********************************************************************     float genchi(float df)                Generate random value of CHIsquare variable                              Function     Generates random deviate from the distribution of a chisquare     with DF degrees of freedom random variable.                              Arguments     df --> Degrees of freedom of the chisquare            (Must be positive)                                     Method     Uses relation between chisquare and gamma.***********************************************************************/{static float genchi;    if(!(df <= 0.0)) goto S10;        mexPrintf(" Value of DF: %16.6E\n",df);    mexErrMsgTxt("Problem generating chi-squared deviate");    exit(1);S10:/* * JJV changed the code to call SGAMMA directly *    genchi = 2.0*gengam(1.0,df/2.0); <- OLD */    genchi = 2.0*sgamma(df/2.0);    return genchi;}float genexp(float av)/***********************************************************************     float genexp(float av)                    GENerate EXPonential random deviate                              Function     Generates a single random deviate from an exponential     distribution with mean AV.                              Arguments     av --> The mean of the exponential distribution from which            a random deviate is to be generated.        JJV (av >= 0)                              Method     Renames SEXPO from TOMS as slightly modified by BWB to use RANF     instead of SUNIF.     For details see:               Ahrens, J.H. and Dieter, U.               Computer Methods for Sampling From the               Exponential and Normal Distributions.               Comm. ACM, 15,10 (Oct. 1972), 873 - 882.***********************************************************************/{static float genexp;/* JJV added check that av >= 0 */    if(av >= 0.0) goto S10;     mexPrintf(" Value of AV: %16.6E\n",av);    mexErrMsgTxt("Problem generating exponential deviate");    exit(1);S10:    genexp = sexpo()*av;    return genexp;}float genf(float dfn,float dfd)/***********************************************************************     float genf(float dfn,float dfd)                GENerate random deviate from the F distribution                              Function     Generates a random deviate from the F (variance ratio)     distribution with DFN degrees of freedom in the numerator     and DFD degrees of freedom in the denominator.                              Arguments     dfn --> Numerator degrees of freedom             (Must be positive)     dfd --> Denominator degrees of freedom             (Must be positive)                              Method     Directly generates ratio of chisquare variates***********************************************************************/{static float genf,xden,xnum;    if(!(dfn <= 0.0 || dfd <= 0.0)) goto S10;     mexPrintf(" DFN value: %16.6E DFD value: %16.6E\n",dfn,dfd);    mexErrMsgTxt("Problem generating F deviate");    exit(1);S10:/* * JJV changed this to call SGAMMA directly * *     GENF = ( GENCHI( DFN ) / DFN ) / ( GENCHI( DFD ) / DFD ) *   xnum = genchi(dfn)/dfn; <- OLD *   xden = genchi(dfd)/dfd; <- OLD */    xnum = 2.0*sgamma(dfn/2.0)/dfn;    xden = 2.0*sgamma(dfd/2.0)/dfd;/* * JJV changed constant to prevent underflow at compile time. *   if(!(xden <= 9.999999999998E-39*xnum)) goto S20; */    if(!(xden <= 1.0E-37*xnum)) goto S20;        mexPrintf(" Numerator %16.6E Denominator %16.6E\n",xnum,xden);    mexErrMsgTxt("Problem generating F-deviate");   /* * JJV changed next 2 lines to reflect constant change above in the * JJV truncated value returned. *   fputs(" GENF returning 1.0E38\n",stderr); *   genf = 1.0E38; */       genf = 1.0E37;    goto S30;S20:    genf = xnum/xden;S30:    return genf;}float gengam(float a,float r)/***********************************************************************     float gengam(float a,float r)           GENerates random deviates from GAMma distribution                              Function     Generates random deviates from the gamma distribution whose     density is          (A**R)/Gamma(R) * X**(R-1) * Exp(-A*X)                              Arguments     a --> Location parameter of Gamma distribution     JJV   (a > 0)     r --> Shape parameter of Gamma distribution     JJV   (r > 0)                              Method     Renames SGAMMA from TOMS as slightly modified by BWB to use RANF     instead of SUNIF.     For details see:               (Case R >= 1.0)               Ahrens, J.H. and Dieter, U.               Generating Gamma Variates by a               Modified Rejection Technique.               Comm. ACM, 25,1 (Jan. 1982), 47 - 54.     Algorithm GD     JJV altered following to reflect argument ranges               (Case 0.0 < R < 1.0)               Ahrens, J.H. and Dieter, U.               Computer Methods for Sampling from Gamma,               Beta, Poisson and Binomial Distributions.               Computing, 12 (1974), 223-246/     Adapted algorithm GS.***********************************************************************/{static float gengam;/* JJV added argument checker */    if(a > 0.0 && r > 0.0) goto S10;       mexPrintf(" A value: %16.6E R value: %16.6E\n",a,r);    mexErrMsgTxt("Problem generating gamma deviate");        exit(1);S10:    gengam = sgamma(r);    gengam /= a;    return gengam;}void genmn(float *parm,float *x,float *work)/***********************************************************************     void genmn(float *parm,float *x,float *work)              GENerate Multivariate Normal random deviate                              Arguments     parm --> Parameters needed to generate multivariate normal               deviates (MEANV and Cholesky decomposition of               COVM). Set by a previous call to SETGMN.               1 : 1                - size of deviate, P               2 : P + 1            - mean vector               P+2 : P*(P+3)/2 + 1  - upper half of cholesky                                       decomposition of cov matrix     x    <-- Vector deviate generated.     work <--> Scratch array                              Method     1) Generate P independent standard normal deviates - Ei ~ N(0,1)     2) Using Cholesky decomposition find A s.t. trans(A)*A = COVM     3) trans(A)E + MEANV ~ N(MEANV,COVM)***********************************************************************/{static long i,icount,j,p,D1,D2,D3,D4;static float ae;    p = (long) (*parm);/*     Generate P independent normal deviates - WORK ~ N(0,1)*/    for(i=1; i<=p; i++) *(work+i-1) = snorm();    for(i=1,D3=1,D4=(p-i+D3)/D3; D4>0; D4--,i+=D3) {/*     PARM (P+2 : P*(P+3)/2 + 1) contains A, the Cholesky      decomposition of the desired covariance matrix.          trans(A)(1,1) = PARM(P+2)          trans(A)(2,1) = PARM(P+3)          trans(A)(2,2) = PARM(P+2+P)          trans(A)(3,1) = PARM(P+4)          trans(A)(3,2) = PARM(P+3+P)          trans(A)(3,3) = PARM(P+2-1+2P)  ...     trans(A)*WORK + MEANV ~ N(MEANV,COVM)*/        icount = 0;        ae = 0.0;        for(j=1,D1=1,D2=(i-j+D1)/D1; D2>0; D2--,j+=D1) {            icount += (j-1);            ae += (*(parm+i+(j-1)*p-icount+p)**(work+j-1));        }        *(x+i-1) = ae+*(parm+i);    }}void genmul(long n,float *p,long ncat,long *ix)/***********************************************************************      void genmul(int n,float *p,int ncat,int *ix)     GENerate an observation from the MULtinomial distribution                              Arguments     N --> Number of events that will be classified into one of           the categories 1..NCAT     P --> Vector of probabilities.  P(i) is the probability that           an event will be classified into category i.  Thus, P(i)           must be [0,1]. Only the first NCAT-1 P(i) must be defined           since P(NCAT) is 1.0 minus the sum of the first           NCAT-1 P(i).     NCAT --> Number of categories.  Length of P and IX.     IX <-- Observation from multinomial distribution.  All IX(i)            will be nonnegative and their sum will be N.                              Method     Algorithm from page 559 of      Devroye, Luc      Non-Uniform Random Variate Generation.  Springer-Verlag,     New York, 1986. ***********************************************************************/{static float prob,ptot,sum;static long i,icat,ntot;    if(n < 0) ftnstop("N < 0 in GENMUL");    if(ncat <= 1) ftnstop("NCAT <= 1 in GENMUL");    ptot = 0.0F;    for(i=0; i<ncat-1; i++) {        if(*(p+i) < 0.0F) ftnstop("Some P(i) < 0 in GENMUL");        if(*(p+i) > 1.0F) ftnstop("Some P(i) > 1 in GENMUL");        ptot += *(p+i);    }    if(ptot > 0.99999F) ftnstop("Sum of P(i) > 1 in GENMUL");/*     Initialize variables*/    ntot = n;    sum = 1.0F;    for(i=0; i<ncat; i++) ix[i] = 0;/*     Generate the observation*/    for(icat=0; icat<ncat-1; icat++) {        prob = *(p+icat)/sum;        *(ix+icat) = ignbin(ntot,prob);        ntot -= *(ix+icat);	if(ntot <= 0) return;        sum -= *(p+icat);    }    *(ix+ncat-1) = ntot;/*     Finished*/    return;}float gennch(float df,float xnonc)/***********************************************************************     float gennch(float df,float xnonc)           Generate random value of Noncentral CHIsquare variable                              Function     Generates random deviate  from the  distribution  of a  noncentral     chisquare with DF degrees  of freedom and noncentrality  parameter     xnonc.                              Arguments     df --> Degrees of freedom of the chisquare            (Must be >= 1.0)     xnonc --> Noncentrality parameter of the chisquare               (Must be >= 0.0)                              Method     Uses fact that  noncentral chisquare  is  the  sum of a  chisquare

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -