📄 dcdflib.c
字号:
// was detected.//{ static double bm1,bp2n,cn,coef,dj,j,l,lnx,n2,nu,p,q,r,s,sum,t,t2,u,v,z; static int i,n,nm1; static double c[30],d[30],T1; bm1 = *b-0.5e0-0.5e0; nu = *a+0.5e0*bm1; if(*y > 0.375e0) goto S10; T1 = -*y; lnx = alnrel(&T1); goto S20;S10: lnx = log(*x);S20: z = -(nu*lnx); if(*b*z == 0.0e0) goto S70;//// COMPUTATION OF THE EXPANSION// SET R = EXP(-Z)*Z**B/GAMMA(B)// r = *b*(1.0e0+gam1(b))*exp(*b*log(z)); r *= (exp(*a*lnx)*exp(0.5e0*bm1*lnx)); u = algdiv(b,a)+*b*log(nu); u = r*exp(-u); if(u == 0.0e0) goto S70; gamma_rat1 ( b, &z, &r, &p, &q, eps ); v = 0.25e0*pow(1.0e0/nu,2.0); t2 = 0.25e0*lnx*lnx; l = *w/u; j = q/r; sum = j; t = cn = 1.0e0; n2 = 0.0e0; for ( n = 1; n <= 30; n++ ) { bp2n = *b+n2; j = (bp2n*(bp2n+1.0e0)*j+(z+bp2n+1.0e0)*t)*v; n2 += 2.0e0; t *= t2; cn /= (n2*(n2+1.0e0)); c[n-1] = cn; s = 0.0e0; if(n == 1) goto S40; nm1 = n-1; coef = *b-(double)n; for ( i = 1; i <= nm1; i++ ) { s += (coef*c[i-1]*d[n-i-1]); coef += *b; }S40: d[n-1] = bm1*cn+s/(double)n; dj = d[n-1]*j; sum += dj; if(sum <= 0.0e0) goto S70; if(fabs(dj) <= *eps*(sum+l)) goto S60; }S60://// ADD THE RESULTS TO W// *ierr = 0; *w += (u*sum); return;S70://// THE EXPANSION CANNOT BE COMPUTED// *ierr = 1; return;}//****************************************************************************80void beta_inc ( double *a, double *b, double *x, double *y, double *w, double *w1, int *ierr )//****************************************************************************80//// Purpose:// // BETA_INC evaluates the incomplete beta function IX(A,B).//// Author://// Alfred H Morris, Jr,// Naval Surface Weapons Center,// Dahlgren, Virginia.//// Parameters://// Input, double *A, *B, the parameters of the function.// A and B should be nonnegative.//// Input, double *X, *Y. X is the argument of the// function, and should satisy 0 <= X <= 1. Y should equal 1 - X.//// Output, double *W, *W1, the values of IX(A,B) and// 1-IX(A,B).//// Output, int *IERR, the error flag.// 0, no error was detected.// 1, A or B is negative;// 2, A = B = 0;// 3, X < 0 or 1 < X;// 4, Y < 0 or 1 < Y;// 5, X + Y /= 1;// 6, X = A = 0;// 7, Y = B = 0.//{ static int K1 = 1; static double a0,b0,eps,lambda,t,x0,y0,z; static int ierr1,ind,n; static double T2,T3,T4,T5;//// EPS IS A MACHINE DEPENDENT CONSTANT. EPS IS THE SMALLEST// NUMBER FOR WHICH 1.0 + EPS .GT. 1.0// eps = dpmpar ( &K1 ); *w = *w1 = 0.0e0; if(*a < 0.0e0 || *b < 0.0e0) goto S270; if(*a == 0.0e0 && *b == 0.0e0) goto S280; if(*x < 0.0e0 || *x > 1.0e0) goto S290; if(*y < 0.0e0 || *y > 1.0e0) goto S300; z = *x+*y-0.5e0-0.5e0; if(fabs(z) > 3.0e0*eps) goto S310; *ierr = 0; if(*x == 0.0e0) goto S210; if(*y == 0.0e0) goto S230; if(*a == 0.0e0) goto S240; if(*b == 0.0e0) goto S220; eps = fifdmax1(eps,1.e-15); if(fifdmax1(*a,*b) < 1.e-3*eps) goto S260; ind = 0; a0 = *a; b0 = *b; x0 = *x; y0 = *y; if(fifdmin1(a0,b0) > 1.0e0) goto S40;//// PROCEDURE FOR A0 .LE. 1 OR B0 .LE. 1// if(*x <= 0.5e0) goto S10; ind = 1; a0 = *b; b0 = *a; x0 = *y; y0 = *x;S10: if(b0 < fifdmin1(eps,eps*a0)) goto S90; if(a0 < fifdmin1(eps,eps*b0) && b0*x0 <= 1.0e0) goto S100; if(fifdmax1(a0,b0) > 1.0e0) goto S20; if(a0 >= fifdmin1(0.2e0,b0)) goto S110; if(pow(x0,a0) <= 0.9e0) goto S110; if(x0 >= 0.3e0) goto S120; n = 20; goto S140;S20: if(b0 <= 1.0e0) goto S110; if(x0 >= 0.3e0) goto S120; if(x0 >= 0.1e0) goto S30; if(pow(x0*b0,a0) <= 0.7e0) goto S110;S30: if(b0 > 15.0e0) goto S150; n = 20; goto S140;S40://// PROCEDURE FOR A0 .GT. 1 AND B0 .GT. 1// if(*a > *b) goto S50; lambda = *a-(*a+*b)**x; goto S60;S50: lambda = (*a+*b)**y-*b;S60: if(lambda >= 0.0e0) goto S70; ind = 1; a0 = *b; b0 = *a; x0 = *y; y0 = *x; lambda = fabs(lambda);S70: if(b0 < 40.0e0 && b0*x0 <= 0.7e0) goto S110; if(b0 < 40.0e0) goto S160; if(a0 > b0) goto S80; if(a0 <= 100.0e0) goto S130; if(lambda > 0.03e0*a0) goto S130; goto S200;S80: if(b0 <= 100.0e0) goto S130; if(lambda > 0.03e0*b0) goto S130; goto S200;S90://// EVALUATION OF THE APPROPRIATE ALGORITHM// *w = fpser(&a0,&b0,&x0,&eps); *w1 = 0.5e0+(0.5e0-*w); goto S250;S100: *w1 = apser(&a0,&b0,&x0,&eps); *w = 0.5e0+(0.5e0-*w1); goto S250;S110: *w = beta_pser(&a0,&b0,&x0,&eps); *w1 = 0.5e0+(0.5e0-*w); goto S250;S120: *w1 = beta_pser(&b0,&a0,&y0,&eps); *w = 0.5e0+(0.5e0-*w1); goto S250;S130: T2 = 15.0e0*eps; *w = beta_frac ( &a0,&b0,&x0,&y0,&lambda,&T2 ); *w1 = 0.5e0+(0.5e0-*w); goto S250;S140: *w1 = beta_up ( &b0, &a0, &y0, &x0, &n, &eps ); b0 += (double)n;S150: T3 = 15.0e0*eps; beta_grat (&b0,&a0,&y0,&x0,w1,&T3,&ierr1); *w = 0.5e0+(0.5e0-*w1); goto S250;S160: n = ( int ) b0; b0 -= (double)n; if(b0 != 0.0e0) goto S170; n -= 1; b0 = 1.0e0;S170: *w = beta_up ( &b0, &a0, &y0, &x0, &n, &eps ); if(x0 > 0.7e0) goto S180; *w += beta_pser(&a0,&b0,&x0,&eps); *w1 = 0.5e0+(0.5e0-*w); goto S250;S180: if(a0 > 15.0e0) goto S190; n = 20; *w += beta_up ( &a0, &b0, &x0, &y0, &n, &eps ); a0 += (double)n;S190: T4 = 15.0e0*eps; beta_grat ( &a0, &b0, &x0, &y0, w, &T4, &ierr1 ); *w1 = 0.5e0+(0.5e0-*w); goto S250;S200: T5 = 100.0e0*eps; *w = beta_asym ( &a0, &b0, &lambda, &T5 ); *w1 = 0.5e0+(0.5e0-*w); goto S250;S210://// TERMINATION OF THE PROCEDURE// if(*a == 0.0e0) goto S320;S220: *w = 0.0e0; *w1 = 1.0e0; return;S230: if(*b == 0.0e0) goto S330;S240: *w = 1.0e0; *w1 = 0.0e0; return;S250: if(ind == 0) return; t = *w; *w = *w1; *w1 = t; return;S260://// PROCEDURE FOR A AND B .LT. 1.E-3*EPS// *w = *b/(*a+*b); *w1 = *a/(*a+*b); return;S270://// ERROR RETURN// *ierr = 1; return;S280: *ierr = 2; return;S290: *ierr = 3; return;S300: *ierr = 4; return;S310: *ierr = 5; return;S320: *ierr = 6; return;S330: *ierr = 7; return;}//****************************************************************************80***void beta_inc_values ( int *n_data, double *a, double *b, double *x, double *fx )//****************************************************************************80***//// Purpose: //// BETA_INC_VALUES returns some values of the incomplete Beta function.//// Discussion://// The incomplete Beta function may be written//// BETA_INC(A,B,X) = Integral (0 to X) T**(A-1) * (1-T)**(B-1) dT// / Integral (0 to 1) T**(A-1) * (1-T)**(B-1) dT//// Thus,//// BETA_INC(A,B,0.0) = 0.0// BETA_INC(A,B,1.0) = 1.0//// Note that in Mathematica, the expressions://// BETA[A,B] = Integral (0 to 1) T**(A-1) * (1-T)**(B-1) dT// BETA[X,A,B] = Integral (0 to X) T**(A-1) * (1-T)**(B-1) dT//// and thus, to evaluate the incomplete Beta function requires://// BETA_INC(A,B,X) = BETA[X,A,B] / BETA[A,B]//// Modified://// 09 June 2004//// Author://// John Burkardt//// Reference://// Milton Abramowitz and Irene Stegun,// Handbook of Mathematical Functions,// US Department of Commerce, 1964.//// Karl Pearson,// Tables of the Incomplete Beta Function,// Cambridge University Press, 1968.//// Parameters://// Input/output, int *N_DATA. The user sets N_DATA to 0 before the// first call. On each call, the routine increments N_DATA by 1, and// returns the corresponding data; when there is no more data, the// output value of N_DATA will be 0 again.//// Output, double *A, *B, the parameters of the function.//// Output, double *X, the argument of the function.//// Output, double *FX, the value of the function.//{# define N_MAX 30 double a_vec[N_MAX] = { 0.5E+00, 0.5E+00, 0.5E+00, 1.0E+00, 1.0E+00, 1.0E+00, 1.0E+00, 1.0E+00, 2.0E+00, 2.0E+00, 2.0E+00, 2.0E+00, 2.0E+00, 2.0E+00, 2.0E+00, 2.0E+00, 2.0E+00, 5.5E+00, 10.0E+00, 10.0E+00, 10.0E+00, 10.0E+00, 20.0E+00, 20.0E+00, 20.0E+00, 20.0E+00, 20.0E+00, 30.0E+00, 30.0E+00, 40.0E+00 }; double b_vec[N_MAX] = { 0.5E+00, 0.5E+00, 0.5E+00, 0.5E+00, 0.5E+00, 0.5E+00, 0.5E+00, 1.0E+00, 2.0E+00, 2.0E+00, 2.0E+00, 2.0E+00, 2.0E+00, 2.0E+00, 2.0E+00, 2.0E+00, 2.0E+00, 5.0E+00, 0.5E+00, 5.0E+00, 5.0E+00, 10.0E+00, 5.0E+00, 10.0E+00, 10.0E+00, 20.0E+00, 20.0E+00, 10.0E+00, 10.0E+00, 20.0E+00 }; double fx_vec[N_MAX] = { 0.0637686E+00, 0.2048328E+00, 1.0000000E+00, 0.0E+00, 0.0050126E+00, 0.0513167E+00, 0.2928932E+00, 0.5000000E+00, 0.028E+00, 0.104E+00, 0.216E+00, 0.352E+00, 0.500E+00, 0.648E+00, 0.784E+00, 0.896E+00, 0.972E+00, 0.4361909E+00, 0.1516409E+00, 0.0897827E+00, 1.0000000E+00, 0.5000000E+00, 0.4598773E+00, 0.2146816E+00, 0.9507365E+00, 0.5000000E+00, 0.8979414E+00, 0.2241297E+00, 0.7586405E+00, 0.7001783E+00 }; double x_vec[N_MAX] = { 0.01E+00, 0.10E+00, 1.00E+00, 0.0E+00, 0.01E+00, 0.10E+00, 0.50E+00, 0.50E+00, 0.1E+00, 0.2E+00, 0.3E+00, 0.4E+00, 0.5E+00, 0.6E+00, 0.7E+00, 0.8E+00, 0.9E+00, 0.50E+00, 0.90E+00, 0.50E+00, 1.00E+00, 0.50E+00, 0.80E+00, 0.60E+00, 0.80E+00, 0.50E+00, 0.60E+00, 0.70E+00, 0.80E+00, 0.70E+00 }; if ( *n_data < 0 ) { *n_data = 0; } *n_data = *n_data + 1; if ( N_MAX < *n_data ) { *n_data = 0; *a = 0.0E+00; *b = 0.0E+00; *x = 0.0E+00; *fx = 0.0E+00; } else { *a = a_vec[*n_data-1]; *b = b_vec[*n_data-1]; *x = x_vec[*n_data-1]; *fx = fx_vec[*n_data-1]; } return;# undef N_MAX}//****************************************************************************80double beta_log ( double *a0, double *b0 )//****************************************************************************80//// Purpose://// BETA_LOG evaluates the logarithm of the beta function.//// Reference://// Armido DiDinato and Alfred Morris,// Algorithm 708: // Significant Digit Computation of the Incomplete Beta Function Ratios,// ACM Transactions on Mathematical Software, // Volume 18, 1993, pages 360-373.//// Parameters://// Input, double *A0, *B0, the parameters of the function.// A0 and B0 should be nonnegative.//// Output, double *BETA_LOG, the value of the logarithm// of the Beta function.//{ static double e = .918938533204673e0; static double value,a,b,c,h,u,v,w,z; static int i,n; static double T1; a = fifdmin1(*a0,*b0); b = fifdmax1(*a0,*b0); if(a >= 8.0e0) goto S100; if(a >= 1.0e0) goto S20;//// PROCEDURE WHEN A .LT. 1// if(b >= 8.0e0) goto S10; T1 = a+b; value = gamma_log ( &a )+( gamma_log ( &b )- gamma_log ( &T1 )); return value;S10: value = gamma_log ( &a )+algdiv(&a,&b); return value;S20://// PROCEDURE WHEN 1 .LE. A .LT. 8// if(a > 2.0e0) goto S40; if(b > 2.0e0) goto S30; value = gamma_log ( &a )+ gamma_log ( &b )-gsumln(&a,&b); return value;S30: w = 0.0e0; if(b < 8.0e0) goto S60; value = gamma_log ( &a )+algdiv(&a,&b); return value;S40://// REDUCTION OF A WHEN B .LE. 1000// if(b > 1000.0e0) goto S80; n = ( int ) ( a - 1.0e0 ); w = 1.0e0; for ( i = 1; i <= n; i++ ) { a -= 1.0e0; h = a/b; w *= (h/(1.0e0+h)); } w = log(w); if(b < 8.0e0) goto S60; value = w+ gamma_log ( &a )+algdiv(&a,&b); return value;S60://// REDUCTION OF B WHEN B .LT. 8// n = ( int ) ( b - 1.0e0 ); z = 1.0e0; for ( i = 1; i <= n; i++ ) { b -= 1.0e0; z *= (b/(a+b)); } value = w+log(z)+( gamma_log ( &a )+( gamma_log ( &b )-gsumln(&a,&b))); return value;S80://// REDUCTION OF A WHEN B .GT. 1000// n = ( int ) ( a - 1.0e0 ); w = 1.0e0; for ( i = 1; i <= n; i++ ) { a -= 1.0e0; w *= (a/(1.0e0+a/b)); } value = log(w)-(double)n*log(b)+( gamma_log ( &a )+algdiv(&a,&b)); return value;S100://// PROCEDURE WHEN A .GE. 8// w = bcorr(&a,&b); h = a/b; c = h/(1.0e0+h); u = -((a-0.5e0)*log(c)); v = b*alnrel(&h); if(u <= v) goto S110; value = -(0.5e0*log(b))+e+w-v-u; return value;S110: value = -(0.5e0*log(b))+e+w-u-v; return value;}//****************************************************************************80double beta_pser ( double *a, double *b, double *x, double *eps )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -