Tengo dos gráficos con casi n ~ 100000 nodos cada uno. En ambos gráficos, cada nodo está conectado a exactamente otros 3 nodos, por lo que la matriz de adyacencia es simétrica y muy escasa.
La parte difícil es que necesito todos los valores propios de la matriz de adyacencia pero no los vectores propios. Para ser exactos, esto será una vez en mi vida (¡hasta donde puedo ver, al menos!), Así que quiero obtener todos los valores propios y no me importa esperar unos días para obtenerlos.
Intenté scipy
envoltorios ARPACK
, pero lleva demasiado tiempo. Encontré varias bibliotecas, pero funcionan mejor para obtener un subconjunto de valores propios más grandes / más pequeños. ¿Hay alguna biblioteca que funcione para matrices dispersas simétricas con implementación posiblemente paralela para obtener todos los valores propios?
Respuestas:
Puede usar la transformación espectral shift-invert [1] y calcular el espectro banda por banda.
La técnica también se explica en mi artículo [2]. Además de la implementación en [1], hay una implementación disponible en C ++ en mi software Graphite [3] ( actualización 17 de enero : ahora todo está portado a la versión 3 de geogram / graphite ), que utilicé para calcular las funciones propias del operador de Laplace para mallas con hasta 1 millón de vértices (un problema similar al suyo).
Cómo funciona:
La idea es que si es invertible, entonces si es un par propio de , es un par propio de . El método iterativo en ARPACK es muy eficiente para calcular los valores propios grandes (frecuencias altas), pero mucho menos eficiente para los pequeños (frecuencias pequeñas). Por lo tanto, cuando uno necesita calcular frecuencias pequeñas, es una buena idea reemplazar con . Ahora, dado que ARPACK solo necesita calcular productos de vectores de matriz, no es necesario invertir realmente : en su lugar, se puede factorizar (usando, por ejemplo, una LU escasa o una factorización escasa ), luego resolverUN ( V, λ ) UN ( V, 1 / λ ) UN- 1 UN UN- 1 UN L Lt A x = b cada vez que ARPACK solicita un producto matriz-vector. Esta es la transformación "invertida". Ahora, cuando el número de valores propios se vuelve grande, ARPACK se vuelve lento, pero hay otro truco / transformación que se puede usar, y uno calcula los valores propios de donde es un "cambio" que determina qué parte del espectro es explorado (esta es la transformación "shift"). Combinando ambas transformaciones, uno calcula un cierto número de valores propios de , y luego explora todo el espectro banda por banda, aumentando . Los detalles están en [1], [2].A - σyore σ ( A - σyore)- 1 σ
[1] http://www.mcs.anl.gov/uploads/cels/papers/P1263.pdf
[2] http://alice.loria.fr/index.php/publications.html?redirect=0&Paper=ManifoldHarmonics@2008
[3] http://alice.loria.fr/software/graphite/doc/html/
fuente
Otra opción sería usar rotaciones de Jacobi. Como su matriz ya es casi diagonal, no debería tomar mucho tiempo converger. Generalmente converge en velocidad lineal, pero después de suficientes iteraciones la velocidad de convergencia se vuelve cuadrática.
fuente