gpt4 book ai didi

delphi - Delphi中卡方分布函数的代码

转载 作者:行者123 更新时间:2023-12-03 19:24:49 26 4
gpt4 key购买 nike

我一直在寻找Delphi中chi-square分发的可用且完整的代码。通过网络有一些代码,但是通常它们不起作用或缺少部分,无法编译等。还有一些库,但是我对我可以简单实现的一些代码感兴趣。

我发现有些东西快用了。一些德语部分已经修复,可以编译并为大多数数据提供p-values

function LnGamma (x : Real) : Real;    
const
a0 = 0.083333333096;
a1 = -0.002777655457;
a2 = 0.000777830670;
c = 0.918938533205;
var
r : Real;
begin
r := (a0 + (a1 + a2 / sqr(x)) / sqr(x)) / x;
LnGamma := (x - 0.5) * ln(x) - x + c + r;
end;

function LnFak (x : Real) : Real;
var
z : Real;
begin
z := x+1;
LnFak := LnGamma(z);
end;

function Reihe (chi : Real; f : Real) : Real;
const MaxError = 0.0001;
var
Bruch,
Summe,
Summand : Real;
k, i : longint;
begin
Summe := 1;
k := 1;
repeat
Bruch := 1;
for i := 1 to k do
Bruch := Bruch * (f + 2 * i);
Summand := power(chi, 2 * k) / Bruch;
Summe := Summe + Summand;
k := succ(k);
until (Summand < MaxError);
Reihe := Summe;
end;

function IntegralChi (chisqr : Real; f : longint) : Real;
var
s : Real;
begin
S := power((0.5 * chisqr), f/2) * Reihe(sqrt(chisqr), f)
* exp((-chisqr/2) - LnGamma((f + 2) / 2));
IntegralChi := 1 - s;
end;


对于相当大的结果,它工作得很好。

例如:

对于 Chi = 1.142132df = 1我得到关于 p0.285202,这很完美。与 SPSS结果或其他程序相同。

但是例如 Chi = 138.609137df = 4我应该得到关于 0.000000的一些信息,但是我在 Reiche函数中遇到浮点溢出错误。那么 SummeSummand很大。

我承认了解分布函数不是我的强项,所以也许有人会告诉我我做错了什么?

非常感谢你提供的信息

最佳答案

您应该调试程序并发现有溢出
在您的循环中k = 149。对于k = 148,Bruch的值为3.3976725289e + 304。 Bruch的下一次计算溢出。解决方法是编码

for i := 1 to k do
Bruch := Bruch / (f + 2 * i);
Summand := power(chi, 2 * k) * Bruch;


通过此更改,您可以在第156次迭代后获得值 IntegralChi(138.609137,4) = 1.76835197E-7

请注意,您的计算(即使对于这种简单算法)也不是最优的
因为您可以一遍又一遍地计算Bruch值。只需更新一次
每个循环:

function Reihe (chi : Real; f : Real) : Real;
const MaxError = 0.0001;
var
Bruch,
Summe,
Summand : Real;
k : longint;
begin
Summe := 1;
k := 1;
Bruch := 1;
repeat
Bruch := Bruch / (f + 2 * k);
Summand := power(chi, 2 * k) * Bruch;
Summe := Summe + Summand;
k := succ(k);
until (Summand < MaxError);
Reihe := Summe;
end;


应该将类似的考虑因素应用于计算 power(chi, 2*k),然后将其与Bruch的改进评估结合起来。

编辑:作为对您的评论的回应,这里是基于幂函数的属性的改进版本,即 power(chi, 2*(k+1)) = power(chi, 2*k)*sqr(chi)

function Reihe (chi : Real; f : Real) : Real;
const MaxError = 0.0001;
var
chi2,
Summe,
Summand : Real;
k : longint;
begin
Summe := 1;
k := 1;
Summand := 1;
chi2 := sqr(chi);
repeat
Summand := Summand * chi2 / (f + 2 * k);
Summe := Summe + Summand;
k := succ(k);
until (Summand < MaxError);
Reihe := Summe;
end;

关于delphi - Delphi中卡方分布函数的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50394952/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com