📄 dcdflib.c
字号:
//****************************************************************************80//// Purpose:// // BETA_PSER uses a power series expansion to evaluate IX(A,B)(X).//// Discussion://// BETA_PSER is used when B <= 1 or B*X <= 0.7.//// Parameters://// Input, double *A, *B, the parameters.//// Input, double *X, the point where the function// is to be evaluated.//// Input, double *EPS, the tolerance.//// Output, double BETA_PSER, the approximate value of IX(A,B)(X).//{ static double bpser,a0,apb,b0,c,n,sum,t,tol,u,w,z; static int i,m; bpser = 0.0e0; if(*x == 0.0e0) return bpser;//// COMPUTE THE FACTOR X**A/(A*BETA(A,B))// a0 = fifdmin1(*a,*b); if(a0 < 1.0e0) goto S10; z = *a*log(*x)-beta_log(a,b); bpser = exp(z)/ *a; goto S100;S10: b0 = fifdmax1(*a,*b); if(b0 >= 8.0e0) goto S90; if(b0 > 1.0e0) goto S40;//// PROCEDURE FOR A0 .LT. 1 AND B0 .LE. 1// bpser = pow(*x,*a); if(bpser == 0.0e0) return bpser; apb = *a+*b; if(apb > 1.0e0) goto S20; z = 1.0e0+gam1(&apb); goto S30;S20: u = *a+*b-1.e0; z = (1.0e0+gam1(&u))/apb;S30: c = (1.0e0+gam1(a))*(1.0e0+gam1(b))/z; bpser *= (c*(*b/apb)); goto S100;S40://// PROCEDURE FOR A0 .LT. 1 AND 1 .LT. B0 .LT. 8// u = gamma_ln1 ( &a0 ); m = ( int ) ( b0 - 1.0e0 ); if(m < 1) goto S60; c = 1.0e0; for ( i = 1; i <= m; i++ ) { b0 -= 1.0e0; c *= (b0/(a0+b0)); } u = log(c)+u;S60: z = *a*log(*x)-u; b0 -= 1.0e0; apb = a0+b0; if(apb > 1.0e0) goto S70; t = 1.0e0+gam1(&apb); goto S80;S70: u = a0+b0-1.e0; t = (1.0e0+gam1(&u))/apb;S80: bpser = exp(z)*(a0/ *a)*(1.0e0+gam1(&b0))/t; goto S100;S90://// PROCEDURE FOR A0 .LT. 1 AND B0 .GE. 8// u = gamma_ln1 ( &a0 ) + algdiv ( &a0, &b0 ); z = *a*log(*x)-u; bpser = a0/ *a*exp(z);S100: if(bpser == 0.0e0 || *a <= 0.1e0**eps) return bpser;//// COMPUTE THE SERIES// sum = n = 0.0e0; c = 1.0e0; tol = *eps/ *a;S110: n += 1.0e0; c *= ((0.5e0+(0.5e0-*b/n))**x); w = c/(*a+n); sum += w; if(fabs(w) > tol) goto S110; bpser *= (1.0e0+*a*sum); return bpser;}//****************************************************************************80double beta_rcomp ( double *a, double *b, double *x, double *y )//****************************************************************************80//// Purpose:// // BETA_RCOMP evaluates X**A * Y**B / Beta(A,B).//// Parameters://// Input, double *A, *B, the parameters of the Beta function.// A and B should be nonnegative.//// Input, double *X, *Y, define the numerator of the fraction.//// Output, double BETA_RCOMP, the value of X**A * Y**B / Beta(A,B).//{ static double Const = .398942280401433e0; static double brcomp,a0,apb,b0,c,e,h,lambda,lnx,lny,t,u,v,x0,y0,z; static int i,n;//// CONST = 1/SQRT(2*PI)// static double T1,T2; brcomp = 0.0e0; if(*x == 0.0e0 || *y == 0.0e0) return brcomp; a0 = fifdmin1(*a,*b); if(a0 >= 8.0e0) goto S130; if(*x > 0.375e0) goto S10; lnx = log(*x); T1 = -*x; lny = alnrel(&T1); goto S30;S10: if(*y > 0.375e0) goto S20; T2 = -*y; lnx = alnrel(&T2); lny = log(*y); goto S30;S20: lnx = log(*x); lny = log(*y);S30: z = *a*lnx+*b*lny; if(a0 < 1.0e0) goto S40; z -= beta_log(a,b); brcomp = exp(z); return brcomp;S40://// PROCEDURE FOR A .LT. 1 OR B .LT. 1// b0 = fifdmax1(*a,*b); if(b0 >= 8.0e0) goto S120; if(b0 > 1.0e0) goto S70;//// ALGORITHM FOR B0 .LE. 1// brcomp = exp(z); if(brcomp == 0.0e0) return brcomp; apb = *a+*b; if(apb > 1.0e0) goto S50; z = 1.0e0+gam1(&apb); goto S60;S50: u = *a+*b-1.e0; z = (1.0e0+gam1(&u))/apb;S60: c = (1.0e0+gam1(a))*(1.0e0+gam1(b))/z; brcomp = brcomp*(a0*c)/(1.0e0+a0/b0); return brcomp;S70://// ALGORITHM FOR 1 .LT. B0 .LT. 8// u = gamma_ln1 ( &a0 ); n = ( int ) ( b0 - 1.0e0 ); if(n < 1) goto S90; c = 1.0e0; for ( i = 1; i <= n; i++ ) { b0 -= 1.0e0; c *= (b0/(a0+b0)); } u = log(c)+u;S90: z -= u; b0 -= 1.0e0; apb = a0+b0; if(apb > 1.0e0) goto S100; t = 1.0e0+gam1(&apb); goto S110;S100: u = a0+b0-1.e0; t = (1.0e0+gam1(&u))/apb;S110: brcomp = a0*exp(z)*(1.0e0+gam1(&b0))/t; return brcomp;S120://// ALGORITHM FOR B0 .GE. 8// u = gamma_ln1 ( &a0 ) + algdiv ( &a0, &b0 ); brcomp = a0*exp(z-u); return brcomp;S130://// PROCEDURE FOR A .GE. 8 AND B .GE. 8// if(*a > *b) goto S140; h = *a/ *b; x0 = h/(1.0e0+h); y0 = 1.0e0/(1.0e0+h); lambda = *a-(*a+*b)**x; goto S150;S140: h = *b/ *a; x0 = 1.0e0/(1.0e0+h); y0 = h/(1.0e0+h); lambda = (*a+*b)**y-*b;S150: e = -(lambda/ *a); if(fabs(e) > 0.6e0) goto S160; u = rlog1(&e); goto S170;S160: u = e-log(*x/x0);S170: e = lambda/ *b; if(fabs(e) > 0.6e0) goto S180; v = rlog1(&e); goto S190;S180: v = e-log(*y/y0);S190: z = exp(-(*a*u+*b*v)); brcomp = Const*sqrt(*b*x0)*z*exp(-bcorr(a,b)); return brcomp;}//****************************************************************************80double beta_rcomp1 ( int *mu, double *a, double *b, double *x, double *y )//****************************************************************************80//// Purpose:// // BETA_RCOMP1 evaluates exp(MU) * X**A * Y**B / Beta(A,B).//// Parameters://// Input, int MU, ?//// Input, double A, B, the parameters of the Beta function.// A and B should be nonnegative.//// Input, double X, Y, ?//// Output, double BETA_RCOMP1, the value of// exp(MU) * X**A * Y**B / Beta(A,B).//{ static double Const = .398942280401433e0; static double brcmp1,a0,apb,b0,c,e,h,lambda,lnx,lny,t,u,v,x0,y0,z; static int i,n;//// CONST = 1/SQRT(2*PI)// static double T1,T2,T3,T4; a0 = fifdmin1(*a,*b); if(a0 >= 8.0e0) goto S130; if(*x > 0.375e0) goto S10; lnx = log(*x); T1 = -*x; lny = alnrel(&T1); goto S30;S10: if(*y > 0.375e0) goto S20; T2 = -*y; lnx = alnrel(&T2); lny = log(*y); goto S30;S20: lnx = log(*x); lny = log(*y);S30: z = *a*lnx+*b*lny; if(a0 < 1.0e0) goto S40; z -= beta_log(a,b); brcmp1 = esum(mu,&z); return brcmp1;S40://// PROCEDURE FOR A .LT. 1 OR B .LT. 1// b0 = fifdmax1(*a,*b); if(b0 >= 8.0e0) goto S120; if(b0 > 1.0e0) goto S70;//// ALGORITHM FOR B0 .LE. 1// brcmp1 = esum(mu,&z); if(brcmp1 == 0.0e0) return brcmp1; apb = *a+*b; if(apb > 1.0e0) goto S50; z = 1.0e0+gam1(&apb); goto S60;S50: u = *a+*b-1.e0; z = (1.0e0+gam1(&u))/apb;S60: c = (1.0e0+gam1(a))*(1.0e0+gam1(b))/z; brcmp1 = brcmp1*(a0*c)/(1.0e0+a0/b0); return brcmp1;S70://// ALGORITHM FOR 1 .LT. B0 .LT. 8// u = gamma_ln1 ( &a0 ); n = ( int ) ( b0 - 1.0e0 ); if(n < 1) goto S90; c = 1.0e0; for ( i = 1; i <= n; i++ ) { b0 -= 1.0e0; c *= (b0/(a0+b0)); } u = log(c)+u;S90: z -= u; b0 -= 1.0e0; apb = a0+b0; if(apb > 1.0e0) goto S100; t = 1.0e0+gam1(&apb); goto S110;S100: u = a0+b0-1.e0; t = (1.0e0+gam1(&u))/apb;S110: brcmp1 = a0*esum(mu,&z)*(1.0e0+gam1(&b0))/t; return brcmp1;S120://// ALGORITHM FOR B0 .GE. 8// u = gamma_ln1 ( &a0 ) + algdiv ( &a0, &b0 ); T3 = z-u; brcmp1 = a0*esum(mu,&T3); return brcmp1;S130://// PROCEDURE FOR A .GE. 8 AND B .GE. 8// if(*a > *b) goto S140; h = *a/ *b; x0 = h/(1.0e0+h); y0 = 1.0e0/(1.0e0+h); lambda = *a-(*a+*b)**x; goto S150;S140: h = *b/ *a; x0 = 1.0e0/(1.0e0+h); y0 = h/(1.0e0+h); lambda = (*a+*b)**y-*b;S150: e = -(lambda/ *a); if(fabs(e) > 0.6e0) goto S160; u = rlog1(&e); goto S170;S160: u = e-log(*x/x0);S170: e = lambda/ *b; if(fabs(e) > 0.6e0) goto S180; v = rlog1(&e); goto S190;S180: v = e-log(*y/y0);S190: T4 = -(*a*u+*b*v); z = esum(mu,&T4); brcmp1 = Const*sqrt(*b*x0)*z*exp(-bcorr(a,b)); return brcmp1;}//****************************************************************************80double beta_up ( double *a, double *b, double *x, double *y, int *n, double *eps )//****************************************************************************80//// Purpose:// // BETA_UP evaluates IX(A,B) - IX(A+N,B) where N is a positive integer.//// Parameters://// Input, double *A, *B, the parameters of the function.// A and B should be nonnegative.//// Input, double *X, *Y, ?//// Input, int *N, ?//// Input, double *EPS, the tolerance.//// Output, double BETA_UP, the value of IX(A,B) - IX(A+N,B).//{ static int K1 = 1; static int K2 = 0; static double bup,ap1,apb,d,l,r,t,w; static int i,k,kp1,mu,nm1;//// OBTAIN THE SCALING FACTOR EXP(-MU) AND// EXP(MU)*(X**A*Y**B/BETA(A,B))/A// apb = *a+*b; ap1 = *a+1.0e0; mu = 0; d = 1.0e0; if(*n == 1 || *a < 1.0e0) goto S10; if(apb < 1.1e0*ap1) goto S10; mu = ( int ) fabs ( exparg(&K1) ); k = ( int ) exparg ( &K2 ); if(k < mu) mu = k; t = mu; d = exp(-t);S10: bup = beta_rcomp1 ( &mu, a, b, x, y ) / *a; if(*n == 1 || bup == 0.0e0) return bup; nm1 = *n-1; w = d;//// LET K BE THE INDEX OF THE MAXIMUM TERM// k = 0; if(*b <= 1.0e0) goto S50; if(*y > 1.e-4) goto S20; k = nm1; goto S30;S20: r = (*b-1.0e0)**x/ *y-*a; if(r < 1.0e0) goto S50; t = ( double ) nm1; k = nm1; if ( r < t ) k = ( int ) r;S30://// ADD THE INCREASING TERMS OF THE SERIES// for ( i = 1; i <= k; i++ ) { l = i-1; d = (apb+l)/(ap1+l)**x*d; w += d; } if(k == nm1) goto S70;S50://// ADD THE REMAINING TERMS OF THE SERIES// kp1 = k+1; for ( i = kp1; i <= nm1; i++ ) { l = i-1; d = (apb+l)/(ap1+l)**x*d; w += d; if(d <= *eps*w) goto S70; }S70://// TERMINATE THE PROCEDURE// bup *= w; return bup;}//****************************************************************************80***void binomial_cdf_values ( int *n_data, int *a, double *b, int *x, double *fx )//****************************************************************************80***//// Purpose: //// BINOMIAL_CDF_VALUES returns some values of the binomial CDF.//// Discussion://// CDF(X)(A,B) is the probability of at most X successes in A trials,// given that the probability of success on a single trial is B.//// Modified://// 31 May 2004//// Author://// John Burkardt//// Reference://// Milton Abramowitz and Irene Stegun,// Handbook of Mathematical Functions,// US Department of Commerce, 1964.//// Daniel Zwillinger,// CRC Standard Mathematical Tables and Formulae,// 30th Edition, CRC Press, 1996, pages 651-652.//// 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, int *A, double *B, the parameters of the function.//// Output, int *X, the argument of the function.//// Output, double *FX, the value of the function.//{# define N_MAX 17 int a_vec[N_MAX] = { 2, 2, 2, 2, 2, 4, 4, 4, 4, 10, 10, 10, 10, 10, 10, 10, 10 }; double b_vec[N_MAX] = { 0.05E+00, 0.05E+00, 0.05E+00, 0.50E+00, 0.50E+00, 0.25E+00, 0.25E+00, 0.25E+00, 0.25E+00, 0.05E+00, 0.10E+00, 0.15E+00, 0.20E+00, 0.25E+00, 0.30E+00, 0.40E+00, 0.50E+00 }; double fx_vec[N_MAX] = { 0.9025E+00, 0.9975E+00, 1.0000E+00, 0.2500E+00, 0.7500E+00, 0.3164E+00, 0.7383E+00, 0.9492E+00, 0.9961E+00, 0.9999E+00, 0.9984E+00, 0.9901E+00, 0.9672E+00, 0.9219E+00, 0.8497E+00, 0.6331E+00, 0.3770E+00 }; int x_vec[N_MAX] = { 0, 1, 2, 0, 1, 0, 1, 2,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -