Comprendere come Numpy fa SVD


13

Ho usato diversi metodi per calcolare sia il rango di una matrice sia la soluzione di un sistema di equazioni a matrice. Mi sono imbattuto nella funzione linalg.svd. Confrontando questo con il mio sforzo di risolvere il sistema con l'eliminazione gaussiana, sembra essere sia più veloce che più preciso. Sto cercando di capire come sia possibile.

Per quanto ne so, la funzione linalg.svd utilizza un algoritmo QR per calcolare gli autovalori della mia matrice. So come funziona matematicamente, ma non so come Numpy riesca a farlo così rapidamente e senza perdere molta precisione.

Quindi la mia domanda: come funziona la funzione numpy.svd e, più specificamente, come riesce a farlo in modo rapido e preciso (rispetto all'eliminazione gaussiana)?


2
numpy utilizza la routine Lapack dgesddper SVD con valori reali. Quindi la tua vera domanda è probabilmente "come funziona Lapack dgesdd?", Ed è piuttosto fuori tema per StackOverflow.
Talonmies

Se sei davvero curioso, suggerirei di esaminare la fonte LAPACK.

Grazie per i vostri commenti e le mie scuse sono offtopico.
RobVerheyen,

Questo post è un cross-post da StackTranslate.it . Il cross-posting è generalmente sconsigliato sui siti di Stack Exchange. Il protocollo standard per ripubblicare una domanda su un altro sito è chiudere, eliminare o migrare il post originale prima di tentare di ripubblicare su un altro sito. (Se migra la domanda, viene ripubblicata automaticamente.)
Geoff Oxberry

Mi dispiace, non ero a conoscenza del protocollo. Spero di poter ancora ottenere una risposta.
RobVerheyen,

Risposte:


15

Ci sono una serie di problemi nella tua domanda.

Non utilizzare l'eliminazione gaussiana (fattorizzazione LU) per calcolare il rango numerico di una matrice. La fattorizzazione LU non è affidabile per questo scopo nell'aritmetica in virgola mobile. Invece, usa una decomposizione QR rivelatrice di rango (come xGEQPXo xGEPQYin LAPACK, dove x è C, D, S o Z, anche se quelle routine sono difficili da rintracciare; vedi la risposta di JedBrown su una domanda correlata ) o usa un SVD (decomposizione del valore singolare, come xGESDDo xGESVD, dove x è di nuovo C, D, S o Z). SVD è un algoritmo più preciso e affidabile per la determinazione del rango numerico, ma richiede più operazioni in virgola mobile.

Tuttavia, per risolvere un sistema lineare, la fattorizzazione LU (con pivot parziale, che è l'implementazione standard in LAPACK) è estremamente affidabile nella pratica. Ci sono alcuni casi patologici per i quali la fattorizzazione LU con pivot parziale è instabile (vedi lezione 22 in Algebra lineare numericadi Trefethen e Bau per i dettagli). La fattorizzazione QR è un algoritmo numerico più stabile per risolvere i sistemi lineari, motivo per cui ti dà risultati così precisi. Tuttavia, richiede più operazioni in virgola mobile rispetto alla fattorizzazione LU di un fattore 2 per le matrici quadrate (credo; JackPoulson potrebbe correggermi su questo). Per i sistemi rettangolari, la fattorizzazione QR è una scelta migliore perché produrrà soluzioni dei minimi quadrati a sistemi lineari non determinati. SVD può anche essere usato per risolvere sistemi lineari, ma sarà più costoso della fattorizzazione QR.

janneb ha ragione che numpy.linalg.svd è un wrapper xGESDDin LAPACK. Le scomposizioni di valori singolari procedono in due fasi. Innanzitutto, la matrice da scomporre viene ridotta in forma bidiagonale. L'algoritmo utilizzato per ridurre in forma bidiagonale in LAPACK è probabilmente l'algoritmo Lawson-Hanson-Chan, e utilizza la fattorizzazione QR in un punto. La lezione 31 in Algebra lineare numerica di Trefethen e Bau offre una panoramica di questo processo. Quindi, xGESDDutilizza un algoritmo di divisione e conquista per calcolare i valori singolari e i vettori singolari sinistro e destro dalla matrice bidiagonale. Per ottenere informazioni su questo passaggio, è necessario consultare Matrix Computations di Golub e Van Loan, o Applied Numerical Linear Algebra di Jim Demmel.

Infine, non dovresti confondere i valori singolari con gli autovalori . Queste due serie di quantità non sono uguali. SVD calcola i valori singolari di una matrice. Il calcolo numerico di Cleve Moler con MATLAB offre una buona panoramica delle differenze tra valori singolari ed autovalori . In generale, non esiste una relazione evidente tra i valori singolari di una data matrice e i suoi autovalori, tranne nel caso di matrici normali , dove i valori singolari sono il valore assoluto degli autovalori.


Penso che "non correlato" sia piuttosto forte per la relazione tra autovalori e valori singolari. La relazione è piuttosto oscura a meno che tu non conosca la completa decomposizione Jordan della tua matrice, ma puoi usarne una per ottenere stime dell'altra se hai informazioni (o sei disposto a fare ipotesi) su detta decomposizione Jordan.
Dan

Cosa suggeriresti invece?
Geoff Oxberry,

Prima di tutto, grazie per la risposta elaborata. Ho scoperto che non posso usare la decomposizione LU per determinare il grado di matrice nel modo più duro. La tua risposta sembra implicare che la fattorizzazione QR sarebbe in realtà un metodo più veloce per risolvere il mio problema, giusto? C'è un netto vantaggio nell'uso di SVD? Ero ben consapevole del fatto che i valori singolari non sono autovalori. Mi riferivo al fatto che i valori singolari possono essere calcolati come autovalori della matrice moltiplicati per la sua trasposizione da sinistra. Mi dispiace che non fosse chiaro.
RobVerheyen,

Potrei aggiungere che la matrice che sto risolvendo è in realtà singolare. In effetti, il rango della matrice è solo circa la metà della dimensione della matrice. Forse questo rende un metodo più preferibile?
RobVerheyen,

1
@RobVerheyen: QR sarà più lento di LU, ma considerevolmente più preciso. SVD sarà anche più lento di QR, ma SVD è considerato il metodo più affidabile per determinare il rango numerico (ad esempio, MATLAB utilizza SVD nella sua rankfunzione). C'è anche un po 'di discrezione quando si utilizza uno dei due approcci; nell'approccio SVD, il rango numerico è il numero di valori singolari al di sopra di un valore soglia specificato (di solito molto piccolo). (L'approccio QR è simile, ma sostituisce i valori singolari con voci diagonali della matrice R.)
Geoff Oxberry

8

A causa della formulazione della tua domanda, presumo che la tua matrice sia quadrata. Le routine SVD di LAPACK, come zgesvd , procedono essenzialmente in tre fasi per le matrici quadrate:

  1. UUNVUNUNB: =UUNHUNVUNUUNVUNBO(n3)
  2. {UB,VB,Σ}B=UBΣVBHO(n2)O(n3)
  3. UUNBVUNH=UNUN=(UUNUB)Σ(VUNVB)HUUNVUNUBVBO(n3)

7

numpy.linalg.svd è un wrapper intorno a {Z, D} GESDD da LAPACK. LAPACK, a sua volta, è scritto con molta attenzione da alcuni dei maggiori esperti mondiali di algebra lineare numerica. In effetti, sarebbe molto sorprendente se qualcuno che non avesse familiarità con il campo riuscisse a battere LAPACK (sia in velocità che in precisione).

Per quanto riguarda il motivo per cui QR è meglio dell'eliminazione gaussiana, questo è probabilmente più appropriato per /scicomp//


Grazie per la risposta e il riferimento. Lo proverò laggiù.
RobVerheyen,
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.