Je comparais quelques-uns de mes codes avec les codes MATLAB "en stock". Je suis surpris des résultats.
J'ai couru un exemple de code (Sparse Matrix)
n = 5000;
a = diag(rand(n,1));
b = rand(n,1);
disp('For a\b');
tic;a\b;toc;
disp('For LU');
tic;LULU;toc;
disp('For Conj Grad');
tic;conjgrad(a,b,1e-8);toc;
disp('Inv(A)*B');
tic;inv(a)*b;toc;
Résultats :
For a\b
Elapsed time is 0.052838 seconds.
For LU
Elapsed time is 7.441331 seconds.
For Conj Grad
Elapsed time is 3.819182 seconds.
Inv(A)*B
Elapsed time is 38.511110 seconds.
Pour la matrice dense:
n = 2000;
a = rand(n,n);
b = rand(n,1);
disp('For a\b');
tic;a\b;toc;
disp('For LU');
tic;LULU;toc;
disp('For Conj Grad');
tic;conjgrad(a,b,1e-8);toc;
disp('For INV(A)*B');
tic;inv(a)*b;toc;
Résultats:
For a\b
Elapsed time is 0.575926 seconds.
For LU
Elapsed time is 0.654287 seconds.
For Conj Grad
Elapsed time is 9.875896 seconds.
Inv(A)*B
Elapsed time is 1.648074 seconds.
Comment diable est un \ b si génial?
linear-algebra
performance
matlab
Enquête
la source
la source
Réponses:
Dans Matlab, la commande '\' appelle un algorithme qui dépend de la structure de la matrice A et comprend des vérifications (faible temps système) sur les propriétés de A.
Pour réduire les frais généraux, il est possible d'utiliser la commande linsolve dans Matlab et de sélectionner vous-même un solveur approprié parmi ces options.
la source
Si vous voulez voir ce qui
a\b
fait pour votre matrice particulière, vous pouvez définirspparms('spumoni',1)
et déterminer exactement quel algorithme vous a impressionné. Par exemple:va sortir
je peux donc voir que "\" a fini par utiliser "CHOLMOD" dans ce cas.
la source
help mldivide
.Pour les matrices creuses, Matlab utilise UMFPACK pour l'
\
opération " ", qui, dans votre exemple, parcourt les valeurs dea
, les inverse et les multiplie par les valeurs deb
. Pour cet exemple, vous devriez utiliserb./diag(a)
, ce qui est beaucoup plus rapide.Pour les systèmes denses, l'opérateur de barre oblique inverse est un peu plus compliqué. Une brève description de ce qui est fait quand est donnée ici . Selon cette description, dans votre exemple, Matlab résoudrait l’
a\b
utilisation de la substitution arrière. Pour les matrices carrées générales, une décomposition de LU est utilisée.la source
tic; for k=1:100, a\b; end; toc
.En règle générale, si vous avez une matrice creuse de complexité raisonnable (c’est-à-dire que ce n’est pas nécessairement le gabarit à 5 points, mais peut en fait être une discrétisation des équations de Stokes pour laquelle le nombre de nonzeros par ligne est beaucoup plus grand que 5), un solveur direct maigre, tel que UMFPACK, bat généralement un solveur de Krylov itératif si le problème ne dépasse pas environ 100 000 inconnus.
En d'autres termes, pour la plupart des matrices creuses résultant de la discrétisation 2D, un résolveur direct est la solution la plus rapide. Il est impératif d'utiliser un résolveur itératif uniquement pour les problèmes 3D où vous obtenez rapidement plus de 100 000 inconnus.
la source