(これは、私が投稿したものを含め、投稿された他のソリューションとは独立したアプローチであるため、個別の回答として提供しています)。
pの合計が小さい場合、正確な分布を秒(またはそれ以下)で計算できます。
分布は、ほぼガウス分布(一部のシナリオでは)またはポアソン(他のシナリオでは)である可能性があるという提案を見てきました。いずれにしても、その平均はの合計であり、その分散は合計です。従って分布がその平均値の数の標準偏差内で濃縮され、言う用いたSDS 4および6またはその近傍との間を。したがって、からの合計が(整数)等しい確率を計算するだけです。ほとんどのP I σ 2 P I(1 - P I)Z 、Z 、X 、K 、K = μ - Z σ K = μ + Z σ P I σ 2 μ K [ μ - Z √μpiσ2pi(1−pi)zzXkk=μ−zσk=μ+zσpi、小さいほぼ等しい(わずか未満)されているので、我々は、計算を行うことができ、保存的であることが、間隔で。和場合、例えば、等しく及び選択ウェルテールをカバーするために、我々は、カバーに計算を必要とするであろうで =、これはわずか28の値です。σ2μkPI9、Z=6、K[9-6 √[μ−zμ−−√,μ+zμ−−√]pi9z=6k[0、27][9−69–√,9+69–√][0,27]
分布は再帰的に計算されます。みましょう最初の和の分布でこれらベルヌーイ変数の。いずれかのためにからを介して、最初の和の変数は等しくすることができる二つの相互に排他的な方法で、第一の和変数が等しいとであるまたは、最初の個の変数の合計が等しく、がです。だから i j 0 i + 1 i + 1 j i j i i + 1 st 0 i j − 1fiij0i+1i+1jiji+1st0ij−1 1i+1st1
fi+1(j)=fi(j)(1−pi+1)+fi(j−1)pi+1.
この計算は 、からの区間の積分に対してのみ実行する必要がありj max(0,μ−zμ−−√) μ+zμ−−√.
ほとんどのが小さい場合(ただし、はと妥当な精度でまだ区別可能)、このアプローチは、以前に投稿したソリューションで使用された浮動小数点丸め誤差の膨大な蓄積に悩まされません。したがって、拡張精度の計算は必要ありません。例えば、アレイのための倍精度演算確率(間の和の確率の計算が必要な、とpi1−pi1216pi=1/(i+1)μ=10.6676031)Mathematica 8では0.1秒、Excel 2002では1〜2秒かかりました(どちらも同じ回答を得ました)。(Mathematicaで)4倍の精度でそれを繰り返すのに約2秒かかりましたが、超えて答えを変更しませんでした。 SD での分布をアッパーテールで終了すると、合計確率のだけが失われました。3×10−15z=63.6×10−8
0から0.001()の間の40,000倍精度ランダム値の配列の別の計算には、Mathematicaで0.08秒かかりました。μ=19.9093
このアルゴリズムは並列化可能です。のセットを、プロセッサごとに1つ、ほぼ等しいサイズの互いに素なサブセットに分割するだけです。各サブセットの分布を計算し、結果を畳み込んで(必要に応じてFFTを使用しますが、この高速化はおそらく不要ですが)、完全な答えを取得します。これにより、が大きくなったとき、尾を遠くに見なければならないとき(大きい)、および/またはが大きいときでも実用的です。piμzn
個のプロセッサを持つ変数の配列のタイミングは、としてスケーリングされます。Mathematicaの速度は毎秒百万のオーダーです。たとえば、プロセッサ、変量、合計確率、標準偏差が上裾に出る場合、万:数秒の計算時間を計算します。これをコンパイルすると、パフォーマンスが2桁速くなる可能性があります。nmO(n(μ+zμ−−√)/m)m=1n=20000μ=100z=6n(μ+zμ−−√)/m=3.2
ちなみに、これらのテストケースでは、分布のグラフは明らかに正の歪度を示しました。これらは正常ではありません。
記録のために、ここにMathematicaソリューションがあります:
pb[p_, z_] := Module[
{\[Mu] = Total[p]},
Fold[#1 - #2 Differences[Prepend[#1, 0]] &,
Prepend[ConstantArray[0, Ceiling[\[Mu] + Sqrt[\[Mu]] z]], 1], p]
]
(NBこのサイトで適用されている色分けはMathematicaコードにとって無意味です。特に、灰色のものはコメントではありません。すべての作業が行われる場所です!)
その使用例は次のとおりです。
pb[RandomReal[{0, 0.001}, 40000], 8]
編集
R
解決策は、10倍よりも遅いですMathematicaに、おそらく私が最適にそれをコーディングしていない- -このテストケースでは、それはまだ(1秒程度)早く実行します。
pb <- function(p, z) {
mu <- sum(p)
x <- c(1, rep(0, ceiling(mu + sqrt(mu) * z)))
f <- function(v) {x <<- x - v * diff(c(0, x));}
sapply(p, f); x
}
y <- pb(runif(40000, 0, 0.001), 8)
plot(y)