Risolve ripetutamente


12

Sto usando MATLAB per risolvere un problema che comporta la risoluzione di in ogni momento, dove b cambia nel tempo. In questo momento, sto realizzando questo usando MATLAB :Ax=bbmldivide

x = A\b

Ho la flessibilità di effettuare tutti i precomputamenti necessari, quindi mi chiedo se esiste un metodo più veloce e / o più accurato di mldivide. Cosa si fa di solito qui? Ringrazia tutti!


1
Hai una conoscenza specifica della struttura di ? Ad esempio, è simmetrico? Definito positivo? Tridiagonali? Ortogonale? A
Dominique,

La matrice è una densa matrice quadrata. A
Dubbio,

3
Se non hai altre conoscenze su , la fattorizzazione L U come descritto nella risposta di seguito è la soluzione migliore. ALU
Dominique,

Risposte:


14

La cosa più ovvia che puoi fare è pre-calcolare

[L,U] = lu(A) ~ O (n ^ 3)

Quindi calcoli

x = U \ (L \ b) ~ O (2 n ^ 2)

Ciò ridurrebbe enormemente il costo e lo renderebbe più veloce. La precisione sarebbe la stessa.


1
Nota, dalla documentazione , L non è necessariamente triangolare inferiore. Questa risposta sarebbe probabilmente più veloce di una risoluzione diretta, tuttavia starei attento a assicurarmi che il comando L \ b sia abbastanza intelligente da sapere di risolvere L nell'ordine corretto (probabilmente lo è, ma non lo dice per certo nella documentazione).
Godric Seer,

Sì, hai ragione, L è il prodotto di una matrice triangolare inferiore e di una matrice di permutazione. Ma sarò dannato se non riconoscesse che tutto ciò che deve fare è sostituire all'indietro L\b. Perché ho visto che questa linea esatta è stata usata nel codice ad alte prestazioni da quelli che considero esperti.
Milind R

8
O(n2)

1
A

3
@BrianBorcher Per quanto ne so, il modo migliore per tenere traccia delle permutazioni è [L,U,p] = lu(A,'vector'); x = U\(L\b(p));Vedi l'esempio 3 nei lu documenti .
Stefano M,

5

Nei nostri corsi di informatica scientifica abbiamo svolto numerosi laboratori informatici su questo argomento. Per i "piccoli" calcoli che abbiamo fatto lì, l'operatore di barra rovesciata di Matlab era sempre più veloce di ogni altra cosa, anche dopo aver ottimizzato il nostro codice il più possibile e riordinato in anticipo tutte le matrici (ad esempio con Reverse Cuthill McKee che ordinava matrici sparse) .

Puoi consultare una delle nostre istruzioni di laboratorio . La risposta alla tua domanda è trattata (a breve) a pagina 4.

Un buon libro sull'argomento è stato scritto ad esempio da Cheney .


4

An×n Axi=bii=1mm

V = inv(A);
...
x = V*b;

O(n3)inv(A)O(n2)V*bm

>> n = 5000;
>> A = randn(n,n);
>> x = randn(n,1);
>> b = A*x;
>> rcond(A)
ans =
   1.3837e-06
>> tic, xm = A\b; toc
Elapsed time is 1.907102 seconds.
>> tic, [L,U] = lu(A); toc
Elapsed time is 1.818247 seconds.
>> tic, xl = U\(L\b); toc
Elapsed time is 0.399051 seconds.
>> tic, [L,U,p] = lu(A,'vector'); toc
Elapsed time is 1.581756 seconds.
>> tic, xp = U\(L\b(p)); toc
Elapsed time is 0.060203 seconds.
>> tic, V=inv(A); toc
Elapsed time is 7.614582 seconds.
>> tic, xv = V*b; toc     
Elapsed time is 0.011499 seconds.
>> [norm(xm-x), norm(xp-x), norm(xl-x), norm(xv-x)] ./ norm(x)
ans =
   1.0e-11 *
    0.1912    0.1912    0.1912    0.6183

A1LUm>125

Alcune note

Per l'analisi della stabilità e degli errori, vedere i commenti a questa diversa risposta , in particolare quella di VictorLiu.

mn

I tempi sono stati eseguiti con Matlab R2011b su un computer a 12 core con una media di carico UNIX abbastanza costante di 5; miglior tic, toctempo di tre sonde.


In effetti, in un moltiplicatore di matrici vettoriali esiste molto più parallelismo rispetto a un solutore triangolare, quindi ciò dovrebbe essere ancora più evidente se i calcoli vengono eseguiti in parallelo (multicore / GPU / ecc ...) in alcun modo.
Aron Ahmadia,

@AronAhmadia Sono d'accordo: le stime del punto di pareggio basate solo sul conteggio delle operazioni hanno senso solo per un'implementazione seriale.
Stefano M,

1
Si noti che le cose saranno molto diverse se la matrice A è scarsa - l'inverso sarà in genere abbastanza denso, mentre i fattori LU sono in genere ragionevolmente sparsi, ribaltando le cose nella direzione di LU più veloce.
Brian Borchers,

1
A

1
inv(A)Ax=bbBA\B

2

Dai un'occhiata a questa domanda , le risposte mostrano che mldivideè abbastanza intelligente e fornisce anche suggerimenti su come vedere cosa Matlab usa per risolvere A\b. Questo può darti un suggerimento per quanto riguarda le opzioni di ottimizzazione.


0

L'uso di backslash è più o meno equivalente a inv(A)*B, se lo stai codificando liberamente, quest'ultimo potrebbe essere più intuitivo. Sono quasi uguali (solo diversi nel modo in cui viene eseguito il calcolo), anche se è necessario controllare la documentazione di Matlab per chiarimenti.

Per rispondere alla tua domanda, la barra rovesciata va generalmente bene, ma dipende dalle proprietà della matrice di massa.


1
Matematicamente inv (A) * b è uguale a \ comunque numericamente, in realtà formare l'inverso è sia meno efficiente che meno preciso. Se stai lavorando per imparare l'algebra lineare, questo potrebbe essere accettabile, ma direi che hai bisogno di un'ottima ragione per formare l'inverso.
Godric Seer,

Ma perché dovresti mai calcolare inv(A)dal momento che da solo è più costoso di A\b?
Dominique,

7
@Godric: C'è un articolo recente che discute del "mito" che inv (A) * b è meno preciso: su ArXiv . Non dire che di solito c'è motivo di calcolare l'inverso vero, ma solo dire.
Victor Liu,

3
@Dominique: le soluzioni triangolari sono molto meno parallelizzabili rispetto alla moltiplicazione matrice-vettore e i sofisticati metodi iterativi precondizionati spesso fanno uso di metodi diretti su sottodomini. È spesso utile formare esplicitamente le inversioni di alcune matrici triangolari dense di dimensioni modeste al fine di migliorare il parallelismo.
Jack Poulson,

@VictorLiu: grazie per l'articolo. Sono corretto sulla mia dichiarazione di accuratezza (almeno per implementazioni intelligenti di inv (A)).
Godric Seer,
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.