为什么小值的逆t分布在Matlab和R中有所不同?

时间:2015-01-12 23:16:04

标签: r matlab statistics distribution probability

我想在Matlab中为小值(例如1e-18)评估逆学生 t - 分布函数。自由度是2。

不幸的是,Matlab返回NaN

tinv(1e-18,2)
NaN

但是,如果我使用R&#39的内置功能:

qt(1e-18,2)
-707106781

结果是明智的。为什么Matlab不能评估这个小值的函数? Matlab和R的结果非常类似于1e-15,但是对于较小的值,差异是相当大的:

tinv(1e-16,2)/qt(1e-16,2) = 1.05

有没有人知道Matlab和R的实现算法有什么不同,如果R给出了正确的结果,我怎样才能有效地计算Matlab中的逆 t -distribution,以获得更小的值?

1 个答案:

答案 0 :(得分:5)

似乎R qt可能使用completely different algorithm而不是Matlab的tinv。我认为您和其他人应该通过提交service request向The MathWorks报告此缺陷。顺便说一下,在R2014b和R2015a中,对于第一个参数-Inf的小值(大约NaN和更小),返回eps/8而不是p。这更明智,但我认为他们应该做得更好。

在此期间,有几种解决方法。

特殊情况
首先,在Student's t-distribution的情况下,对于反向CDF有several simple analytic solutions或对于ν的某些整数参数有quantile function。对于ν = 2的例子:

% for v = 2
p = 1e-18;
x = (2*p-1)./sqrt(2*p.*(1-p))

返回-7.071067811865475e+08。至少,Matlab的tinv应该包含这些特殊情况(它们只对ν = 1这样做)。它也可能会提高这些特定解决方案的准确性和速度。

数字反转
tinv函数基于betaincinv函数。似乎这个函数可能导致第一个参数p的小值的精度损失。但是,如OP所建议的,可以使用CDF函数tcdf和根寻找方法来数值地评估逆CDF。 tcdf函数基于betainc,它似乎不敏感。使用fzero

p = 1e-18;
v = 2
x = fzero(@(x)tcdf(x,v)-p, 0)

返回-7.071067811865468e+08。请注意,对于p接近1的值,此方法不是非常健壮。

符号解决方案
对于更一般的情况,您可以利用symbolic mathvariable precision arithmetic。您可以将Gausian hypergeometric functions 2 F 1 中的标识用作CDF的given here。因此,使用solvehypergeom

% Supposedly valid for or x^2 < v, but appears to work for your example
p = sym('1e-18');
v = sym(2);
syms x
F = 0.5+x*gamma((v+1)/2)*hypergeom([0.5 (v+1)/2],1.5,-x^2/v)/(sqrt(sym('pi')*v)*gamma(v/2));
sol_x = solve(p==F,x);
vpa(sol_x)

tinv函数基于betaincinv函数。符号数学工具箱或MuPAD中没有等效函数甚至不完整的Beta函数,但{的 2 F 1 关系类似可以使用{3}}:

p = sym('1e-18');
v = sym(2);
syms x
a = v/2;
F = 1-x^a*hypergeom([a 0.5],a+1,x)/(a*beta(a,0.5));
sol_x = solve(2*abs(p-0.5)==F,x);
sol_x = sign(p-0.5).*sqrt(v.*(1-sol_x)./sol_x);
vpa(sol_x)

两种符号方案都使用默认值-707106781.186547523340184返回同意digits的结果。

我还没有完全验证上面的两种符号方法,所以在所有情况下我都不能保证它们的正确性。代码也需要进行矢量化,并且比完全数值解决方案慢。