Cálculo de los valores propios más pequeños de la matriz dispersa en Python

Me gustaría encontrar los N valores más pequeños de una matriz dispersa en Python. He intentado usar el paquete scipy.sparse.linalg.eigen.arpack , pero es muy lento para calcular los valores propios más pequeños. Leí en algún lugar que hay un modo de inversión de cambio, pero cuando bash usarlo, recibo un mensaje de error que me indica que el modo de inversión de cambio aún no es compatible. ¿Alguna idea de cómo debo proceder?

Versiones de SciPy

Al comparar la documentación de scipy.sparse.linalg.eigs de SciPy v0.9 con la documentación de scipy.sparse.linalg.eigs de SciPy v0.10 , parece que el modo de cambio de inversión está implementado y funciona desde v0.10. Específicamente, la explicación del parámetro sigma en la documentación v0.9 indica que no está implementado, pero la documentación v0.10 no indica que ese sea el caso.

Si no tiene SciPy v0.10, o posterior, la instalación de la última debería permitirle utilizar el modo de inversión de desplazamiento con el dispersor de pantalla disperso.

Detección lenta de valores propios de pequeña magnitud

Como se mencionó en la pregunta, es posible utilizar la interfaz ARPACK para encontrar valores propios de pequeña magnitud. Esto se hace al pasar lo which='SM' cuando se llama a scipy.sparse.linalg.eigs . Es, sin embargo, como se afirma en la pregunta, lento. Esto se confirma en la sección Tutorial de ciencia ficción sobre problemas de valores propios dispersos con ARPACK , donde dice:

Tenga en cuenta que ARPACK generalmente es mejor para encontrar valores propios extremos: es decir, valores propios con grandes magnitudes. En particular, el uso de which = 'SM' puede llevar a un tiempo de ejecución lento y / o resultados anómalos. Un mejor enfoque es utilizar el modo de inversión de cambio .

Experimentos

Veamos algunos códigos que intentan usar shift-invert con v0.9 y v0.10 de SciPy. En ambos casos, utilizaremos el siguiente código.

 from scipy.sparse import identity from scipy.sparse.linalg import eigs A = identity(10, format='csc') A.setdiag(range(1, 11)) eigs(A, 3, sigma=0) # find three eigenvalues near zero using shift-invert mode 

SciPy v0.9

Ejecutar el código en SciPy v0.9 hace que se genere una excepción.

 NotImplementedError: shifted eigenproblem not supported yet 

Ciencia v0.10

Ejecutar el código en SciPy 0.10 produce los resultados esperados.

 (array([ 1.+0.j, 2.+0.j, 3.+0.j]), array([[ -1.00000000e+00+0.j, 5.96300068e-17+0.j, 9.95488924e-17+0.j], [ 3.55591776e-17+0.j, 1.00000000e+00+0.j, -4.88997616e-16+0.j], [ -3.79110898e-17+0.j, 1.16635626e-16+0.j, 1.00000000e+00+0.j], [ -1.08397454e-17+0.j, 1.23544164e-17+0.j, 1.78854096e-15+0.j], [ 1.68486368e-17+0.j, -9.37965967e-18+0.j, 2.05571432e-16+0.j], [ -2.97859557e-19+0.j, -3.43100887e-18+0.j, 3.35947574e-17+0.j], [ 1.89565432e-17+0.j, -3.61479402e-17+0.j, -1.33021453e-17+0.j], [ -1.40925577e-18+0.j, 3.16953070e-18+0.j, 7.91193025e-17+0.j], [ 6.76947854e-19+0.j, -3.75674631e-19+0.j, 3.61821551e-17+0.j], [ -3.07505146e-17+0.j, -6.52050102e-17+0.j, -8.57423599e-16+0.j]]))