Rのqt
は、Matlabのtinv
よりcompletely different algorithmを使用するように見えます。私はあなたと他の人たちがservice requestを提出してこの欠陥をThe MathWorksに報告しなければならないと思います。ちなみに、R2014bとR2015aでは、p
の最初の引数の小さい値(約eps/8
以下)に対して、NaN
の代わりに-Inf
が返されます。これはより賢明ですが、彼らはより良くなるべきだと思います。
途中で、いくつかの回避策があります。
特殊なケース
まず、Student's t-distributionの場合には、νの特定の整数パラメータの逆CDFにseveral simple analytic solutionsまたはquantile functionがあります。 -7.071067811865475e+08
を返し
% for v = 2
p = 1e-18;
x = (2*p-1)./sqrt(2*p.*(1-p))
:ν = 2のあなたの例。 Matlabのtinv
には最低限、これらの特別なケースが含まれている必要があります(ν = 1の場合のみ)。おそらくこれらの特定のソリューションの精度とスピードも向上するでしょう。
数値逆
tinv
関数はbetaincinv
関数に基づいています。この関数は、最初の引数の小さな値の精度が失われる原因となることがあります(p
)。しかしながら、OPによって示唆されるように、逆CDFを数値的に評価するために、CDF関数tcdf
と根探索法を使用することができる。 tcdf
関数はbetainc
に基づいていますが、それほど敏感ではないようです。 fzero
の使用:
p = 1e-18;
v = 2
x = fzero(@(x)tcdf(x,v)-p, 0)
これは-7.071067811865468e+08
を返します。この方法は、p
の値が1
に近いほどあまり強くないことに注意してください。
シンボリックソリューションは
より一般的なケースでは、あなたはsymbolic mathとvariable precision arithmeticを利用することができます。あなたはCDFのためgiven hereとして、 F 、Gausian hypergeometric functionsの面でIDを使用することができます。したがって、solve
とhypergeom
を使用して:
% 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
関数に基づいています。
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)
両方シンボリックスキームが返さ:使用することができない同等の機能や記号数学ツールボックスまたはのMuPADでさえ不完全ベータ関数が、incomplete Beta functionに対する同様 F 関係は存在しません結果は、digits
のデフォルト値を使用して-707106781.186547523340184
に同意する結果になります。
私は上記の2つの象徴的な方法を完全には検証していないので、すべての場合においてその正確さを保証することはできません。コードはベクトル化する必要もあり、完全な数値解よりも遅くなります。
R 'qt'Cコード関数の引用された2つの権限は、Hill、G.W.(1970)Algorithm 396:スチューデントのt-分位数です。 ACMのコミュニケーション、13(10)、619-620。 and Hill、G. W.(1981)「アルゴリズム396、数学ソフトウェアのACMトランザクション、7,250-1」を参照。 –
私のマシンでは、最初の引数が1e-16よりも少なくなっていることを確認しています。アルゴリズムについては、Matlabで 'open tinv'を実行して何ができるかを確認することができます –
何年もの間、多くの作業が(主にMartin Maechlerによる)' qt() 'に入ったと思います。多くの極端な場合に確実に動作することを確認してください。https://github.com/wch/r-source/commits/trunk/src/nmath/qt.c –