C#, Numerical Computing - 불완전한 베타 기능을 위한 소스 코드

불완전한 베타 기능


불완전 베타 함수(Euler 적분이라고도 함)는 일반화된 β 함수입니다. 독립 적분(0에서 x까지의 적분 범위 포함)이 정적분을 대체합니다. 공식은 다음과 같습니다.

어디:

0 ≤ x ≤ 1,
a, b > 0. 참고: 정의는 때때로 음의 정수를 포함하도록 작성되지만(예: Özçag et al., 2008) 이는 일반적인 것이 아닙니다.
B1(p, q)는 (완전한) 베타 함수입니다. 즉, 함수는 x = 1로 완전해집니다. 불완전 베타 함수는 베타 함수 또는 3개의 완전 감마 함수로 표현될 수도 있습니다(DiDonato & Jarnagin, 1972).


베타 함수는 다음과 같이 표현됩니다.

 

불완전한 베타 기능 비율


비율

에게

불완전 베타 함수 비율이라고 합니다.
기호 Ix로 표시하면 Ix(a, b) ≡ Bx(a, b) / B1(a, b)로 표시됩니다 .
여기서 a > 0, b > 0입니다(DiDonato & Jarnagin, nd).

불완전한 베타 기능 사용

불완전한 베타 함수와 Ix는 원자 물리학, 유체 역학, 격자 이론(격자 연구) 및 전송 이론(DiDonato & Morris, 1988)을 포함한 다양한 과학 응용 분야에서 발생합니다.

  •     t-테스트, F-테스트(Besset, 2001) 및 한계를 계산하는 데 불완전한 베타 함수가 사용되는 이항 분포에 기반한 신뢰 구간 계산(Young et al., 1998),
  •     이항 분포 꼬리에서 확률 계산(DTIC, 1979),
  •     표준 정규 분포에 대한 누적 확률 생성(Klugman, 2013).
  •     베타 분포를 따르는 데이터에 대해 특정 값보다 큰 측정값 찾기.

C# SourceCodes 소스 코드

시스템 사용;

namespace Legalsoft.Truffer
{     /// <summary>     /// 불완전한 베타 기능을 위한 객체입니다.     /// Gauleg18은 Gauss-Legendre 구적법에 대한 계수를 제공합니다.     /// </summary>     공개 클래스 베타: Gauleg18     {         비공개 const int SWITCH = 3000;         private const double EPS = float.Epsilon;         private const double FPMIN = float.MinValue;// / float.Epsilon;








