Resolver repetidamente

12

Estoy usando MATLAB para resolver un problema que implica resolver en cada paso de tiempo, donde cambia con el tiempo. En este momento, estoy logrando esto usando MATLAB :bAx=bbmldivide

x = A\b

Tengo la flexibilidad de hacer tantas calculaciones previas como sea necesario, por lo que me pregunto si existe un método más rápido y / o más preciso que mldivide. ¿Qué se hace típicamente aquí? ¡Gracias a todos!

Duda
fuente
1
¿Tienes conocimiento específico sobre la estructura de ? Por ejemplo, ¿es simétrico? ¿Positivo definitivo? Tridiagonal? ¿Ortogonal? A
Dominique
La matriz es una matriz cuadrada densa. A
Duda
3
Si no tiene otro conocimiento sobre , la mejor factorización como se describe en la respuesta a continuación. L UALU
Dominique

Respuestas:

14

Lo más obvio que puede hacer es precalcular

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

Entonces solo calculas

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

Esto reduciría enormemente el costo y lo haría más rápido. La precisión sería la misma.

Milind R
fuente
1
Tenga en cuenta que, de la documentación , L no es necesariamente triangular inferior. Es probable que esta respuesta sea más rápida que una resolución directa, sin embargo, tendría cuidado de asegurarme de que el comando L \ b sea lo suficientemente inteligente como para saber resolver L en el orden correcto (probablemente lo sea, pero no lo dice con certeza en la documentación).
Godric Seer
Sí, tienes razón, L es el producto de una matriz triangular inferior y una matriz de permutación. Pero estaré condenado si no reconoce que todo lo que tiene que hacer es la sustitución hacia atrás L\b. Porque he visto esta línea exacta siendo utilizada en código de alto rendimiento por aquellos que considero expertos.
Milind R
8
mldivide reconoce las matrices triangulares permutadas y hace lo correcto para resolver dicho sistema. Sin embargo, en mis experimentos, esto parece hacer que el proceso de solución sea más lento en un factor de aproximadamente 10 para una matriz de tamaño 2000 por 2000 a 10000 por 10000. Por lo tanto, sería mejor no hacer un seguimiento explícito de la permutación usando [L , U, P] = lu (P). O(n2)
Brian Borchers
1
Además, si su matriz es escasa, debe aprovechar la escasez para resolver el sistema. La forma más sencilla de hacer esto es asegurarse de que se almacene en formato disperso utilizando A = disperso (A) antes de calcular la factorización LU. También puede intentar permutar las filas de A para reducir el relleno durante la factorización LU. A
Brian Borchers
3
@BrianBorcher Hasta donde yo sé, la mejor manera de hacer un seguimiento de la permutación es [L,U,p] = lu(A,'vector'); x = U\(L\b(p));ver el ejemplo 3 en los lu documentos .
Stefano M
5

Hicimos algunos laboratorios de computación extensivos en nuestros cursos de computación científica sobre este tema. Para los cálculos "pequeños" que hicimos allí, el operador de barra invertida de Matlab siempre fue más rápido que cualquier otra cosa, incluso después de haber optimizado nuestro código tanto como sea posible y haber reordenado todas las matrices de antemano (por ejemplo, con Reverse Cuthill McKee ordenando matrices dispersas) .

Puede consultar una de nuestras instrucciones de laboratorio . La respuesta a su pregunta se trata (en breve) en la página 4.

Un buen libro sobre el tema está escrito, por ejemplo, por Cheney .

seb
fuente
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

Algunas notas

Para un análisis de estabilidad y error, vea los comentarios a esta respuesta diferente , especialmente la de VictorLiu.

mn

La sincronización se realizó con Matlab R2011b en una computadora de 12 núcleos con un promedio de carga UNIX bastante constante de 5; El mejor tic, tocmomento de tres sondas.

Stefano M
fuente
De hecho, hay mucho más paralelismo disponible en una multiplicación matriz-vector que en un solucionador triangular, por lo que esto debería ser aún más evidente si los cálculos se realizan en paralelo (multinúcleo / GPU / etc ...) de alguna manera.
Aron Ahmadia
@AronAhmadia Estoy de acuerdo: las estimaciones de punto de equilibrio basadas solo en el recuento de operaciones solo tienen sentido para una implementación en serie.
Stefano M
1
Tenga en cuenta que las cosas serán muy diferentes si la matriz A es escasa: lo inverso suele ser bastante denso, mientras que los factores LU suelen ser razonablemente escasos, volviendo las cosas en la dirección de LU más rápido.
Brian Borchers
1
A
1
inv(A)Ax=bbBA\B
2

Eche un vistazo a esta pregunta , las respuestas muestran que mldividees bastante inteligente y también ofrece sugerencias sobre cómo ver qué utiliza Matlab para resolver A\b. Esto puede darle una pista sobre las opciones de optimización.

Psirus
fuente
0

El uso de la barra diagonal inversa es más o menos equivalente a inv(A)*B, si lo está codificando libremente, este último podría ser más intuitivo. Son casi iguales (solo diferentes en cómo se lleva a cabo el cálculo), aunque debe consultar la documentación de Matlab para obtener aclaraciones.

Para responder a su pregunta, la barra invertida generalmente está bien, pero depende de las propiedades de la matriz de masa.

AlanH
fuente
1
Matemáticamente inv (A) * b es lo mismo que \ sin embargo, numéricamente, formar el inverso es menos eficiente y menos preciso. Si está trabajando para aprender el álgebra lineal, esto puede ser aceptable, pero diría que necesita una muy buena razón para formar el inverso.
Godric Seer
Pero, ¿por qué calcularías inv(A)ya que solo eso es más caro que A\b?
Dominique
77
@Godric: Hay un artículo reciente que discute el "mito" de que inv (A) * b es menos preciso: en ArXiv . No digo que generalmente haya razones para calcular el inverso real, sino simplemente decir.
Victor Liu
3
@Dominique: Las soluciones triangulares son mucho menos paralelizables que la multiplicación matriz-vector, y los sofisticados métodos iterativos preacondicionados a menudo utilizan métodos directos en subdominios. A menudo es útil formar explícitamente las inversas de unas pocas matrices triangulares densas de tamaño modesto para mejorar el paralelismo.
Jack Poulson
@VictorLiu: Gracias por el artículo. Estoy corregido en mi declaración de precisión (al menos para implementaciones inteligentes de inv (A)).
Godric Seer