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

📄 dcdflib.c

📁 计算各种随机分布的密度函数
💻 C
📖 第 1 页 / 共 5 页
字号:
# include <cstdlib># include <iostream># include <iomanip># include <cmath># include <ctime>using namespace std;# include "dcdflib.H"//****************************************************************************80double algdiv ( double *a, double *b )//****************************************************************************80////  Purpose:// //    ALGDIV computes ln ( Gamma ( B ) / Gamma ( A + B ) ) when 8 <= B.////  Discussion:////    In this algorithm, DEL(X) is the function defined by////      ln ( Gamma(X) ) = ( X - 0.5 ) * ln ( X ) - X + 0.5 * ln ( 2 * PI ) //                      + DEL(X).////  Parameters:////    Input, double *A, *B, define the arguments.////    Output, double ALGDIV, the value of ln(Gamma(B)/Gamma(A+B)).//{  static double algdiv;  static double c;  static double c0 =  0.833333333333333e-01;  static double c1 = -0.277777777760991e-02;  static double c2 =  0.793650666825390e-03;  static double c3 = -0.595202931351870e-03;  static double c4 =  0.837308034031215e-03;  static double c5 = -0.165322962780713e-02;  static double d;  static double h;  static double s11;  static double s3;  static double s5;  static double s7;  static double s9;  static double t;  static double T1;  static double u;  static double v;  static double w;  static double x;  static double x2;  if ( *b <= *a )  {    h = *b / *a;    c = 1.0e0 / ( 1.0e0 + h );    x = h / ( 1.0e0 + h );    d = *a + ( *b - 0.5e0 );  }  else  {    h = *a / *b;    c = h / ( 1.0e0 + h );    x = 1.0e0 / ( 1.0e0 + h );    d = *b + ( *a - 0.5e0 );  }////  SET SN = (1 - X**N)/(1 - X)//  x2 = x * x;  s3 = 1.0e0 + ( x + x2 );  s5 = 1.0e0 + ( x + x2 * s3 );  s7 = 1.0e0 + ( x + x2 * s5 );  s9 = 1.0e0 + ( x + x2 * s7 );  s11 = 1.0e0 + ( x + x2 * s9 );////  SET W = DEL(B) - DEL(A + B)//  t = pow ( 1.0e0 / *b, 2.0 );  w = (((( c5 * s11  * t          + c4 * s9 ) * t         + c3 * s7 ) * t         + c2 * s5 ) * t         + c1 * s3 ) * t         + c0;  w *= ( c / *b );////  COMBINE THE RESULTS//  T1 = *a / *b;  u = d * alnrel ( &T1 );  v = *a * ( log ( *b ) - 1.0e0 );  if ( v < u )  {    algdiv = w - v - u;  }  else  {    algdiv = w - u - v;  }  return algdiv;}//****************************************************************************80double alnrel ( double *a )//****************************************************************************80////  Purpose:// //    ALNREL evaluates the function ln ( 1 + A ).////  Modified:////    17 November 2006////  Reference:////    Armido DiDinato, 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 *A, the argument.////    Output, double ALNREL, the value of ln ( 1 + A ).//{  double alnrel;  static double p1 = -0.129418923021993e+01;  static double p2 =  0.405303492862024e+00;  static double p3 = -0.178874546012214e-01;  static double q1 = -0.162752256355323e+01;  static double q2 =  0.747811014037616e+00;  static double q3 = -0.845104217945565e-01;  double t;  double t2;  double w;  double x;  if ( fabs ( *a ) <= 0.375e0 )  {    t = *a / ( *a + 2.0e0 );    t2 = t * t;    w = (((p3*t2+p2)*t2+p1)*t2+1.0e0)/(((q3*t2+q2)*t2+q1)*t2+1.0e0);    alnrel = 2.0e0 * t * w;  }  else  {    x = 1.0e0 + *a;    alnrel = log ( x );  }  return alnrel;}//****************************************************************************80double apser ( double *a, double *b, double *x, double *eps )//****************************************************************************80////  Purpose:// //    APSER computes the incomplete beta ratio I(SUB(1-X))(B,A).////  Discussion:////    APSER is used only for cases where////      A <= min ( EPS, EPS * B ), //      B * X <= 1, and //      X <= 0.5.////  Parameters:////    Input, double *A, *B, *X, the parameters of teh//    incomplete beta ratio.////    Input, double *EPS, a tolerance.////    Output, double APSER, the computed value of the//    incomplete beta ratio.//{  static double g = 0.577215664901533e0;  static double apser,aj,bx,c,j,s,t,tol;    bx = *b**x;    t = *x-bx;    if(*b**eps > 2.e-2) goto S10;    c = log(*x)+psi(b)+g+t;    goto S20;S10:    c = log(bx)+g+t;S20:    tol = 5.0e0**eps*fabs(c);    j = 1.0e0;    s = 0.0e0;S30:    j = j + 1.0e0;    t = t * (*x-bx/j);    aj = t/j;    s = s + aj;    if(fabs(aj) > tol) goto S30;    apser = -(*a*(c+s));    return apser;}//****************************************************************************80double bcorr ( double *a0, double *b0 )//****************************************************************************80////  Purpose:// //    BCORR evaluates DEL(A0) + DEL(B0) - DEL(A0 + B0).////  Discussion:////    The function DEL(A) is a remainder term that is used in the expression:////      ln ( Gamma ( A ) ) = ( A - 0.5 ) * ln ( A ) //        - A + 0.5 * ln ( 2 * PI ) + DEL ( A ),////    or, in other words, DEL ( A ) is defined as:////      DEL ( A ) = ln ( Gamma ( A ) ) - ( A - 0.5 ) * ln ( A ) //        + A + 0.5 * ln ( 2 * PI ).////  Parameters:////    Input, double *A0, *B0, the arguments.//    It is assumed that 8 <= A0 and 8 <= B0.////    Output, double *BCORR, the value of the function.//{  static double c0 =  0.833333333333333e-01;  static double c1 = -0.277777777760991e-02;  static double c2 =  0.793650666825390e-03;  static double c3 = -0.595202931351870e-03;  static double c4 =  0.837308034031215e-03;  static double c5 = -0.165322962780713e-02;  static double bcorr,a,b,c,h,s11,s3,s5,s7,s9,t,w,x,x2;  a = fifdmin1 ( *a0, *b0 );  b = fifdmax1 ( *a0, *b0 );  h = a / b;  c = h / ( 1.0e0 + h );  x = 1.0e0 / ( 1.0e0 + h );  x2 = x * x;////  SET SN = (1 - X**N)/(1 - X)//  s3 = 1.0e0 + ( x + x2 );  s5 = 1.0e0 + ( x + x2 * s3 );  s7 = 1.0e0 + ( x + x2 * s5 );  s9 = 1.0e0 + ( x + x2 * s7 );  s11 = 1.0e0 + ( x + x2 * s9 );////  SET W = DEL(B) - DEL(A + B)//  t = pow ( 1.0e0 / b, 2.0 );  w = (((( c5 * s11  * t + c4               * s9 ) * t + c3               * s7 ) * t + c2               * s5 ) * t + c1               * s3 ) * t + c0;  w *= ( c / b );////  COMPUTE  DEL(A) + W//  t = pow ( 1.0e0 / a, 2.0 );  bcorr = ((((( c5 * t + c4 )                    * t + c3 )                    * t + c2 )                    * t + c1 )                    * t + c0 ) / a + w;  return bcorr;}//****************************************************************************80**double beta ( double a, double b )//****************************************************************************80**////  Purpose:////    BETA evaluates the beta function.////  Modified:////    03 December 1999////  Author:////    John Burkardt////  Parameters:////    Input, double A, B, the arguments of the beta function.////    Output, double BETA, the value of the beta function.//{  return ( exp ( beta_log ( &a, &b ) ) );}//****************************************************************************80double beta_asym ( double *a, double *b, double *lambda, double *eps )//****************************************************************************80////  Purpose:////    BETA_ASYM computes an asymptotic expansion for IX(A,B), for large A and B.////  Parameters:////    Input, double *A, *B, the parameters of the function.//    A and B should be nonnegative.  It is assumed that both A and B//    are greater than or equal to 15.////    Input, double *LAMBDA, the value of ( A + B ) * Y - B.//    It is assumed that 0 <= LAMBDA.////    Input, double *EPS, the tolerance.//{  static double e0 = 1.12837916709551e0;  static double e1 = .353553390593274e0;  static int num = 20;////  NUM IS THE MAXIMUM VALUE THAT N CAN TAKE IN THE DO LOOP//            ENDING AT STATEMENT 50. IT IS REQUIRED THAT NUM BE EVEN.//            THE ARRAYS A0, B0, C, D HAVE DIMENSION NUM + 1.//     E0 = 2/SQRT(PI)//     E1 = 2**(-3/2)//  static int K3 = 1;  static double value;  static double bsum,dsum,f,h,h2,hn,j0,j1,r,r0,r1,s,sum,t,t0,t1,u,w,w0,z,z0,    z2,zn,znm1;  static int i,im1,imj,j,m,mm1,mmj,n,np1;  static double a0[21],b0[21],c[21],d[21],T1,T2;    value = 0.0e0;    if(*a >= *b) goto S10;    h = *a/ *b;    r0 = 1.0e0/(1.0e0+h);    r1 = (*b-*a)/ *b;    w0 = 1.0e0/sqrt(*a*(1.0e0+h));    goto S20;S10:    h = *b/ *a;    r0 = 1.0e0/(1.0e0+h);    r1 = (*b-*a)/ *a;    w0 = 1.0e0/sqrt(*b*(1.0e0+h));S20:    T1 = -(*lambda/ *a);    T2 = *lambda/ *b;    f = *a*rlog1(&T1)+*b*rlog1(&T2);    t = exp(-f);    if(t == 0.0e0) return value;    z0 = sqrt(f);    z = 0.5e0*(z0/e1);    z2 = f+f;    a0[0] = 2.0e0/3.0e0*r1;    c[0] = -(0.5e0*a0[0]);    d[0] = -c[0];    j0 = 0.5e0/e0 * error_fc ( &K3, &z0 );    j1 = e1;    sum = j0+d[0]*w0*j1;    s = 1.0e0;    h2 = h*h;    hn = 1.0e0;    w = w0;    znm1 = z;    zn = z2;    for ( n = 2; n <= num; n += 2 )    {        hn = h2*hn;        a0[n-1] = 2.0e0*r0*(1.0e0+h*hn)/((double)n+2.0e0);        np1 = n+1;        s += hn;        a0[np1-1] = 2.0e0*r1*s/((double)n+3.0e0);        for ( i = n; i <= np1; i++ )        {            r = -(0.5e0*((double)i+1.0e0));            b0[0] = r*a0[0];            for ( m = 2; m <= i; m++ )            {                bsum = 0.0e0;                mm1 = m-1;                for ( j = 1; j <= mm1; j++ )                {                    mmj = m-j;                    bsum += (((double)j*r-(double)mmj)*a0[j-1]*b0[mmj-1]);                }                b0[m-1] = r*a0[m-1]+bsum/(double)m;            }            c[i-1] = b0[i-1]/((double)i+1.0e0);            dsum = 0.0e0;            im1 = i-1;            for ( j = 1; j <= im1; j++ )            {                imj = i-j;                dsum += (d[imj-1]*c[j-1]);            }            d[i-1] = -(dsum+c[i-1]);        }        j0 = e1*znm1+((double)n-1.0e0)*j0;        j1 = e1*zn+(double)n*j1;        znm1 = z2*znm1;        zn = z2*zn;        w = w0*w;        t0 = d[n-1]*w*j0;        w = w0*w;        t1 = d[np1-1]*w*j1;        sum += (t0+t1);        if(fabs(t0)+fabs(t1) <= *eps*sum) goto S80;    }S80:    u = exp(-bcorr(a,b));    value = e0*t*u*sum;    return value;}//****************************************************************************80double beta_frac ( double *a, double *b, double *x, double *y, double *lambda,  double *eps )//****************************************************************************80////  Purpose:// //    BETA_FRAC evaluates a continued fraction expansion for IX(A,B).////  Parameters:////    Input, double *A, *B, the parameters of the function.//    A and B should be nonnegative.  It is assumed that both A and//    B are greater than 1.////    Input, double *X, *Y.  X is the argument of the//    function, and should satisy 0 <= X <= 1.  Y should equal 1 - X.////    Input, double *LAMBDA, the value of ( A + B ) * Y - B.////    Input, double *EPS, a tolerance.////    Output, double BETA_FRAC, the value of the continued//    fraction approximation for IX(A,B).//{  static double bfrac,alpha,an,anp1,beta,bn,bnp1,c,c0,c1,e,n,p,r,r0,s,t,w,yp1;  bfrac = beta_rcomp ( a, b, x, y );  if ( bfrac == 0.0e0 )   {    return bfrac;  }  c = 1.0e0+*lambda;  c0 = *b/ *a;  c1 = 1.0e0+1.0e0/ *a;  yp1 = *y+1.0e0;  n = 0.0e0;  p = 1.0e0;  s = *a+1.0e0;  an = 0.0e0;  bn = anp1 = 1.0e0;  bnp1 = c/c1;  r = c1/c;////  CONTINUED FRACTION CALCULATION//S10:  n += 1.0e0;  t = n/ *a;  w = n*(*b-n)**x;  e = *a/s;  alpha = p*(p+c0)*e*e*(w**x);  e = (1.0e0+t)/(c1+t+t);  beta = n+w/s+e*(c+n*yp1);  p = 1.0e0+t;  s += 2.0e0;////  UPDATE AN, BN, ANP1, AND BNP1//  t = alpha*an+beta*anp1;  an = anp1;  anp1 = t;  t = alpha*bn+beta*bnp1;  bn = bnp1;  bnp1 = t;  r0 = r;  r = anp1/bnp1;  if ( fabs(r-r0) <= (*eps) * r )   {    goto S20;  }////  RESCALE AN, BN, ANP1, AND BNP1//  an /= bnp1;  bn /= bnp1;  anp1 = r;  bnp1 = 1.0e0;  goto S10;////  TERMINATION//S20:  bfrac *= r;  return bfrac;}//****************************************************************************80void beta_grat ( double *a, double *b, double *x, double *y, double *w,  double *eps,int *ierr )//****************************************************************************80////  Purpose:// //    BETA_GRAT evaluates an asymptotic expansion for IX(A,B).////  Parameters:////    Input, double *A, *B, the parameters of the function.//    A and B should be nonnegative.  It is assumed that 15 <= A //    and B <= 1, and that B is less than A.////    Input, double *X, *Y.  X is the argument of the//    function, and should satisy 0 <= X <= 1.  Y should equal 1 - X.////    Input/output, double *W, a quantity to which the//    result of the computation is to be added on output.////    Input, double *EPS, a tolerance.////    Output, int *IERR, an error flag, which is 0 if no error

⌨️ 快捷键说明

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