Up

分布の計算

 

カイ2乗分布の計算プログラムをPythonで作ってみた。

カイ2乗分布の確率密度関数は次式で与えられる。

カイ2乗の値に対する累積確率

を求めるプログラムを以下のように作成した。

 

===============  Calc_p_from_chi2.py=========================

import math

from adap_gl import AdapGL as agl

#from calcroot import Newton

#from Calc_z_NormalDistri import calc_z

 

def sqr( x ):

    return x * x

 

class C_chi2_tan_kernel:

    def __init__(self, df):

        self.df = df

 

    def v(self, theta):

        x = math.tan(theta)

        v = pow(x, (self.df/2.0) - 1.0) * math.exp(-0.5 * x)

        return v / sqr(math.cos(theta))

               

class C_chi2_tan_density:

    def __init__(self, df):

        self.df = df

        chi2_kernel = C_chi2_tan_kernel(self.df)

        gl = agl()

        v = gl.integral( 0.0, math.pi/2.0, chi2_kernel)

        self.c = 1.0 / v

 

    def v(self, theta):

        x = math.tan(theta)

        v = pow(x, (self.df/2.0) - 1.0) * math.exp(-0.5 * x)

        return self.c * v / sqr(math.cos(theta))

       

class C_cum_chi2:

    def __init__(self, df):

        self.df = df

        self.chi2_tan = C_chi2_tan_density(self.df)

        self.gl = agl()

 

    def v( self, x ):

        chi2_cum = self.gl.integral(0.0, math.atan(x), self.chi2_tan)

        return chi2_cum

 

 

while True:

    try:

        s = input("df = ")

        df = float(s)

        cum_chi2 = C_cum_chi2(df)

        s = input("chi^2 = ")

        chi2 = float(s)

        p = cum_chi2.v(chi2)

        print("p = %f   chi^2 = %f"%(p, chi2))

    except:

        break

===========================================

 

実行例を図1に示す。

図1

 

自由度dfとカイ2乗chi^2の値を設定すると累積確率pが算出される。自由度dfに文字を設定するとプログラムの実行終了となる。図1では、文字pを設定して終了している。

 

累積確率pに対するカイ2乗の値を求めるプログラムを以下のように作成した。

 

=================  Calc_chi2_from_p.py=====================

import math

from adap_gl import AdapGL as agl

from calcroot import Newton

#from Calc_z_NormalDistri import calc_z

 

def sqr( x ):

    return x * x

 

class C_chi2_tan_kernel:

    def __init__(self, df):

        self.df = df

 

    def v(self, theta):

        x = math.tan(theta)

        v = pow(x, (self.df/2.0) - 1.0) * math.exp(-0.5 * x)

        return v / sqr(math.cos(theta))

               

class C_chi2_tan_density:

    def __init__(self, df):

        self.df = df

        chi2_kernel = C_chi2_tan_kernel(self.df)

        gl = agl()

        v = gl.integral( 0.0, math.pi/2.0, chi2_kernel)

        self.c = 1.0 / v

 

    def v(self, theta):

        x = math.tan(theta)

        v = pow(x, (self.df/2.0) - 1.0) * math.exp(-0.5 * x)

        return self.c * v / sqr(math.cos(theta))

       

class C_cum_chi2:

    def __init__(self, df):

        self.df = df

        self.chi2_tan = C_chi2_tan_density(self.df)

        self.gl = agl()

 

    def v( self, x ):

        chi2_cum = self.gl.integral(0.0, math.atan(x), self.chi2_tan)

        return chi2_cum

 

class C_dcum_chi2:

    def __init__(self, df):

        self.df = df

        chi2_kernel = C_chi2_tan_kernel(self.df)

        gl = agl()

        v = gl.integral( 0.0, math.pi/2.0, chi2_kernel)

        self.c = 1.0 / v

 

    def v(self, x):

        v = self.c * pow(x, (self.df/2.0) - 1.0) * math.exp(-0.5 * x)

        return v

 

def calc_chi2_from_p( p, df ):

    cum_chi2 = C_cum_chi2( df )

    Lb = df

    while (cum_chi2.v(Lb) >= p):

        Lb *= 0.5

    Ub = Lb + 1.0

    while (cum_chi2.v(Ub) <= p):

        Ub += 1.0

 

    dcum_chi2 = C_dcum_chi2( df )

    chi2 = Newton( cum_chi2, dcum_chi2, p, Lb, Ub )

    return chi2

 

 

while True:

    try:

        s = input("df = ")

        df = float(s)

        s = input("p = ")

        p = float(s)

        chi2 = calc_chi2_from_p( p, df )

        print("chi^2 = %f     p = %f   df = %f"%(chi2, p, df))

    except:

        break

============================================

 

実行例を図2に示す。

図2

 

自由度dfと累積確率pを設定すると、対応するカイ2乗の値chi^2が計算される。自由度に文字を設定するとプログラムの実行終了となる。図2では、文字aを設定して終了している。

 

プログラムは圧縮ファイルchi2_distriPrgs.zipにまとめた。ファイル名chi2_distriPrgs.zipをクリックしてダウンロードすることができる。

 

 

Up