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=1…mm

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

A−1LUm>125

Alcune note

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

m≪n

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.