Python: ¿Existe una alternativa más rápida para usar polyfromroots de numpy?
Utilizando Python, estoy iterando sobre una gran colección de conjuntos de raíces (representados como un array numpy bidimensional, en esencia), y formando cada vez el polinomio mónico que tiene el conjunto de raíces (llamado “roots”) como raíces, de la siguiente manera:
poly = np.polynomial.polynomial.polyfromroots(roots)
Sin embargo, mi código se ejecuta lentamente cuando el número de conjuntos de raíces es grande (alrededor de 40000), aunque cada conjunto de raíces en sí mismo es pequeño (contiene solo 4 raíces).
Por ejemplo, si ejecuto:
import timeit
SETUP_CODE = '''
import numpy as np'''
TEST_CODE = '''
N, n = 40000, 4
collection_roots = np.random.random((N,n)) + 1.j*np.random.random((N,n))
polynomials = np.zeros((N, n + 1), dtype=complex)
for k in range(N):
roots = collection_roots[k, :]
polynomials[k, :] = np.polynomial.polynomial.polyfromroots(roots)'''
print(timeit.timeit(setup=SETUP_CODE,
stmt=TEST_CODE,
number=1))
La salida en mi máquina relativamente antigua es de alrededor de 2,9 segundos. ¿Hay alguna manera de acelerar este trozo de código, dentro de Python?
Hay otros lugares en mi código que podrían beneficiarse de optimización. Por supuesto, podría crear publicaciones separadas, pero me ayudaría (y a otros) si alguien también pudiera publicar algunos recursos que encontró útiles para optimizar el código de Python para la computación científica.
davy.ai
Para acelerar el código dado en Python, podemos utilizar la función numpy.vectorize, la cual puede ser utilizada para vectorizar la función np.polynomial.polynomial.polyfromroots, lo que la hace mucho más rápida para calcular polinomios para grandes colecciones de raíces.
Para hacer esto, podemos definir una nueva función que llame a np.polynomial.polynomial.polyfromroots y luego vectorizarla usando numpy.vectorize. Aquí hay un ejemplo de código que demuestra cómo hacerlo:
En mi máquina, este código se ejecuta en alrededor de 0.3 segundos, lo que es casi 10 veces más rápido que la implementación original.
Existen varios recursos disponibles para optimizar el código Python para la computación científica. Algunos de ellos son:
Estos libros cubren diversas técnicas y mejores prácticas para optimizar el código Python, incluyendo el uso de numpy y la vectorización, el uso de Cython, el uso de multiprocessing y la paralelización, y la optimización del uso de memoria.