Qual è il modo più veloce per calcolare tutti gli autovalori di una matrice di adiacenza molto grande e sparsa in Python?


12

Sto cercando di capire se esiste un modo più veloce per calcolare tutti gli autovalori e gli autovettori di una matrice di adiacenza molto grande e sparsa rispetto all'uso di scipy.sparse.linalg.eigsh Per quanto ne so, questo metodo utilizza solo la scarsità e attributi di simmetria della matrice. Una matrice di adiacenza è anche binaria, ciò che mi fa pensare che ci sia un modo più veloce per farlo.

Ho creato una matrice sparsa di adiacenza 1000x1000 e confrontata tra diversi metodi sul mio laptop Ubuntu 13.04 x230:

  • scipy.sparse.linalg.eigs: 0,65 secondi
  • scipy.sparse.linalg.eigsh: 0.44 secondi
  • scipy.linalg.eig: 6,09 secondi
  • scipy.linalg.eigh: 1,60 secondi

Con gli eigs e gli eigsh sparsi, ho impostato k, il numero degli autovalori e degli autovettori desiderati, per essere il rango della matrice.

Il problema inizia con matrici più grandi - su una matrice 9000x9000, ci sono voluti scipy.sparse.linalg.eigsh 45 minuti!


1
NB. scipy.sparse.linalg.eigsh è ARPACK
pv.

4
Per dare seguito, più grande è la tua matrice, minore è la probabilità di calcolare con precisione gli autovalori interni (ovvero, gli autovalori più grandi o più piccoli). Di quali informazioni hai bisogno dalla matrice che stai decomponendo?
Geoff Oxberry,

1
Questa domanda è stata inviata qui . Raccomanderò che la versione cross-post sia chiusa.
Aron Ahmadia,

2
Voglio calcolare A ^ k. Dopo aver ripensato, penso che con una tale matrice sia molto più veloce calcolare la moltiplicazione diretta (A A A ...) piuttosto che usare la composizione elettronica. Certo, dipende da k.
Noam Peled,

2
Sì, fallo direttamente. I risultati della composizione elettronica non sono scarsi, quindi si avranno problemi di archiviazione (quindi, nemmeno A ^ k se k è abbastanza grande). Correlati stackoverflow.com/a/9495457/424631
dranxo

Risposte:


6

FILTLAN è una libreria C ++ per il calcolo di autovalori interni di matrici simmetriche sparse. Il fatto che ci sia un intero pacchetto dedicato solo a questo dovrebbe dirti che è un problema piuttosto difficile. Trovare gli autovalori più piccoli o più piccoli di una matrice simmetrica può essere fatto spostando / invertendo e usando l'algoritmo di Lanczos, ma il centro dello spettro è un'altra questione. Se vuoi usarlo, puoi usare SWIG per chiamare un programma C ++ da Python.

Se il tuo obiettivo finale è calcolare grandi poteri della matrice, potresti semplicemente calcolare autovettori corrispondenti ai più grandi autovalori, contento nella consapevolezza che le modalità più piccole saranno meno importanti quando prendi grandi poteri.

Detto questo, potresti davvero fare meglio a calcolare i poteri direttamente. Man mano che calcolerai poteri superiori, diventeranno sempre meno radi, il che significa occupare più memoria; a seconda di quanto sia alto , potresti eventualmente passare a una matrice densa.k

Perdonami se questi sono già ovvi per te: puoi sfruttare la natura binaria della matrice dicendo intorpidito che è costituito da numeri interi anziché da float, per esempio usando

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

Questo (si spera) farà risparmiare un po 'di spazio. Puoi risparmiare tempo (ma non memoria) bloccando le moltiplicazioni della matrice. Supponiamo che tu voglia calcolare ; si calcola , quindi si quadrano per ottenere , si quadrano per ottenere e così via. In questo modo, fai moltiplicazioni di matrici anziché moltiplicazioni. A 2 A 4 A 8log 2 k kA16A2A4A8log2kk

Puoi anche esplorare chiamando una libreria di algebra lineare sparsa parallela come CUSP o cuSPARSE da Python se la velocità è la tua preoccupazione e hai una GPU NVIDIA.


1

Vorrei commentare la risposta di Daniel Shapero, ma non ho abbastanza reputazione SE.

La risposta accettata mi confonde molto. Penso che la modalità shift-invert possa essere facilmente usata per calcolare gli autovalori interni. Vedi: https://docs.scipy.org/doc/scipy/reference/tutorial/arpack.html

Per rispondere alla domanda originale: raramente si vogliono tutti gli autovalori di una matrice sparsa di grandi dimensioni. Di solito, si desidera extrem o un gruppo di valori interni. In tal caso, per una matrice eremitica eigshè più veloce. Per i non eremiti, dovrai andare con eigs. E sono molto più veloci di intorpiditi eigo eigh.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.