(Ponieważ takie podejście jest niezależne od innych opublikowanych rozwiązań, w tym jednego, które opublikowałem, oferuję je jako osobną odpowiedź).
Możesz obliczyć dokładny rozkład w sekundach (lub mniej), pod warunkiem, że suma wartości p jest niewielka.
Widzieliśmy już sugestie, że rozkład może być w przybliżeniu Gaussa (w niektórych scenariuszach) lub Poissona (w innych scenariuszach). W każdym razie wiemy, że jego średnia jest sumą a jej wariancja jest sumą . Dlatego rozkład będzie skoncentrowany w obrębie kilku standardowych odchyleń jego średniej, powiedzmy SD między 4 a 6 lub więcej. Dlatego musimy tylko obliczyć prawdopodobieństwo, że suma jest równa (liczba całkowita) dla do . Kiedy większość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σpisą małe, jest w przybliżeniu równa (ale nieco mniejsza niż) , więc aby zachować ostrożność, możemy wykonać obliczenia dla w przedziale . Na przykład, gdy suma wynosi i wybranie aby dobrze pokryć ogony, potrzebowalibyśmy obliczeń, aby pokryć w = , czyli tylko 28 wartości.σ2μkpi9z=6K[9-6 √[μ−zμ−−√,μ+zμ−−√]pi9z=6k[0,27][9−69–√,9+69–√][0,27]
Rozkład jest obliczany rekurencyjnie . Niech będzie rozkładem sumy pierwszego tych zmiennych Bernoulliego. Dla dowolnego od do suma pierwszych zmiennych może być równa na dwa wzajemnie wykluczające się sposoby: suma pierwszych zmiennych jest równa a wynosi w przeciwnym razie suma pierwszych zmiennych jest równa a wynosi . W związku z tym 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.
Musimy przeprowadzić to obliczenie dla całki w przedziale od domax ( 0 , μ - z √j μ+z √max(0,μ−zμ−−√) μ+zμ−−√.
Kiedy większość jest niewielkich (ale są nadal odróżnialne od z rozsądną precyzją), podejście to nie jest nękane ogromną kumulacją błędów zaokrągleń zmiennoprzecinkowych używanych w rozwiązaniu, które wcześniej opublikowałem. Dlatego obliczenia o zwiększonej precyzji nie są wymagane. Na przykład obliczenia o podwójnej precyzji dla tablicy prawdopodobieństw ( , wymagające obliczeń dla prawdopodobieństw sum od do 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) zajęło 0,1 sekundy w przypadku Mathematica 8 i 1-2 sekundy w programie Excel 2002 (oba uzyskały te same odpowiedzi). Powtarzanie go z poczwórną precyzją (w Mathematica) zajęło około 2 sekund, ale nie zmieniło żadnej odpowiedzi więcej niż . Zakończenie rozkładu przy SD w górny ogon straciło tylko całkowitego prawdopodobieństwa.3×10−15z=63.6×10−8
Kolejne obliczenia dla tablicy 40 000 losowych wartości podwójnej precyzji od 0 do 0,001 ( ) zajęło 0,08 sekundy dla Mathematica.μ=19.9093
Ten algorytm można zrównoleglać. Po prostu podziel zestaw na rozłączne podzbiory o mniej więcej równej wielkości, po jednym na procesor. Oblicz rozkład dla każdego podzbioru, a następnie zbierz wyniki (używając FFT, jeśli chcesz, chociaż to przyspieszenie prawdopodobnie nie jest konieczne), aby uzyskać pełną odpowiedź. To sprawia, że jest praktyczny w użyciu, nawet gdy staje się duży, gdy trzeba patrzeć daleko w ogony ( duże) i / lub jest duży. μ z npiμzn
Czas dla tablicy zmiennych z procesorami jest skalowany jako . Prędkość Mathematiki jest rzędu miliona na sekundę. Na przykład, przy procesorze, zmienia się, całkowite prawdopodobieństwo wynosi , a wychodząc na standardowych odchyleń w górnym ogonie, miliona: oblicz kilka sekund czasu obliczeniowego. Jeśli to skompilujesz, możesz przyspieszyć działanie o dwa rzędy wielkości.m O ( n ( μ + z √nmm=1n=20000μ=100z=6n(μ+z √O(n(μ+zμ−−√)/m)m=1n=20000μ=100z=6n(μ+zμ−−√)/m=3.2
Nawiasem mówiąc, w tych przypadkach testowych wykresy rozkładu wyraźnie pokazały pewną dodatnią skośność: nie są one normalne.
Dla przypomnienia, oto rozwiązanie 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]
]
( Uwaga: kodowanie kolorami stosowane przez tę stronę nie ma znaczenia dla kodu Mathematica. W szczególności szare elementy nie są komentarzami: tam cała praca jest wykonywana!)
Przykładem jego zastosowania jest
pb[RandomReal[{0, 0.001}, 40000], 8]
Edytować
R
Rozwiązaniem jest dziesięć razy wolniej niż Mathematica w tym przypadku testowego - być może nie zostały zakodowane go optymalnie - ale nadal wykonuje szybko (około jednej sekundy):
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)