불완전한 베타 기능
불완전 베타 함수(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)); } } }