「正規分布累積関数」の編集履歴(バックアップ)一覧はこちら
「正規分布累積関数」(2010/01/25 (月) 19:11:31) の最新版変更点
追加された行は緑色になります。
削除された行は赤色になります。
EXCELの同名関数と同じ動作をします。ただし計算精度は多少劣ります。 Normsdistは、絶対誤差10進で約6桁。Normsinvは、解をもう1回Normsdistで元に戻した 時点の誤差が絶対誤差10進で約6桁。したがって、単精度関数としてもいいけど、 32bitCPUで単精度というのはあまり意味ないので仕様上は倍精度関数扱いとします。
Normsdistが有効6桁では足りないというなら、ラプラス&シェントンの連分数を使えば 有効桁をもっと増やすことは可能。(EXCELの最新Verはこうやってる。)統計で使う場合、 そもそも有効6桁も必要な場合ってあるんか? よって、有効6桁あれば良しとします。
Normsinv関数の引数の範囲は0≦P≦1ですが、リミットチェックしてエラー処理はしていません。 本来、こういうのをサボると使い物にならない(EXCELは、ちゃんとやってる。)場合が多いけど、 この版はアルゴリズム版であるためあえて省略。
#asciiart(blockquote){
Function Normsdist(X As Double) As Double
'ExlelのNormsdistに同じ。
Dim SPI As Double,D as Double, W as Double
SPI=Sqr(2.0*_System_PI)
W=1.0/(1.0+0.2316419*X)
D=Exp(X^2/(-2))/SPI
Normsdist=1.0-D*(0.3193815*W-0.3565638*W^2+1.781478*W^3-1.821256*W^4+1.330274*W^5)
END Function
Function Normsinv (P As Double)
'ExlelのNormsinvに同じ。
'関数式の性質上、Pがゼロ付近および1付近の精度は悪い。
Dim PP As double,Z As Double, ANS0 As Double,P0 As Double
Dim SPI As Double,D As Double,ANS As Double
SPI=Sqr(2.0*_System_PI)
PP=P
IF PP > 0.5 THEN LET PP=1-P
Z=Sqr(-2.0*Log(PP))
ANS0=Z-(0.27061*Z+2.30753)/((0.04481*Z+0.99229)*Z+1.0)
P0=1-Normsdist(ANS0)
D=Exp(ANS0^2/(-2))/SPI
ANS=ANS0+(P0-PP)/D
IF P >= 0.5 THEN Normsinv=ANS ELSE Normsinv=-ANS
End Function
}