Estaba comparando algunos de mis códigos con los códigos MATLAB "de inventario". Estoy sorprendido por los resultados.
Ejecuté un código de muestra (matriz dispersa)
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;
Resultados:
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.
Para matriz densa:
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;
Resultados:
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.
¿Cómo diablos es a \ b tan increíble?
linear-algebra
performance
matlab
Encuesta
fuente
fuente
Respuestas:
En Matlab, el comando '\' invoca un algoritmo que depende de la estructura de la matriz A e incluye controles (pequeña sobrecarga) en las propiedades de A.
Para reducir los gastos generales, es posible utilizar el comando linsolve en Matlab y seleccionar un solucionador adecuado entre estas opciones usted mismo.
fuente
Si desea ver qué
a\b
hace para su matriz particular, puede establecerspparms('spumoni',1)
y calcular exactamente qué algoritmo le impresionó. Por ejemplo:saldrá
entonces puedo ver que "\" terminó usando "CHOLMOD" en este caso.
fuente
help mldivide
.Para matrices dispersas, Matlab usa UMFPACK para la
\
operación " ", que, en su ejemplo, básicamente ejecuta los valores dea
, los invierte y los multiplica con los valores deb
. Sin embargo, para este ejemplo, debe usarb./diag(a)
, que es mucho más rápido.Para sistemas densos, el operador de barra invertida es un poco más complicado. Una breve descripción de lo que se hace cuando se da aquí . De acuerdo con esa descripción, en su ejemplo, Matlab resolvería
a\b
usando la sustitución hacia atrás. Para las matrices cuadradas generales, se utiliza una descomposición LU.fuente
tic; for k=1:100, a\b; end; toc
.Como regla general, si tiene una matriz escasa de complejidad razonable (es decir, no tiene que ser la plantilla de 5 puntos, pero de hecho puede ser una discretización de las ecuaciones de Stokes para las cuales el número de no ceros por fila es mucho más grande que 5), entonces un solucionador directo escaso como UMFPACK generalmente supera a un solucionador iterativo de Krylov si el problema no es mayor que alrededor de unas 100,000 incógnitas.
En otras palabras, para la mayoría de las matrices dispersas resultantes de discretizaciones 2D, un solucionador directo es la alternativa más rápida. Solo para los problemas 3D en los que superas rápidamente las 100.000 incógnitas, es imprescindible utilizar un solucionador iterativo.
fuente