generación de números aleatorios a partir de cython

8

Quiero hacer que mi programa de Python sea rápido usando cython, ¡pero mi ciclo interno todavía está haciendo llamadas lentas de Python al generador de números aleatorios! Hace varios años, alguien con el apoyo de Sage planteó este mismo problema y parecía que no había una buena solución en ese momento. No es conveniente para mí generar previamente una larga lista de muestras aleatorias porque en realidad estoy tomando muestras de varias distribuciones de una manera que está condicionada a muestras anteriores.

Aquí hay una publicación en el blog que explica cómo se corrigió esto al conectarse de cython a gsl:
http://pyinsci.blogspot.com/2010/12/efficient-mcmc-in-python-errata-and.html

Y una publicación de stackoverflow de alguien que intenta implementar el gsl kludge:
/programming/8177446/random-number-generators-to-work-on-x86-64

ninguna
fuente
No entiendo tu pregunta. Cython + GSL RNG es exactamente cómo implementaría esto. ¿Qué te gustaría de otra manera?
Aron Ahmadia
@Aron: Tal vez esa sea la respuesta a mi pregunta: que Cython + GSL RNG sigue siendo la mejor manera de hacerlo. ¿Qué me gustaría hacer de manera diferente? Me gustaría evitar la dependencia adicional de gsl y evitar la repetitiva que implica vincularlo, pero entiendo que la tecnología para esto aún no existe. Pero soy optimista de que estamos trabajando para lograrlo, por ejemplo con proyectos como github.com/twiecki/CythonGSL .
ninguno

Respuestas:

7

Cython acelera el código al eliminar la ambigüedad de tipo. Dado que random.py es un módulo de Python puro, puede copiarlo y agregar los tipos a las funciones que necesita. Entonces, Cython puede optimizar la sobrecarga dinámica.

aterrel
fuente
De hecho, estoy usando numpy.random, pero esta es una sugerencia interesante para copiar y cifrar el código en los paquetes que estoy usando.
ninguno
5

Siguiendo la sugerencia de aterrel, puede usar pyximportpara compilar automáticamente el randommódulo :

import pyximport
pyximport.install(pyimport=True)

import random

Sin embargo, esto aún no lo hará tan rápido como lo sería si declarara tipos estáticos para las variables en Cython.

Jim Garrison
fuente
1
¡Bienvenido al sitio, Jim! Gracias por la buena entrada fuera de la puerta de inicio :)
Aron Ahmadia
2

No estoy seguro de si se agregaron recientemente, pero parece que ahora hay formas fáciles de generar números aleatorios rápidamente sin demasiados gastos generales. De este artículo sobre simulaciones de Monte Carlo en cython podemos hacer

from libc.stdlib cimport rand, RAND_MAX
r = 1 + int(rand()/(RAND_MAX*6.0)) # random integer 1,...,6

Por lo que yo entiendo, no necesitas hacer nada especial al compilar.

Para la reproducibilidad durante las pruebas, puede establecer una semilla

# srand48(time(0)) # Do it this way in production
srand48(100) # For reproducibility in testing
emschorsch
fuente