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

📄 randlib.c

📁 雷达工具箱
💻 C
📖 第 1 页 / 共 5 页
字号:
*/    if(fy-u*fy <= py*exp(px-fx)) return ignpoi;S50:/*     STEP E. EXPONENTIAL SAMPLE - SEXPO(IR) FOR STANDARD EXPONENTIAL             DEVIATE E AND SAMPLE T FROM THE LAPLACE 'HAT'             (IF T <= -.6744 THEN PK < FK FOR ALL MU >= 10.)*/    e = sexpo();    u = ranf();    u += (u-1.0);    t = 1.8+fsign(e,u);    if(t <= -0.6744) goto S50;    ignpoi = (long) (mu+s*t);    fk = (float)ignpoi;    difmuk = mu-fk;/*             'SUBROUTINE' F IS CALLED (KFLAG=1 FOR CORRECT RETURN)*/    kflag = 1;    goto S70;S60:/*     STEP H. HAT ACCEPTANCE (E IS REPEATED ON REJECTION)*/    if(c*fabs(u) > py*exp(px+e)-fy*exp(fx+e)) goto S50;    return ignpoi;S70:/*     STEP F. 'SUBROUTINE' F. CALCULATION OF PX,PY,FX,FY.             CASE IGNPOI .LT. 10 USES FACTORIALS FROM TABLE FACT*/    if(ignpoi >= 10) goto S80;    px = -mu;    py = pow(mu,(double)ignpoi)/ *(fact+ignpoi);    goto S110;S80:/*             CASE IGNPOI .GE. 10 USES POLYNOMIAL APPROXIMATION             A0-A7 FOR ACCURACY WHEN ADVISABLE             .8333333E-1=1./12.  .3989423=(2*PI)**(-.5)*/    del = 8.333333E-2/fk;    del -= (4.8*del*del*del);    v = difmuk/fk;    if(fabs(v) <= 0.25) goto S90;    px = fk*log(1.0+v)-difmuk-del;    goto S100;S90:    px = fk*v*v*(((((((a7*v+a6)*v+a5)*v+a4)*v+a3)*v+a2)*v+a1)*v+a0)-del;S100:    py = 0.3989423/sqrt(fk);S110:    x = (0.5-difmuk)/s;    xx = x*x;    fx = -0.5*xx;    fy = omega*(((c3*xx+c2)*xx+c1)*xx+c0);    if(kflag <= 0) goto S40;    goto S60;S120:/*     C A S E  B. (START NEW TABLE AND CALCULATE P0 IF NECESSARY)     JJV changed MUPREV assignment to initial value*/    muprev = -1.0E37;    if(mu == muold) goto S130;/* JJV added argument checker here */    if(mu >= 0.0) goto S125;    fprintf(stderr,"MU < 0 in IGNPOI: MU %16.6E\n",mu);    fputs("Abort\n",stderr);    mexErrMsgTxt("Error: exit code 1"); /* exit(1); */S125:    muold = mu;    m = max(1L,(long) (mu));    l = 0;    p = exp(-mu);    q = p0 = p;S130:/*     STEP U. UNIFORM SAMPLE FOR INVERSION METHOD*/    u = ranf();    ignpoi = 0;    if(u <= p0) return ignpoi;/*     STEP T. TABLE COMPARISON UNTIL THE END PP(L) OF THE             PP-TABLE OF CUMULATIVE POISSON PROBABILITIES             (0.458=PP(9) FOR MU=10)*/    if(l == 0) goto S150;    j = 1;    if(u > 0.458) j = min(l,m);    for(k=j; k<=l; k++) {        if(u <= *(pp+k-1)) goto S180;    }    if(l == 35) goto S130;S150:/*     STEP C. CREATION OF NEW POISSON PROBABILITIES P             AND THEIR CUMULATIVES Q=PP(K)*/    l += 1;    for(k=l; k<=35; k++) {        p = p*mu/(float)k;        q += p;        *(pp+k-1) = q;        if(u <= q) goto S170;    }    l = 35;    goto S130;S170:    l = k;S180:    ignpoi = k;    return ignpoi;}long ignuin(long low,long high)/***********************************************************************     long ignuin(long low,long high)               GeNerate Uniform INteger                              Function     Generates an integer uniformly distributed between LOW and HIGH.                              Arguments     low --> Low bound (inclusive) on integer value to be generated     high --> High bound (inclusive) on integer value to be generated                              Note     If (HIGH-LOW) > 2,147,483,561 prints error message on * unit and     stops the program.**********************************************************************     IGNLGI generates integers between 1 and 2147483562     MAXNUM is 1 less than maximum generable value*/{#define maxnum 2147483561Lstatic long ignuin,ign,maxnow,range,ranp1;    if(!(low > high)) goto S10;    fputs(" low > high in ignuin - ABORT\n",stderr);    mexErrMsgTxt("Error: exit code 1"); /* exit(1); */S10:    range = high-low;    if(!(range > maxnum)) goto S20;    fputs(" high - low too large in ignuin - ABORT\n",stderr);    mexErrMsgTxt("Error: exit code 1"); /* exit(1); */S20:    if(!(low == high)) goto S30;    ignuin = low;    return ignuin;S30:/*     Number to be generated should be in range 0..RANGE     Set MAXNOW so that the number of integers in 0..MAXNOW is an     integral multiple of the number in 0..RANGE*/    ranp1 = range+1;    maxnow = maxnum/ranp1*ranp1;S40:    ign = ignlgi()-1;    if(!(ign <= maxnow)) goto S40;    ignuin = low+ign%ranp1;    return ignuin;#undef maxnum#undef err1#undef err2}long lennob( char *str )/* Returns the length of str ignoring trailing blanks but not other white space.*/{long i, i_nb;for (i=0, i_nb= -1L; *(str+i); i++)    if ( *(str+i) != ' ' ) i_nb = i;return (i_nb+1);    }long mltmod(long a,long s,long m)/***********************************************************************     long mltmod(long a,long s,long m)                    Returns (A*S) MOD M     This is a transcription from Pascal to Fortran of routine     MULtMod_Decompos from the paper     L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package     with Splitting Facilities." ACM Transactions on Mathematical     Software, 17:98-111 (1991)                              Arguments     a, s, m  -->***********************************************************************/{#define h 32768Lstatic long mltmod,a0,a1,k,p,q,qh,rh;/*     H = 2**((b-2)/2) where b = 32 because we are using a 32 bit      machine. On a different machine recompute H*/    if(!(a <= 0 || a >= m || s <= 0 || s >= m)) goto S10;    fputs(" a, m, s out of order in mltmod - ABORT!\n",stderr);    fprintf(stderr," a = %12ld s = %12ld m = %12ld\n",a,s,m);    fputs(" mltmod requires: 0 < a < m; 0 < s < m\n",stderr);    mexErrMsgTxt("Error: exit code 1"); /* exit(1); */S10:    if(!(a < h)) goto S20;    a0 = a;    p = 0;    goto S120;S20:    a1 = a/h;    a0 = a-h*a1;    qh = m/h;    rh = m-h*qh;    if(!(a1 >= h)) goto S50;    a1 -= h;    k = s/qh;    p = h*(s-k*qh)-k*rh;S30:    if(!(p < 0)) goto S40;    p += m;    goto S30;S40:    goto S60;S50:    p = 0;S60:/*     P = (A2*S*H)MOD M*/    if(!(a1 != 0)) goto S90;    q = m/a1;    k = s/q;    p -= (k*(m-a1*q));    if(p > 0) p -= m;    p += (a1*(s-k*q));S70:    if(!(p < 0)) goto S80;    p += m;    goto S70;S90:S80:    k = p/qh;/*     P = ((A2*H + A1)*S)MOD M*/    p = h*(p-k*qh)-k*rh;S100:    if(!(p < 0)) goto S110;    p += m;    goto S100;S120:S110:    if(!(a0 != 0)) goto S150;/*     P = ((A2*H + A1)*H*S)MOD M*/    q = m/a0;    k = s/q;    p -= (k*(m-a0*q));    if(p > 0) p -= m;    p += (a0*(s-k*q));S130:    if(!(p < 0)) goto S140;    p += m;    goto S130;S150:S140:    mltmod = p;    return mltmod;#undef h}void phrtsd(char* phrase,long *seed1,long *seed2)/***********************************************************************     void phrtsd(char* phrase,long *seed1,long *seed2)               PHRase To SeeDs                              Function     Uses a phrase (character string) to generate two seeds for the RGN     random number generator.                              Arguments     phrase --> Phrase to be used for random number generation           seed1 <-- First seed for generator                             seed2 <-- Second seed for generator                                                      Note     Trailing blanks are eliminated before the seeds are generated.     Generated seed values will fall in the range 1..2^30     (1..1,073,741,824)***********************************************************************/{static char table[] ="abcdefghijklmnopqrstuvwxyz\ABCDEFGHIJKLMNOPQRSTUVWXYZ\0123456789\!@#$%^&*()_+[];:'\\\"<>?,./";long ix;static long twop30 = 1073741824L;static long shift[5] = {    1L,64L,4096L,262144L,16777216L};static long i,ichr,j,lphr,values[5];extern long lennob(char *str);    *seed1 = 1234567890L;    *seed2 = 123456789L;    lphr = lennob(phrase);     if(lphr < 1) return;    for(i=0; i<=(lphr-1); i++) {	for (ix=0; table[ix]; ix++) if (*(phrase+i) == table[ix]) break; 	/* JJV added ix++; to bring index in line with fortran's index*/	ix++;        if (!table[ix]) ix = 0;        ichr = ix % 64;        if(ichr == 0) ichr = 63;        for(j=1; j<=5; j++) {            *(values+j-1) = ichr-j;            if(*(values+j-1) < 1) *(values+j-1) += 63;        }        for(j=1; j<=5; j++) {            *seed1 = ( *seed1+*(shift+j-1)**(values+j-1) ) % twop30;            *seed2 = ( *seed2+*(shift+j-1)**(values+6-j-1) )  % twop30;        }    }}float ranf(void)/***********************************************************************     float ranf(void)                RANDom number generator as a Function     Returns a random floating point number from a uniform distribution     over 0 - 1 (endpoints of this interval are not returned) using the     current generator     This is a transcription from Pascal to Fortran of routine     Uniform_01 from the paper     L'Ecuyer, P. and Cote, S. "Implementing a Random Number Package     with Splitting Facilities." ACM Transactions on Mathematical     Software, 17:98-111 (1991)***********************************************************************/{static float ranf;/*     4.656613057E-10 is 1/M1  M1 is set in a data statement in IGNLGI      and is currently 2147483563. If M1 changes, change this also.*/    ranf = ignlgi()*4.656613057E-10;    return ranf;}void setgmn(float *meanv,float *covm,long p,float *parm)/***********************************************************************     void setgmn(float *meanv,float *covm,long p,float *parm)            SET Generate Multivariate Normal random deviate                              Function      Places P, MEANV, and the Cholesky factoriztion of COVM      in GENMN.                              Arguments     meanv --> Mean vector of multivariate normal distribution.     covm   <--> (Input) Covariance   matrix    of  the  multivariate                 normal distribution                 (Output) Destroyed on output     p     --> Dimension of the normal, or length of MEANV.     parm <-- Array of parameters needed to generate multivariate norma                deviates (P, MEANV and Cholesky decomposition of                COVM).                1 : 1                - P                2 : P + 1            - MEANV                P+2 : P*(P+3)/2 + 1  - Cholesky decomposition of COVM               Needed dimension is (p*(p+3)/2 + 1)***********************************************************************/{extern void spofa(float *a,long lda,long n,long *info);static long T1;static long i,icount,info,j,D2,D3,D4,D5;    T1 = p*(p+3)/2+1;/*     TEST THE INPUT*/    if(!(p <= 0)) goto S10;    fputs("P nonpositive in SETGMN\n",stderr);    fprintf(stderr,"Value of P: %12ld\n",p);    mexErrMsgTxt("Error: exit code 1"); /* exit(1); */S10:    *parm = p;/*     PUT P AND MEANV INTO PARM*/    for(i=2,D2=1,D3=(p+1-i+D2)/D2; D3>0; D3--,i+=D2) *(parm+i-1) = *(meanv+i-2);/*      Cholesky decomposition to find A s.t. trans(A)*(A) = COVM*/    spofa(covm,p,p,&info);    if(!(info != 0)) goto S30;    fputs(" COVM not positive definite in SETGMN\n",stderr);    mexErrMsgTxt("Error: exit code 1"); /* exit(1); */S30:    icount = p+1;

⌨️ 快捷键说明

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