(Da dieser Ansatz unabhängig von den anderen veröffentlichten Lösungen ist, einschließlich der von mir veröffentlichten, biete ich ihn als separate Antwort an.)
Sie können die genaue Verteilung in Sekunden (oder weniger) berechnen, sofern die Summe der ps klein ist.
Wir haben bereits Vorschläge gesehen, dass die Verteilung ungefähr Gauß (unter bestimmten Szenarien) oder Poisson (unter anderen Szenarien) sein könnte. In beiden Fällen wissen wir, dass der Mittelwert die Summe von und die Varianz die Summe von . Daher wird sich die Verteilung auf einige Standardabweichungen ihres Mittelwerts konzentrieren, beispielsweise auf SDs mit zwischen 4 und 6 oder so ungefähr . Daher müssen wir nur die Wahrscheinlichkeit berechnen, dass die Summe gleich (eine ganze Zahl) für bis . Wenn die meisten derp 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σpisind klein, ist ungefähr gleich (aber etwas kleiner als) . Um konservativ zu sein, können wir die Berechnung für im Intervall . Wenn zum Beispiel die Summe von gleich und gewählt wird, um die Schwänze gut abzudecken, müsste die Berechnung in abdecken = , das sind nur 28 Werte.σ2μkpi9z=6k[9-6 √[μ−zμ−−√,μ+zμ−−√]pi9z=6k[0,27][9−69–√,9+69–√][0,27]
Die Verteilung wird rekursiv berechnet . Sei die Verteilung der Summe der ersten dieser Bernoulli-Variablen. Für jedes von bis kann die Summe der ersten Variablen auf zwei sich gegenseitig ausschließende Arten gleich sein: Die Summe der ersten Variablen ist gleich und das ist oder die Summe der ersten Variablen ist gleich und das ist . Deshalb i j 0 i + 1 i + 1 j i j i + 1 st 0 i j - 1 i + 1 st 1fiij0i+1i+1jiji+1st0ij−1i+1st1
fi+1(j)=fi(j)(1−pi+1)+fi(j−1)pi+1.
Wir müssen diese Berechnung nur für das Integral im Intervall von bismax ( 0 , μ - z √j μ+z √max(0,μ−zμ−−√) μ+zμ−−√.
Wenn die meisten winzig sind (aber die immer noch mit angemessener Genauigkeit von unterscheidbar sind ), ist dieser Ansatz nicht von der großen Anhäufung von Gleitkomma-Rundungsfehlern geplagt, die in der zuvor veröffentlichten Lösung verwendet wurden. Daher ist keine Berechnung mit erweiterter Genauigkeit erforderlich. Beispiel: Eine Berechnung mit doppelter Genauigkeit für ein Array von Wahrscheinlichkeiten ( ) erfordert Berechnungen für Wahrscheinlichkeiten von Summen zwischen und 1 - p i 1 2 16 p i = 1 / ( i + 1 ) μ = 10,6676 0 31 3 × 10 - 15 z = 6 3,6 × 10 - 8pi1−pi1216pi=1/(i+1)μ=10.6676031) dauerte 0,1 Sekunden mit Mathematica 8 und 1-2 Sekunden mit Excel 2002 (beide erhielten die gleichen Antworten). Das Wiederholen mit vierfacher Genauigkeit (in Mathematica) dauerte ungefähr 2 Sekunden, änderte jedoch keine Antwort um mehr als das . Das Beenden der Verteilung bei SDs in den oberen Schwanz verlor nur der Gesamtwahrscheinlichkeit.3×10−15z=63.6×10−8
Eine weitere Berechnung für ein Array von 40.000 Zufallswerten mit doppelter Genauigkeit zwischen 0 und 0,001 ( ) dauerte mit Mathematica 0,08 Sekunden.μ=19.9093
Dieser Algorithmus ist parallelisierbar. Teilen Sie die Menge von einfach in disjunkte Teilmengen von ungefähr gleicher Größe auf, eine pro Prozessor. Berechnen Sie die Verteilung für jede Teilmenge und falten Sie dann die Ergebnisse zusammen (verwenden Sie FFT, wenn Sie möchten, obwohl diese Beschleunigung wahrscheinlich nicht erforderlich ist), um die vollständige Antwort zu erhalten. Dies macht es praktisch, auch zu verwenden, wenn groß wird, wenn Sie weit in die Schwänze schauen müssen ( groß) und / oder groß ist. μ z npiμzn
Das Timing für ein Array von Variablen mit Prozessoren skaliert als . Die Geschwindigkeit von Mathematica liegt in der Größenordnung von einer Million pro Sekunde. Zum Beispiel mit Prozessor, Variationen, eine Gesamtwahrscheinlichkeit von und Ausgehen zu Standardabweichungen in den oberen Schwanz, Millionen: einige Sekunden Rechenzeit. Wenn Sie dies kompilieren, können Sie die Leistung um zwei Größenordnungen beschleunigen.m O ( n ( μ + z √nmm=1n=20000μ=100z=6n(μ+z √O(n(μ+zμ−−√)/m)m=1n=20000μ=100z=6n(μ+zμ−−√)/m=3.2
Übrigens zeigten in diesen Testfällen Diagramme der Verteilung eindeutig eine positive Schiefe: Sie sind nicht normal.
Für das Protokoll ist hier eine Mathematica-Lösung:
pb[p_, z_] := Module[
{\[Mu] = Total[p]},
Fold[#1 - #2 Differences[Prepend[#1, 0]] &,
Prepend[ConstantArray[0, Ceiling[\[Mu] + Sqrt[\[Mu]] z]], 1], p]
]
( Hinweis: Die Farbcodierung, die von dieser Site angewendet wird, ist für Mathematica-Code bedeutungslos. Insbesondere sind die grauen Elemente keine Kommentare: Hier wird die gesamte Arbeit erledigt!)
Ein Beispiel für seine Verwendung ist
pb[RandomReal[{0, 0.001}, 40000], 8]
Bearbeiten
Eine R
Lösung ist in diesem Testfall zehnmal langsamer als Mathematica - vielleicht habe ich sie nicht optimal codiert - aber sie wird trotzdem schnell ausgeführt (ungefähr eine Sekunde):
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)