F分布の計算
F分布に従う確率変数Xに対して、Fの値に対する累積確率、および累積確率pに対するFの値を求める。F分布は自由度と呼ばれている2つのパラメータdf1とdf2をもち、次式(1)で与えられる。
プログラムでは、F分布の自由度と確率密度関数(1)の係数部分をクラス型のアトリビュートに設定して、(1)式を1変数の関数としてガウスの積分公式を適応的に適用している。具体的には以下のプログラムとした。
============== calc_p_for_F.py ==========================
import math
from adap_gl import
AdapGL as agl
from calcroot import
Newton
class C_F_tan_kernel:
def __init__(self, df1,
df2):
self.df1 = df1
self.df2 = df2
def v(self, theta):
x =
math.tan(theta)
v =
pow(x, (self.df1 / 2.0) - 1.0) / \
pow(1.0 + (self.df1 * x / self.df2), (self.df1 + self.df2) / 2.0)
return v / (math.cos(theta) ** 2.0)
class C_F_tan_density:
def __init__(self, df1, df2):
self.df1 = df1
self.df2 = df2
F_kernel =C_F_tan_kernel(self.df1, self.df2)
gl =
agl()
v =
gl.integral(0.0, math.pi/2.0, F_kernel)
self.c = 1.0 / v
def v(self, theta):
x =
math.tan(theta)
v = pow(x, (self.df1 / 2.0) -
1.0) / \
pow(1.0 + (self.df1 * x / self.df2), (self.df1 + self.df2) / 2.0)
return self.c * v / (math.cos(theta) ** 2.0)
class C_cum_F:
def __init__(self, df1,
df2):
self.df1 = df1
self.df2 = df2
self.F_tan = C_F_tan_density(self.df1, self.df2)
self.gl = agl()
def v(self, F):
F_cum = self.gl.integral(0.0, math.atan(F), self.F_tan)
return F_cum
while True:
try:
s =
input("df1 = ")
df1
= float(s)
s =
input("df2 = ")
df2
= float(s)
s =
input("F = ")
F =
float(s)
cum_F = C_cum_F(df1, df2)
p =
cum_F.v(F)
print("p = %f F =
%f"%(p, F))
except:
break
========================================
無限区間の場合にもガウスの積分公式を適用するため、変数変換
を行っている。
上のプログラムcalc_p_for_F.pyの実行例を図1に示す。
図1
2つの自由度とFの値を設定すると、対応する累積確率が計算されて表示される。自由度などの設定において、数値以外の文字を入力するとプログラムの実行終了となる。図1では文字 q が入力されて、プログラムの実行終了となっている。
累積確率に対して対応するFの値を求めるプログラムcalc_F_for_p.pyを以下のように作成した。
=============== calc_F_for_p.py===============================
import math
from adap_gl import
AdapGL as agl
from calcroot import
Newton
class C_F_tan_kernel:
def __init__(self, df1,
df2):
self.df1 = df1
self.df2 = df2
def v(self, theta):
x =
math.tan(theta)
v =
pow(x, (self.df1 / 2.0) - 1.0) / \
pow(1.0 + (self.df1 * x / self.df2), (self.df1 + self.df2) / 2.0)
return v / (math.cos(theta) ** 2.0)
class C_F_tan_density:
def __init__(self, df1,
df2):
self.df1 = df1
self.df2 =
df2
F_kernel =C_F_tan_kernel(self.df1, self.df2)
gl =
agl()
v =
gl.integral(0.0, math.pi/2.0, F_kernel)
self.c = 1.0 / v
def v(self, theta):
x =
math.tan(theta)
v =
pow(x, (self.df1 / 2.0) - 1.0) / \
pow(1.0 + (self.df1 * x / self.df2), (self.df1 + self.df2) / 2.0)
return self.c * v / (math.cos(theta) ** 2.0)
class C_cum_F:
def __init__(self, df1,
df2):
self.df1 = df1
self.df2 = df2
self.F_tan = C_F_tan_density(self.df1, self.df2)
self.gl = agl()
def v(self, F):
F_cum = self.gl.integral(0.0, math.atan(F), self.F_tan)
return F_cum
class C_dcum_F:
def __init__(self, df1,
df2):
self.df1 = df1
self.df2 = df2
F_kernel =C_F_tan_kernel(self.df1, self.df2)
gl =
agl()
v =
gl.integral(0.0, math.pi/2.0, F_kernel)
self.c = 1.0 / v
def v(self, F):
v =
pow(F, (self.df1 / 2.0) - 1.0) / \
pow(1.0 +
(self.df1 * F / self.df2), (self.df1 + self.df2) / 2.0)
return self.c * v
def calc_F_for_p( p,
df1, df2 ):
cum_F = C_cum_F(df1, df2)
Lb = 1.0
while (cum_F.v(Lb) >= p):
Lb
*= 0.5
Ub = Lb * 2.0
while (cum_F.v(Ub) <= p):
Ub
+= 1.0
dcum_F = C_dcum_F(df1, df2)
F = Newton( cum_F, dcum_F,
p, Lb, Ub )
return F
while True:
try:
s =
input("df1 = ")
df1
= float(s)
s =
input("df2 = ")
df2
= float(s)
s =
input("p = ")
p =
float(s)
F =
calc_F_for_p( p, df1, df2 )
print("F = %f p =
%f df1 = %f df2 = %f"%(F, p, df1, df2))
except:
break
==============================================
プログラムの実行例を図2に示す。
図2
自由度df1とdf2、および累積確率pを設定すると対応するFの値が算出される。自由度に数値に変換されない文字を入力するとプログラムの実行終了となる。図2では文字 a が入力されてプログラムの実行終了となっている。
プログラムファイルは圧縮ファイルF_DistriPrgs.zipにまとめた。ファイル名F_DistriPrgs.zipをクリックしてダウンロードできる。