Deseo implementar la siguiente expresión en Python: donde e son matrices numpy de tamaño , y es una matriz numpy de tamaño . El tamaño puede ser de hasta aproximadamente 10000, y la función es parte de un bucle interno que se evaluará muchas veces, por lo que la velocidad es importante.
Idealmente, me gustaría evitar un ciclo for por completo, aunque supongo que no es el fin del mundo si hay uno. El problema es que tengo problemas para ver cómo hacerlo sin tener un par de bucles anidados, y eso probablemente lo haga bastante lento.
¿Alguien puede ver cómo expresar la ecuación anterior usando numpy de una manera que sea eficiente y preferiblemente también legible? En términos más generales, ¿cuál es la mejor manera de abordar este tipo de cosas?
Respuestas:
Aquí está la solución de Numba. En mi máquina, la versión de Numba es> 1000 veces más rápida que la versión de Python sin el decorador (para una matriz de 200x200, 'k' y un vector de longitud de 200 'a'). También puede usar el decorador @autojit que agrega aproximadamente 10 microsegundos por llamada para que el mismo código funcione con varios tipos.
Divulgación: Soy uno de los desarrolladores de Numba.
fuente
Aquí hay un comienzo. Primero, mis disculpas por cualquier error.
Editar: No, el límite superior era correcto según lo dispuesto en la pregunta. Lo dejé como está aquí porque otra respuesta ahora usa el mismo código, pero la solución es simple.
Primero una versión en bucle:
Hice un solo bucle con rodajas numpy:
Luego escribí una versión de Cython del código en bucle (más legible).
En mi computadora portátil, esta es aproximadamente 200 veces más rápida que la versión en bucle (y 8 veces más rápida que la versión vectorizada de 1 bucle). Estoy seguro de que otros pueden hacerlo mejor.
Jugué con una versión de Julia, y parecía (si lo cronometraba correctamente) comparable al código de Cython.
fuente
Lo que quieres parece ser una convolución; Creo que la forma más rápida de lograrlo sería la
numpy.convolve
función.Es posible que deba corregir los índices de acuerdo con sus necesidades exactas, pero creo que le gustaría probar algo como:
fuente