¿Cuál es la forma más rápida de calcular todos los valores propios de una matriz de adyacencia muy grande y escasa en Python?

12

Estoy tratando de averiguar si hay una forma más rápida de calcular todos los valores propios y vectores propios de una matriz de adyacencia muy grande y dispersa que usando scipy.sparse.linalg.eigsh Hasta donde sé, este método solo usa la dispersión y atributos de simetría de la matriz. Una matriz de adyacencia también es binaria, lo que me hace pensar que hay una forma más rápida de hacerlo.

Creé una matriz de adyacencia dispersa aleatoria de 1000x1000, y la comparé entre varios métodos en mi laptop x230 ubuntu 13.04:

  • scipy.sparse.linalg.eigs: 0.65 segundos
  • scipy.sparse.linalg.eigsh: 0.44 segundos
  • scipy.linalg.eig: 6.09 segundos
  • scipy.linalg.eigh: 1.60 segundos

Con los escasos eigs y eigsh, establecí k, el número de los valores propios y vectores propios deseados, para que sea el rango de la matriz.

El problema comienza con matrices más grandes: en una matriz de 9000x9000, scipy.sparse.linalg.eigsh tardó 45 minutos.

Noam pelado
fuente
1
NÓTESE BIEN. scipy.sparse.linalg.eigsh es ARPACK
pv.
44
Para el seguimiento, cuanto más grande sea su matriz, menos probable es que calcule valores propios interiores (es decir, ni los valores propios más grandes ni los más pequeños) con precisión. ¿Qué información necesita de la matriz que está descomponiendo?
Geoff Oxberry
1
Esta pregunta ha sido publicada aquí . Voy a recomendar que la versión de publicación cruzada esté cerrada.
Aron Ahmadia
2
Quiero calcular A ^ k. Después de repensar, creo que con una matriz de este tipo es mucho más rápido calcular la multiplicación directa (A A A ...) que usar la descomposición propia. Por supuesto, depende de k.
Noam Peled
2
Sí, hazlo directamente. Los resultados de la descomposición propia no son escasos, por lo que tendrá problemas de almacenamiento (de nuevo, tampoco lo es A ^ k si k es lo suficientemente grande). Relacionados stackoverflow.com/a/9495457/424631
dranxo

Respuestas:

6

FILTLAN es una biblioteca C ++ para calcular valores propios interiores de matrices simétricas dispersas. El hecho de que haya un paquete completo dedicado solo a esto debería decirle que es un problema bastante difícil. Encontrar los valores propios más pequeños o más pequeños de una matriz simétrica se puede hacer cambiando / invirtiendo y utilizando el algoritmo de Lanczos, pero la mitad del espectro es otra cuestión. Si desea usar esto, puede usar SWIG para llamar a un programa C ++ desde python.

Si su objetivo final es calcular grandes potencias de la matriz, simplemente podría calcular los vectores propios correspondientes a los valores propios más grandes, contenido sabiendo que los modos más pequeños serán menos importantes a medida que tome grandes potencias.

k

Perdóneme si esto ya es obvio para usted: puede explotar la naturaleza binaria de la matriz diciéndole a numpy que consta de enteros en lugar de flotantes, digamos usando

a = np.zeros(100,dtype=np.uint)

A16A2A4A8log2kk

También puede explorar llamar a una biblioteca de álgebra lineal dispersa paralela como CUSP o cuSPARSE desde Python si le preocupa la velocidad y tiene una GPU NVIDIA.

Daniel Shapero
fuente
1

Me gustaría comentar la respuesta de Daniel Shapero pero no tengo suficiente reputación SE.

La respuesta aceptada me confunde mucho. Creo que el modo shift-invert puede usarse fácilmente para calcular valores propios interiores. Ver: https://docs.scipy.org/doc/scipy/reference/tutorial/arpack.html

Para responder a la pregunta original: rara vez es el caso que desee todos los valores propios de una matriz dispersa grande. Por lo general, desea extremos o algún grupo de valores interiores. En ese caso, para una matriz hermitiana eigshes más rápido. Para los no ermitaños, tendrás que ir con ellos eigs. Y son mucho más rápidos que numpy eigo eigh.

Alex
fuente