2015-01-12 5 views
6

Matlabでは、逆数Studentのt - 小さな値、例えば1e-18の分布関数を評価したいと考えています。自由度は、MATLABはNaN返し、残念ながら2小さな値の逆t分布がMatlabとRで異なるのはなぜですか?

です:

tinv(1e-18,2) 
NaN 

しかし、私はRの組み込み関数を使用する場合:

qt(1e-18,2) 
-707106781 

結果が賢明です。 Matlabがこの小さな値の関数を評価しないのはなぜですか? MATLABとRの結果が1E-15と非常によく似ていますが、小さな値のために違いがかなりある:

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

誰もがMATLABとRの実装されたアルゴリズムの違いは何か知っている、そしてRは正しい与えればん結果、どのようにしてより小さい値のために、逆行列を効率よく計算するには? -distribution?

+3

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」を参照。 –

+1

私のマシンでは、最初の引数が1e-16よりも少なくなっていることを確認しています。アルゴリズムについては、Matlabで 'open tinv'を実行して何ができるかを確認することができます –

+1

何年もの間、多くの作業が(主にMartin Maechlerによる)' qt() 'に入ったと思います。多くの極端な場合に確実に動作することを確認してください。https://github.com/wch/r-source/commits/trunk/src/nmath/qt.c –

答えて

5

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 mathvariable precision arithmeticを利用することができます。あなたはCDFのためgiven hereとして、 FGausian hypergeometric functionsの面でIDを使用することができます。したがって、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関数に基づいています。

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つの象徴的な方法を完全には検証していないので、すべての場合においてその正確さを保証することはできません。コードはベクトル化する必要もあり、完全な数値解よりも遅くなります。

+0

詳細な回答ありがとう! 2014aに「NaN」が返されます。私は特別なケースの分析ソリューションを知らなかった。私はいくつかの点で逆関数を構築するために 'fzero(@(x)tcdf(x、2) - P、0)'を使い、次に 'interp1'を使いました。もっと一般的ですが、 'df = 2'ではかなり無駄です。 – Arpi

+1

@Arpi:ようこそ。数字のCDF関数自体を使って根を解決することについての良い点。私はあなたの提案と追加の解説で私の答えを更新しました。 – horchler

関連する問題