<VB数理统计实用算法>书中的算法源程序

源代码在线查看: 分布假设检验m2.bas

软件大小: 11653 K
上传用户: zhou28
关键词: 算法 lt VB gt
下载地址: 免注册下载 普通下载 VIP

相关代码

				Attribute VB_Name = "modMethod"
				'分布假设检验
				Option Explicit
				'正态分布检验时合并频数小于5的区间
				'x0是区间的左端点
				'x1是区间的右端点
				'y是区间的频数
				'L合并的次数
				Public Sub Merge(x0() As Double, x1() As Double, _
				                y() As Double, L As Integer)
				    Dim n As Integer, I As Integer, J As Integer
				    n = UBound(x0, 1)
				    I = 1: L = 0
				100:
				    If I = n - L Then GoTo 200
				    If y(I) < 5 Then                '是否需要合并
				        y(I) = y(I) + y(I + 1)      '合并频数
				        x1(I) = x1(I + 1)           '合并右端点
				        L = L + 1                   '记录一次合并
				        For J = I + 1 To n - 1      '将区间端点和频数数组向前移位
				            y(J) = y(J + 1)
				            x0(J) = x0(J + 1)
				            x1(J) = x1(J + 1)
				        Next J
				        GoTo 100                    '转去检查新y(I)是否还小于5
				    End If
				    I = I + 1                       '对下一个频数进行检查
				    GoTo 100
				200:
				    If y(n - L) < 5 Then            '检查最后一个频数,如果也小于5则向前合并
				        y(n - L - 1) = y(n - L - 1) + y(n - L)
				        x1(n - L - 1) = x1(n - L)
				        L = L + 1
				    End If
				End Sub
				
				'二项式或泊松分布检验时合并频数小于5的区间
				'y:区间的观测频数
				'y1:区间的理论频数
				'L:合并的次数
				Public Sub Merge_B(y() As Double, y1() As Double, L As Integer)
				    Dim n As Integer, I As Integer, J As Integer
				    n = UBound(x0, 1)
				    I = 1: L = 0
				100:
				    If I = n - L Then GoTo 200
				    If y(I) < 5 Then                '是否需要合并
				        y(I) = y(I) + y(I + 1)      '合并观测频数
				        y1(I) = y1(I) + y1(I + 1)   '合并理论频数
				        L = L + 1                   '记录一次合并
				        For J = I + 1 To n - 1      '将区间端点和频数数组向前移位
				            y(J) = y(J + 1)
				            y1(J) = y1(J + 1)
				        Next J
				        GoTo 100                    '转去检查新y(I)是否还小于5
				    End If
				    I = I + 1                       '对下一个频数进行检查
				    GoTo 100
				200:
				    If y(n - L) < 5 Then            '检查最后一个频数,如果也小于5则向前合并
				        y(n - L - 1) = y(n - L - 1) + y(n - L)
				        y1(n - L - 1) = y1(n - L - 1) + y1(n - L)
				        L = L + 1
				    End If
				End Sub
				
				'计算正态分布函数
				'x:正态偏离点
				'F:下侧概率
				Public Sub Norm(x As Double, F As Double)
				    Dim y As Double, ER As Double, Q As Double
				    Dim A
				    Const a1 As Double = 0.0705230784
				    Const a2 As Double = 0.0422820123
				    Const a3 As Double = 0.0092705272
				    Const a4 As Double = 0.0001520143
				    Const a5 As Double = 0.0002765672
				    Const a6 As Double = 0.0000430638
				    y = 0.707106781187 * Abs(x)
				    A = a4 + y * (a5 + y * a6)
				    A = a3 + y * A
				    A = a2 + y * A
				    A = a1 + y * A
				    ER = 1 - (1 + y * A) ^ (-16)
				    Q = 0.5 * ER
				    If x < 0 Then F = 0.5 - Q Else F = 0.5 + Q
				End Sub
				
				'假定为正态分布时,求理论频数与观测频数的卡方值
				'x0(1 To n):区间段的左端点值
				'x1(1 To n):区间段的右端点值
				'x(1 To n):区间段的左右端点的平均值
				'y(1 To n):区间段的频数
				'X2:卡方检验值,计算结果
				'L:合并的次数(n-L是合并后的区间数)
				Public Sub Norm_X2(x0() As Double, x1() As Double, x() As Double, _
				        y() As Double, x2 As Double, L As Integer)
				    Dim Xa As Double, Ya As Double, Xv As Double
				    Dim n As Integer, I As Integer
				    Dim z0 As Double, z1 As Double
				    Dim p As Double, P0 As Double, P1 As Double
				    Dim Fe As Double, xx As Double, pp, ff
				    n = UBound(x, 1)
				    For I = 1 To n
				        Xa = Xa + x(I) * y(I): Ya = Ya + y(I)
				    Next I
				    Xa = Xa / Ya                                    '平均值
				    For I = 1 To n
				        Xv = Xv + (x(I) - Xa) ^ 2 * y(I)
				    Next I
				    Xv = Sqr(Xv / Ya)                               '标准差
				    Merge x0, x1, y, L                              '对频数小于5的区间进行合并
				    For I = 1 To n - L
				        z0 = (x0(I) - Xa) / Xv                      '标准化左端点
				        z1 = (x1(I) - Xa) / Xv                      '标准化右端点
				        Norm z0, P0                                 'P0为左端点的下侧概率
				        Norm z1, P1                                 'P1为右端点的下侧概率
				        p = P1 - P0                                 '区间段的理论频率
				        pp = pp + p
				        Fe = p * Ya                                 '区间段的理论频数
				        ff = ff + Fe
				        xx = (y(I) - Fe) ^ 2 / Fe                   '卡方值
				        x2 = x2 + xx                                '卡方值的和
				    Next I
				End Sub
				
				'计算符合二项式分布事件的概率
				'n:试验次数
				'p:一次试验中事件A出现的概率
				'x:n次试验中事件A出现的次数
				'Bin:事件A出现x次的概率
				Public Sub Bino(n As Integer, p As Single, x As Integer, bin As Double)
				    Dim Q As Single, nn As Double, NI As Double, m As Double
				    Dim I As Integer, C As Double
				    Q = 1 - p
				    If x = 0 Then
				        bin = Q ^ n
				        Exit Sub
				    End If
				    nn = 0
				    For I = 1 To n
				        nn = nn + Log(I)
				    Next I                                              'NN = n!
				    m = 0
				    For I = 1 To x
				        m = m + Log(I)
				    Next I                                              'x!
				    NI = 0
				    For I = 1 To n - x
				        NI = NI + Log(I)
				    Next I                                              '(n-x)!
				    C = nn - m - NI
				    C = C + Log(p ^ x) + Log(Q ^ (n - x))
				    bin = Exp(C)
				End Sub
				
				'假定为二项式分布时,求理论频数与观测频数的卡方值
				'x(1 To n):事件次数,n为观测组数
				'y(1 To n):观测频数,n为观测组数
				'y1(1 To n):理论频数
				'P1:一次试验中,事件出现的概率
				'nn:试验次数
				'X2:卡方检验值,计算结果
				'L:合并的次数(n-L是合并后的区间数)
				Public Sub Bino_X2(x() As Double, y() As Double, y1() As Double, _
				            P1 As Single, nn As Integer, x2 As Double, L As Integer)
				    Dim I As Integer, J As Integer, n As Integer, z As Double
				    Dim mm As Integer, xx As Double, zmm As Double
				    n = UBound(x, 1)                                'n是原始区间数
				    For I = 1 To n
				        mm = mm + y(I)                              'mm是观测频数
				    Next I
				'按合并前数据求出理论频数
				    For I = 1 To n
				        J = x(I)
				        Bino nn, P1, J, z                           'z是理论频率
				        y1(I) = z * mm                              'y1是理论频数
				    Next I
				    Merge_B y, y1, L                                '将观测频数和理论频数同时合并
				    For I = 1 To n - L
				        xx = (y(I) - y1(I)) ^ 2 / y1(I)             '求卡方值
				        x2 = x2 + xx
				    Next I
				End Sub
				
				'计算符合泊松分布事件的概率
				'L:n * p
				'x:n次试验中事件A出现的次数
				'Poi:事件A出现x次的概率
				Public Sub Poisson(Lamda As Double, x As Integer, Poi As Double)
				    Dim E As Double, x1 As Double, I As Integer
				    x1 = 0
				    For I = 1 To x
				        x1 = x1 + Log(I)
				    Next I
				    E = x * Log(Lamda) - Lamda - x1
				    Poi = Exp(E)
				End Sub
				
				'假定为泊松分布时,求理论频数与观测频数的卡方值
				'x(1 To n):事件次数,n为观测组数
				'y(1 To n):观测频数,n为观测组数
				'y1(1 To n):理论频数
				'X2:卡方检验值,计算结果
				'L:合并的次数(n-L是合并后的区间数)
				Public Sub Poi_X2(x() As Double, y() As Double, y1() As Double, _
				            x2 As Double, L As Integer)
				    Dim I As Integer, J As Integer, n As Integer, z As Double
				    Dim mm As Integer, ff As Integer, xx As Double, zmm As Double
				    Dim Lamda As Double
				    n = UBound(x, 1)
				    For I = 1 To n
				        mm = mm + y(I)                              'mm是观测频数
				        ff = ff + x(I) * y(I)                       'x * f
				    Next I
				    Lamda = ff / mm
				'按合并前数据求出理论频数
				    For I = 1 To n
				        J = x(I)
				        Poisson Lamda, J, z                         'z是理论频率
				        y1(I) = z * mm                              'y1是理论频数
				    Next I
				    Merge_B y, y1, L                                '将观测频数和理论频数同时合并
				    For I = 1 To n - L
				        xx = (y(I) - y1(I)) ^ 2 / y1(I)             '求卡方值
				        x2 = x2 + xx
				    Next I
				End Sub
				
				'计算X2分布的分位数
				'n:自由度
				'Q:上侧概率
				'xx:分位数
				Public Sub PCX2(n As Integer, Q As Double, xx As Double)
				    Dim I As Integer, x As Double, p As Double, W As Double
				    Dim x0 As Double, pp As Double, d As Double
				    If n = 1 Then
				        PNorm Q / 2, x: xx = x * x
				        Exit Sub
				    End If
				    If n = 2 Then
				        xx = -2 * Log(Q)
				        Exit Sub
				    End If
				    p = 1 - Q: PNorm Q, x: W = 2 / (9 * n)
				    x0 = n * (1 - W + x * Sqr(W)) ^ 3
				    For I = 1 To 30
				        CX2 n, x0, pp, d
				        If d = 0 Then
				            xx = x0
				            Exit Sub
				        End If
				        xx = x0 - (pp - p) / d
				        If Abs(xx - x0) < 10 - 6 * Abs(xx) Then Exit Sub Else x0 = xx
				    Next I
				End Sub
				
				'求正态分布的分位数
				'Q:上侧概率
				'x:分位数
				Public Sub PNorm(Q As Double, x As Double)
				    Dim p As Double, y As Double, z As Double
				    Dim b0 As Double, b1 As Double, b2 As Double
				    Dim b3 As Double, b4 As Double, b5 As Double
				    Dim b6 As Double, b7 As Double, b8 As Double
				    Dim b9 As Double, b10 As Double, B As Double
				    b0 = 1.570796288: b1 = 0.03706987906
				    b2 = -0.0008364353589: b3 = -0.0002250947176
				    b4 = 0.000006841218299: b5 = 0.000005824238515
				    b6 = -0.00000104527497: b7 = 8.360937017E-08
				    b8 = -3.231081277E-09: b9 = 3.657763036E-11
				    b10 = 6.936233982E-13
				    If Q = 0.5 Then
				        x = 0: GoTo PN01
				    End If
				    If Q > 0.5 Then p = 1 - Q Else p = Q
				    y = -Log(4 * p * (1 - p))
				    B = y * (b9 + y * b10): B = y * (b8 + B)
				    B = y * (b7 + B): B = y * (b6 + B)
				    B = y * (b5 + B): B = y * (b4 + B)
				    B = y * (b3 + B): B = y * (b2 + B)
				    B = y * (b1 + B): z = y * (b0 + B)
				    x = Sqr(z)
				    If Q > 0.5 Then x = -x
				PN01:
				End Sub
				
				'计算卡方分布函数和概率密度
				'n:自由度
				'x2:卡方值
				'F:下侧概率
				'd:概率密度
				Public Sub CX2(n As Integer, x2 As Double, F As Double, d As Double)
				    Dim PIS As Double, x As Double, CHS As Double, u As Double
				    Dim IAI As Integer, pp As Double, N2 As Integer, I As Integer
				    Const PI As Double = 3.14159265359
				    If x2 = 0 Then
				        F = 0: d = 0: Exit Sub
				    End If
				    PIS = Sqr(PI)
				    x = x2 / 2
				    CHS = Sqr(x2)
				    If (n \ 2) * 2 = n Then                 'n为偶数
				        u = x * Exp(-x)
				        F = 1 - Exp(-x)
				        IAI = 2
				    Else                                    'n为奇数
				        u = Sqr(x) * Exp(-x) / PIS
				        Norm CHS, pp                        '调用正态分布函数计算过程
				        F = 2 * (pp - 0.5)
				        IAI = 1
				    End If
				    If IAI = n Then GoTo LL1 Else N2 = n - 2
				    For I = IAI To N2 Step 2
				        F = F - 2 * u / I
				        u = x2 * u / I
				    Next I
				LL1:
				    d = u / x2
				End Sub
				
				
				
							

相关资源