        public double betai(double a, double b, double x)
        {             if (a <= 0.0 || b <= 0.0)             {                 throw new Exception("루틴 베타에서 잘못된 a 또는 b");             }             if (x < 0.0 || x > 1.0)             {                 throw new Exception("루틴 베타에서 잘못된 x");             }             //if (x == 0.0 || x == 1.0)             if (Math.Abs(x) <= float.Epsilon || Math.Abs(x-1.0) <= float.             Epsilon) {                 반환 x;             }             if (a > SWITCH && b > SWITCH)             {                 return betaiapprox(a, b, x);
















            }
            double bt = Math.Exp(Globals.gammln(a + b) - Globals.gammln(a) - Globals.gammln(b) + a * Math.Log(x) + b * Math.Log(1.0 - x) );
            if (x < (a + 1.0) / (a ​​+ b + 2.0))
            {                 return bt * betacf(a, b, x) / a;             }             else             {                 return 1.0 - bt * betacf(b, a, 1.0 - x) / b;             }         }






        공개 이중 베타cf(이중 a, 이중 b, 이중 x)
        {             이중 qab = a + b;             이중 qap = a + 1.0;             이중 qam = a - 1.0;             더블 c = 1.0;             더블 d = 1.0 - qab * x / qap;             if (Math.Abs(d) < FPMIN)             {                 d = FPMIN;             }             d = 1.0/d;             이중 h = d;             for (int m = 1; m < 10000; m++)             {                 int m2 = 2 * m;                 이중 aa = m * (b - m) * x / ((qam + m2) * (a + m2));                 d = 1.0 + aa * d;
















                if (Math.Abs(d) < FPMIN)
                {                     d = FPMIN;                 }                 c = 1.0 + aa/c;                 if (Math.Abs(c) < FPMIN)                 {                     c = FPMIN;                 }                 d = 1.0/d;                 h *= d * c;                 aa = -(a + m) * (qab + m) * x / ((a + m2) * (qap + m2));                 d = 1.0 + aa * d;                 if (Math.Abs(d) < FPMIN)                 {                     d = FPMIN;                 }                 c = 1.0 + aa/c;                 if (Math.Abs(c) < FPMIN)

















                {                     c = FPMIN;                 }                 d = 1.0/d;                 이중 del = d * c;                 h *= 델;                 if (Math.Abs(del - 1.0) <= EPS)                 {                     break;                 }             }             h를 반환합니다.         }











        공개 이중 베타(double a, double b, double x)
        {             double a1 = a - 1.0;             더블 b1 = b - 1.0;             더블 뮤 = a / (a ​​+ b);             이중 lnmu = Math.Log(mu);             이중 lnmuc = Math.Log(1.0 - mu);             double t = Math.Sqrt(a * b / (Globals.SQR(a + b) * (a + b + 1.0)));             더블 쉬;             if (x > a / (a ​​+ b))             {                 if (x >= 1.0)                 {                     반환 1.0;                 }                 xu = Math.Min(1.0, Math.Max(mu + 10.0 * t, x + 5.0 * t));             }             다른
















            {                 경우 (x <= 0.0)                 {                     반환 0.0;                 }                 xu = Math.Max(0.0, Math.Min(mu - 10.0 * t, x - 5.0 * t));             }             이중 합계 = 0;             for (int j = 0; j < 18; j++)             {                 t = x + (xu - x) * y[j];                 합계 += w[j] * Math.Exp(a1 * (Math.Log(t) - lnmu) + b1 * (Math.Log(1 - t) - lnmuc));             }             double ans = sum * (xu - x) * Math.Exp(a1 * lnmu - Globals.gammln(a) + b1 * lnmuc - Globals.gammln(b) + Globals.gammln(a + b));             ANS > 0.0 반환 ? 1.0 - ans : -ans;         }














        공개 이중 invbetai(double p, double a, double b)
        {             const double EPS = 1.0e-8;             이중 t;             더블 유;             더블 엑스;             이중 a1 = a - 1.0;             더블 b1 = b - 1.0;             if (p <= 0.0)             {                 반환 0.0;             }             그렇지 않으면 (p >= 1.0)             {                 1.0 반환;             }             그렇지 않으면 (a >= 1.0 && b >= 1.0)             {                 double pp = (p < 0.5) ? p: 1.0 - p;                 t = Math.Sqrt(-2.0 * Math.Log(pp));


















                x = (2.30753 + t * 0.27061) / (1.0 + t * (0.99229 + t * 0.04481)) - t;
                if (p < 0.5)
                {                     x = -x;                 }                 double al = (Globals.SQR(x) - 3.0) / 6.0;                 이중 h = 2.0/(1.0/(2.0 * a - 1.0) + 1.0 / (2.0 * b - 1.0));                 더블 w = (x * Math.Sqrt(al + h) / h) - (1.0 / (2.0 * b - 1) - 1.0 / (2.0 * a - 1.0)) * (al + 5.0 / 6.0 - 2.0 / ( 3.0 * h));                 x = a / (a ​​+ b * Math.Exp(2.0 * w));             }             else             {                 double lna = Math.Log(a / (a ​​+ b));                 이중 lnb = Math.Log(b / (a ​​+ b));











                t = Math.Exp(a * lna) / a;
                u = Math.Exp(b * lnb) / b;
                이중 w = t + u;
                if (p < t / w)
                {                     x = Math.Pow(a * w * p, 1.0 / a);                 }                 그렇지 않으면                 {                     x = 1.0 - Math.Pow(b * w * (1.0 - p), 1.0 / b);                 }             }             double afac = -Globals.gammln(a) - Globals.gammln(b) + Globals.gamln(a + b);             for (int j = 0; j < 10; j++)             {                 // if (x == 0.0 || x == 1.0)











                if (Math.Abs(x) <= float.Epsilon || Math.Abs(x=1.0) <= float.Epsilon)
                {                     반환 x;                 }                 이중 오류 = 베타(a, b, x) - p;                 t = Math.Exp(a1 * Math.Log(x) + b1 * Math.Log(1.0 - x) + afac);                 u = 오류 / t;                 x -= (t = u / (1.0 - 0.5 * Math.Min(1.0, u * (a1 / x - b1 / (1.0 - x))))));                 if (x <= 0.0)                 {                     x = 0.5 * (x + t);                 }                 if (x >= 1.0)                 {                     x = 0.5 * (x + t + 1.0);                 }














                if (Math.Abs(t) < EPS * x && j > 0)
                {                     break;                 }             }             x를 반환합니다.         }




        /// <summary>
        /// 베타 함수 B(z,w)의 값을 반환합니다.
        /// </summary>
        /// <param name="z"></param>
        /// <param name="w"></param>
        /// <returns></returns>
        public static double 베타(double z, double w)
        {             return Math.Exp(Globals.gammln(z) + Globals.gammln(w) - Globals.gammln(z + w));         } }     }




 

추천

출처blog.csdn.net/beijinghorn/article/details/131605616