(Debido a que este enfoque es independiente de las otras soluciones publicadas, incluida una que he publicado, la estoy ofreciendo como respuesta por separado).
Puede calcular la distribución exacta en segundos (o menos) siempre que la suma de los p sea pequeña.
Ya hemos visto sugerencias de que la distribución podría ser aproximadamente gaussiana (en algunos escenarios) o Poisson (en otros escenarios). De cualquier manera, sabemos que su media es la suma de y su varianza es la suma de . Por lo tanto, la distribución se concentrará dentro de unas pocas desviaciones estándar de su media, digamos SD con entre 4 y 6 o más o menos. Por lo tanto, solo necesitamos calcular la probabilidad de que la suma igual (un número entero) para través de . Cuando la mayoría de losp 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σpison pequeños, es aproximadamente igual (pero ligeramente menor que) , por lo que para ser conservadores podemos hacer el cálculo de en el intervalo . Por ejemplo, cuando la suma de es igual a y elige para cubrir bien las colas, necesitaríamos el cálculo para cubrir en = , que son solo 28 valores.σ2μkpi9z=6k[9-6 √[μ−zμ−−√,μ+zμ−−√]pi9z=6k[0,27][9−69–√,9+69–√][0,27]
La distribución se calcula de forma recursiva . Sea la distribución de la suma de la primera de estas variables de Bernoulli. Para cualquier desde hasta , la suma de las primeras variables puede ser igual a de dos maneras mutuamente excluyentes: la suma de las primeras variables es igual a y el es o bien la suma de las primeras variables es igual a y el es . Por lo tanto 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.
Solo necesitamos realizar este cálculo para la integral en el intervalo de amax ( 0 , μ - z √j μ+z √max(0,μ−zμ−−√) μ+zμ−−√.
Cuando la mayoría de los son pequeños (pero el aún se distinguen de con una precisión razonable), este enfoque no está plagado de la gran acumulación de errores de redondeo de coma flotante utilizados en la solución que publiqué anteriormente. Por lo tanto, no se requiere computación de precisión extendida. Por ejemplo, un cálculo de doble precisión para una matriz de probabilidades ( , que requiere cálculos para las probabilidades de sumas entre y 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) tardó 0.1 segundos con Mathematica 8 y 1-2 segundos con Excel 2002 (ambos obtuvieron las mismas respuestas). Repetirlo con precisión cuádruple (en Mathematica) tomó aproximadamente 2 segundos pero no cambió ninguna respuesta en más de . Terminar la distribución en SD en la cola superior perdió solo de la probabilidad total.3×10−15z=63.6×10−8
Otro cálculo para una matriz de 40,000 valores aleatorios de doble precisión entre 0 y 0.001 ( ) tomó 0.08 segundos con Mathematica.μ=19.9093
Este algoritmo es paralelo. Simplemente divida el conjunto de en subconjuntos disjuntos de aproximadamente el mismo tamaño, uno por procesador. Calcule la distribución para cada subconjunto, luego involucre los resultados (usando FFT si lo desea, aunque esta aceleración probablemente sea innecesaria) para obtener la respuesta completa. Esto hace que sea práctico usarlo incluso cuando hace grande, cuando necesita mirar hacia adentro de las colas ( grande), y / o es grande. μ z npiμzn
El tiempo para una matriz de variables con procesadores se escala como . La velocidad de Mathematica es del orden de un millón por segundo. Por ejemplo, con procesador, variantes, una probabilidad total de y salir a desviaciones estándar en la cola superior, millones: calcula un par de segundos de tiempo de cálculo. Si compila esto, podría acelerar el rendimiento dos órdenes de magnitud.m O ( n ( μ + z √nmm=1n=20000μ=100z=6n(μ+z √O(n(μ+zμ−−√)/m)m=1n=20000μ=100z=6n(μ+zμ−−√)/m=3.2
Por cierto, en estos casos de prueba, los gráficos de la distribución mostraron claramente cierta asimetría positiva: no son normales.
Para el registro, aquí hay una solución de 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]
]
( Nota : la codificación de colores aplicada por este sitio no tiene sentido para el código de Mathematica. En particular, lo gris no son comentarios: ¡es donde se hace todo el trabajo!)
Un ejemplo de su uso es
pb[RandomReal[{0, 0.001}, 40000], 8]
Editar
Una R
solución es diez veces más lenta que Mathematica en este caso de prueba, tal vez no la he codificado de manera óptima, pero aún se ejecuta rápidamente (aproximadamente un segundo):
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)