Tengo un problema de muestreo simple, donde mi bucle interno se ve así:
v = sample_gamma(k, a)
donde sample_gamma
muestras de la distribución Gamma para formar una muestra de Dirichlet.
Funciona bien, pero para algunos valores de k / a, algunos de los flujos de cálculo aguas abajo.
Lo adapté para usar variables de espacio de registro:
v = log(sample_gamma(k, a))
Después de adaptar todo el resto del programa, funciona correctamente (al menos me da los mismos resultados exactos en casos de prueba). Sin embargo, es más lento que antes.
¿Hay alguna forma de muestrear directamente sin usar funciones lentas como ? Intenté buscar en Google para esto, pero ni siquiera sé si esta distribución tiene un nombre común (log-gamma?).Registro gamma ( )
sampling
gamma-distribution
luispedro
fuente
fuente
Respuestas:
Considere una pequeña forma parámetro cerca de 0, tal como α = 1 / 100 . En el rango entre 0 y α , e - α es aproximadamente 1 , por lo que el Gamma pdf es aproximadamente x α - 1 d x / Γ ( α ) . Esto se puede integrar a un CDF aproximado, F α ( x ) = x αα α = 1 / 100 α mi- α 1 Xα - 1rex / Γ ( α ) . Al invertirlo, vemos unapotencia1/α: un gran exponente. Paraα=1/100esto causa alguna posibilidad de underflow (un valor de doble precisión de menos de10-300, más o menos). Aquí hay una gráfica de la posibilidad de obtener un flujo inferior en función del logaritmo de base diez deα:Fα( x ) = xαα Γ ( α ) 1 / α α = 1 / 100 10- 300 α
Una solución es explotar esta aproximación para generar variables log (Gamma): en efecto, intente generar una variante Gamma y, si es demasiado pequeña, generar su logaritmo a partir de esta distribución de potencia aproximada (como se muestra a continuación). (Haga esto repetidamente hasta que el registro esté dentro del rango de flujo inferior, de modo que sea un sustituto válido para la variante de flujo inferior original). Para el cálculo de Dirichlet, reste el máximo de todos los logaritmos de cada uno de los valores de registro: esto reescala implícitamente todos Gamma varía para que no afecte los valores de Dirichlet. Trate cualquier registro resultante que sea demasiado pequeño (digamos, menor que -100) como el registro de un cero verdadero. Exponga los otros registros. Ahora puede continuar sin desbordamiento.
Esto llevará más tiempo que antes, ¡pero al menos funcionará!
Debido a que el parámetro de escala simplemente reescala la variante, no hay problema para acomodarla en estos procedimientos. Ni siquiera lo necesita si todos los parámetros de escala son iguales.
Editar
fuente
r
a
b
gsl_ran_gamma
gsl_rng_uniform_pos
_pos
Por lo tanto, puedo tomar el registro de la última expresión y usar
log()
pow()
fuente