fbpx
Wikipedia

Algoritmo para matrices tridiagonales

El algoritmo para matrices tridiagonales o algoritmo de Thomas (por Llewellyn Thomas) es un algoritmo del álgebra lineal numérica para resolver matrices tridiagonales de forma eficiente.

Una matriz tridiagonal se corresponde a un sistema de ecuaciones de la forma

donde y . lo que se puede representar matricialmente como

Para este tipo de sistemas se puede obtener con este algoritmo una solución con solo operaciones en vez de las que requiere la eliminación gaussiana. El algoritmo primero elimina las y luego usa una sustitución para obtener la solución.

Este tipo de matrices suelen salir al plantear discretizaciones por métodos de diferencias finitas, volúmenes finitos o elementos finitos de problemas unidimensionales. Algunos de los problemas físicos que se plantean así son la Ecuación de Poisson, la ecuación de calor, la ecuación de onda o la interpolación por splines.

Método

El primer paso del método es modificar los coeficientes como sigue:

 

donde se marcan con superíndice ' los nuevos coeficientes.

De igual manera se opera:

 

a lo que se llama barrido hacia adelante. A continuación se obtiene la solución por sustitución hacia atrás:

 
 

Implementaciones

Implementación en C

La siguiente función en C resolverá el sistema (aunque sobreescribirá el vector de entrada c en el proceso). Se ha de notar que aquí los subíndices están basados en el cero, es decir   donde   es el número de ecuaciones:

void solve_tridiagonal_in_place_destructive(float x[], const size_t N, const float a[], const float b[], float c[]) { int n; /**  * solves Ax = v where A is a tridiagonal matrix consisting of vectors a, b, c  * note that contents of input vector c will be modified, making this a one-time-use function  * x[] - initially contains the input vector v, and returns the solution x. indexed from [0, ..., N - 1]  * N - number of equations  * a[] - subdiagonal (means it is the diagonal below the main diagonal) -- indexed from [1, ..., N - 1]  * b[] - the main diagonal, indexed from [0, ..., N - 1]  * c[] - superdiagonal (means it is the diagonal above the main diagonal) -- indexed from [0, ..., N - 2]  */ c[0] = c[0] / b[0]; x[0] = x[0] / b[0]; /* loop from 1 to N - 1 inclusive */ for (n = 1; n < N; n++) { float m = 1.0f / (b[n] - a[n] * c[n - 1]); if(n < (N-1)) c[n] = c[n] * m; x[n] = (x[n] - a[n] * x[n - 1]) * m; } /* loop from N - 2 to 0 inclusive */ for (n = N - 2; n >= 0; --n) { x[n] = x[n] - c[n] * x[n + 1]; } } 

La siguiente variante preserva el sistema de ecuaciones para reutilizarlo en otras funciones. Se hacen llamadas a la biblioteca para reservar más especiao. Otras variantes usan un puntero a memoria disponible.

void solve_tridiagonal_in_place_reusable(float x[], const size_t N, const float a[], const float b[], const float c[]) { size_t n; /* allocate scratch space */ float * const cprime = malloc(sizeof(float) * N);  cprime[0] = c[0] / b[0]; x[0] = x[0] / b[0]; /* loop from 1 to N - 1 inclusive */ for (n = 1; n < N; n++) { float m = 1.0f / (b[n] - a[n] * cprime[n - 1]); if(n < (N-1)) cprime[n] = c[n] * m; x[n] = (x[n] - a[n] * x[n - 1]) * m; } /* loop from N - 2 to 0 inclusive */ for (n = N - 2; n > 0; --n) x[n] = x[n] - cprime[n] * x[n + 1]; /* free scratch space */ free(cprime); } 

Implementación en Python

La siguiente implementación usa el lenguaje de programación Python.De nuevo, los subíndices son basados en el cero (  donde   es el número de incógnitas).

def TDMASolve(a, b, c, d): n = len(d) # número de filas # Modifica los coeficientes de la primera fila c[0] /= b[0] # Posible división por cero d[0] /= b[0] for i in range(1, n): ptemp = b[i] - (a[i] * c[i-1]) c[i] /= ptemp d[i] = (d[i] - a[i] * d[i-1])/ptemp # Sustitución hacia atrás x = [0 for i in range(n)] x[-1] = d[-1] for i in range(-2, -n-1, -1): x[i] = d[i] - c[i] * x[i+1] return x 

Implementación en Matlab

En Matlab/Octave el algoritmo queda como sigue. Esta vez los vectores están basados en el uno, por lo que   con   que el número de incógnitas.

function x = TDMAsolver(a,b,c,d) %a, b, c are the column vectors for the compressed tridiagonal matrix, d is the right vector % N is the number of rows N = length(d);   % Modify the first-row coefficients c(1) = c(1) / b(1); % Division by zero risk. d(1) = d(1) / b(1);    for n = 2:1:N  temp = b(n) - a(n) * c(n - 1);  if (n<N)  c(n) = c(n) / temp;  end  d(n) = (d(n) - a(n) * d(n - 1)) / temp; end   % Now back substitute. x(N) = d(N); for n = (N - 1):-1:1  x(n) = d(n) - c(n) * x(n + 1); end end 

Implementación en Fortran 90

Fortran usa también una nomenclatura basada en el uno, es decir   siendo   el número de incógnitas.

Algunas veces no es deseable que el programa sobreescriba los coeficientes (por ejemplo para resolver diversos sistemas que solo difieren en el término independiente), así que esta implementación mantiene dichos coeficientes.

 subroutine solve_tridiag(a,b,c,d,x,n) implicit none ! a - sub-diagonal (means it is the diagonal below the main diagonal) ! b - the main diagonal ! c - sup-diagonal (means it is the diagonal above the main diagonal) ! d - right part ! x - the answer ! n - number of equations integer,intent(in) :: n real(8),dimension(n),intent(in) :: a,b,c,d real(8),dimension(n),intent(out) :: x real(8),dimension(n) :: cp,dp real(8) :: m integer i ! initialize c-prime and d-prime cp(1) = c(1)/b(1) dp(1) = d(1)/b(1) ! solve for vectors c-prime and d-prime do i = 2,n m = b(i)-cp(i-1)*a(i) cp(i) = c(i)/m dp(i) = (d(i)-dp(i-1)*a(i))/m enddo ! initialize x x(n) = dp(n) ! solve for x from the vectors c-prime and d-prime do i = n-1, 1, -1  x(i) = dp(i)-cp(i)*x(i+1) end do  end subroutine solve_tridiag 

Derivación

Algoritmo

Se puede obtener dicho algoritmo usando la eliminación gaussiana de forma genérica. Suponiendo como incógnitas   y con ecuaciones a resolver:

 

Modificando la segunda ecuación a partir de la primera obtenemos:

 

lo que da:

 
 

y se ha eliminado   de la segunda ecuación. Si repetimos usando la segunda ecuación en la tercera obtenemos:

 
 

Esta vez se ha eliminado  . El procedimiento se puede repetir hasta la fila enésima, dejando cada ecuación con solo dos incógnitas menos la última que solo tiene una incógnita. Entonces es inmediata la resolución de esta y desde ahí la de las anteriores.

Fórmulas para coeficientes

La determinación de los coeficientes en las ecuaciones generales es más complicada. Examinando el procedimiento, se pueden definir de forma recursiva:

 
 
 
 
 
 
 

Para acelerar la resolución   puede ser dividido (si no hay problemas por división por cero) y los nuevos coeficientes, indicados con primas, serán:

 
 
 
 
 
 

Lo que da el siguiente sistema con las mismas incógnitas y los coeficientes definidos en función de los originales:

 

Donde la última ecuación solo afecta a una incógnita. Resolviéndola podemos resolver la anterior y así sucesivamente:

 
 

Variantes

En algunas situaciones, particularmente con condiciones de contorno periódicas, se busca resolver una forma perturbada de la matriz tridiagonal:

 

Para este caso se usa la Fórmula Sherman-Morrison para evitar las operaciones adicionales de una eliminación gaussiana y poder seguir usando el algoritmo de Thomas. Este método requiere resolver una versión no cíclica del sistema para la entrada y un vector de corrección y combinar los resultados. Todo ello se puede hacer eficientemente de una vez dado que ambos problemas compartan el barrido hacia delante de la matriz triangular..

En otras situaciones el sistema de ecuaciones puede ser tridiagonal por bloques, con submatrices como elementos formando tres diagonales. Este tipo de problemas suelen darse cuando se quiere extender los métodos de discretización a dos dimensiones y puede verse también como una matriz pentadiagonal. Variantes de este algoritmo se usan para estas situaciones.

El libro Numerical Mathematics de Quarteroni, Sacco y Saleri, recoge una versión modificada para multiplicaciones en vez de divisiones, lo que es útil en ciertas arquitecturas.

Referencias

  • Conte, S.D., and deBoor, C. (1972). Elementary Numerical Analysis. McGraw-Hill, New York. ISBN 0070124469. 
  • Este artículo incluye texto del artículo Tridiagonal matrix algorithm - TDMA (Thomas algorithm) publicado con licencia GNU en CFD online wiki
  • Press, WH; Teukolsky, SA; Vetterling, WT; Flannery, BP (2007). «Section 2.4». Numerical Recipes: The Art of Scientific Computing (3rd edición). New York: Cambridge University Press. ISBN 978-0-521-88068-8. 

Enlaces externos

    •   Datos: Q1819156

    algoritmo, para, matrices, tridiagonales, algoritmo, para, matrices, tridiagonales, algoritmo, thomas, llewellyn, thomas, algoritmo, álgebra, lineal, numérica, para, resolver, matrices, tridiagonales, forma, eficiente, matriz, tridiagonal, corresponde, sistema. El algoritmo para matrices tridiagonales o algoritmo de Thomas por Llewellyn Thomas es un algoritmo del algebra lineal numerica para resolver matrices tridiagonales de forma eficiente Una matriz tridiagonal se corresponde a un sistema de ecuaciones de la forma a i x i 1 b i x i c i x i 1 d i displaystyle a i x i 1 b i x i c i x i 1 d i donde a 1 0 displaystyle a 1 0 y c n 0 displaystyle c n 0 lo que se puede representar matricialmente como b 1 c 1 0 a 2 b 2 c 2 a 3 b 3 c n 1 0 a n b n x 1 x 2 x 3 x n d 1 d 2 d 3 d n displaystyle begin bmatrix b 1 amp c 1 amp amp amp 0 a 2 amp b 2 amp c 2 amp amp amp a 3 amp b 3 amp ddots amp amp amp ddots amp ddots amp c n 1 0 amp amp amp a n amp b n end bmatrix begin bmatrix x 1 x 2 x 3 vdots x n end bmatrix begin bmatrix d 1 d 2 d 3 vdots d n end bmatrix Para este tipo de sistemas se puede obtener con este algoritmo una solucion con solo O n displaystyle O n operaciones en vez de las O n 3 displaystyle O n 3 que requiere la eliminacion gaussiana El algoritmo primero elimina las a i displaystyle a i y luego usa una sustitucion para obtener la solucion Este tipo de matrices suelen salir al plantear discretizaciones por metodos de diferencias finitas volumenes finitos o elementos finitos de problemas unidimensionales Algunos de los problemas fisicos que se plantean asi son la Ecuacion de Poisson la ecuacion de calor la ecuacion de onda o la interpolacion por splines Indice 1 Metodo 2 Implementaciones 2 1 Implementacion en C 2 2 Implementacion en Python 2 3 Implementacion en Matlab 2 4 Implementacion en Fortran 90 3 Derivacion 3 1 Algoritmo 3 2 Formulas para coeficientes 4 Variantes 5 Referencias 6 Enlaces externosMetodo EditarEl primer paso del metodo es modificar los coeficientes como sigue c i c i b i i 1 c i b i c i 1 a i i 2 3 n 1 displaystyle c i begin cases begin array lcl cfrac c i b i amp amp i 1 cfrac c i b i c i 1 a i amp amp i 2 3 dots n 1 end array end cases donde se marcan con superindice los nuevos coeficientes De igual manera se opera d i d i b i i 1 d i d i 1 a i b i c i 1 a i i 2 3 n displaystyle d i begin cases begin array lcl cfrac d i b i amp amp i 1 cfrac d i d i 1 a i b i c i 1 a i amp amp i 2 3 dots n end array end cases a lo que se llama barrido hacia adelante A continuacion se obtiene la solucion por sustitucion hacia atras x n d n displaystyle x n d n x i d i c i x i 1 i n 1 n 2 1 displaystyle x i d i c i x i 1 qquad i n 1 n 2 ldots 1 Implementaciones EditarImplementacion en C Editar La siguiente funcion en C resolvera el sistema aunque sobreescribira el vector de entrada c en el proceso Se ha de notar que aqui los subindices estan basados en el cero es decir n 0 1 N 1 displaystyle n 0 1 dots N 1 donde N displaystyle N es el numero de ecuaciones void solve tridiagonal in place destructive float x const size t N const float a const float b float c int n solves Ax v where A is a tridiagonal matrix consisting of vectors a b c note that contents of input vector c will be modified making this a one time use function x initially contains the input vector v and returns the solution x indexed from 0 N 1 N number of equations a subdiagonal means it is the diagonal below the main diagonal indexed from 1 N 1 b the main diagonal indexed from 0 N 1 c superdiagonal means it is the diagonal above the main diagonal indexed from 0 N 2 c 0 c 0 b 0 x 0 x 0 b 0 loop from 1 to N 1 inclusive for n 1 n lt N n float m 1 0f b n a n c n 1 if n lt N 1 c n c n m x n x n a n x n 1 m loop from N 2 to 0 inclusive for n N 2 n gt 0 n x n x n c n x n 1 La siguiente variante preserva el sistema de ecuaciones para reutilizarlo en otras funciones Se hacen llamadas a la biblioteca para reservar mas especiao Otras variantes usan un puntero a memoria disponible void solve tridiagonal in place reusable float x const size t N const float a const float b const float c size t n allocate scratch space float const cprime malloc sizeof float N cprime 0 c 0 b 0 x 0 x 0 b 0 loop from 1 to N 1 inclusive for n 1 n lt N n float m 1 0f b n a n cprime n 1 if n lt N 1 cprime n c n m x n x n a n x n 1 m loop from N 2 to 0 inclusive for n N 2 n gt 0 n x n x n cprime n x n 1 free scratch space free cprime Implementacion en Python Editar La siguiente implementacion usa el lenguaje de programacion Python De nuevo los subindices son basados en el cero i 0 1 n 1 displaystyle i 0 1 dots n 1 donde n displaystyle n es el numero de incognitas def TDMASolve a b c d n len d numero de filas Modifica los coeficientes de la primera fila c 0 b 0 Posible division por cero d 0 b 0 for i in range 1 n ptemp b i a i c i 1 c i ptemp d i d i a i d i 1 ptemp Sustitucion hacia atras x 0 for i in range n x 1 d 1 for i in range 2 n 1 1 x i d i c i x i 1 return x Implementacion en Matlab Editar En Matlab Octave el algoritmo queda como sigue Esta vez los vectores estan basados en el uno por lo que i 1 2 n displaystyle i 1 2 dots n con n displaystyle n que el numero de incognitas function x TDMAsolver a b c d a b c are the column vectors for the compressed tridiagonal matrix d is the right vector N is the number of rows N length d Modify the first row coefficients c 1 c 1 b 1 Division by zero risk d 1 d 1 b 1 for n 2 1 N temp b n a n c n 1 if n lt N c n c n temp end d n d n a n d n 1 temp end Now back substitute x N d N for n N 1 1 1 x n d n c n x n 1 end end Implementacion en Fortran 90 Editar Fortran usa tambien una nomenclatura basada en el uno es decir i 1 2 n displaystyle i 1 2 dots n siendo n displaystyle n el numero de incognitas Algunas veces no es deseable que el programa sobreescriba los coeficientes por ejemplo para resolver diversos sistemas que solo difieren en el termino independiente asi que esta implementacion mantiene dichos coeficientes subroutine solve tridiag a b c d x n implicit none a sub diagonal means it is the diagonal below the main diagonal b the main diagonal c sup diagonal means it is the diagonal above the main diagonal d right part x the answer n number of equations integer intent in n real 8 dimension n intent in a b c d real 8 dimension n intent out x real 8 dimension n cp dp real 8 m integer i initialize c prime and d prime cp 1 c 1 b 1 dp 1 d 1 b 1 solve for vectors c prime and d prime do i 2 n m b i cp i 1 a i cp i c i m dp i d i dp i 1 a i m enddo initialize x x n dp n solve for x from the vectors c prime and d prime do i n 1 1 1 x i dp i cp i x i 1 end do end subroutine solve tridiagDerivacion EditarAlgoritmo Editar Se puede obtener dicho algoritmo usando la eliminacion gaussiana de forma generica Suponiendo como incognitas x 1 x n displaystyle x 1 ldots x n y con ecuaciones a resolver b 1 x 1 c 1 x 2 d 1 i 1 a i x i 1 b i x i c i x i 1 d i i 2 n 1 a n x n 1 b n x n d n i n displaystyle begin aligned b 1 x 1 c 1 x 2 amp d 1 amp i amp 1 a i x i 1 b i x i c i x i 1 amp d i amp i amp 2 ldots n 1 a n x n 1 b n x n amp d n amp i amp n end aligned Modificando la segunda ecuacion a partir de la primera obtenemos ecuacion 2 b 1 ecuacion 1 a 2 displaystyle mbox ecuacion 2 cdot b 1 mbox ecuacion 1 cdot a 2 lo que da a 2 x 1 b 2 x 2 c 2 x 3 b 1 b 1 x 1 c 1 x 2 a 2 d 2 b 1 d 1 a 2 displaystyle a 2 x 1 b 2 x 2 c 2 x 3 b 1 b 1 x 1 c 1 x 2 a 2 d 2 b 1 d 1 a 2 b 2 b 1 c 1 a 2 x 2 c 2 b 1 x 3 d 2 b 1 d 1 a 2 displaystyle b 2 b 1 c 1 a 2 x 2 c 2 b 1 x 3 d 2 b 1 d 1 a 2 y se ha eliminado x 1 displaystyle x 1 de la segunda ecuacion Si repetimos usando la segunda ecuacion en la tercera obtenemos a 3 x 2 b 3 x 3 c 3 x 4 b 2 b 1 c 1 a 2 b 2 b 1 c 1 a 2 x 2 c 2 b 1 x 3 a 3 d 3 b 2 b 1 c 1 a 2 d 2 b 1 d 1 a 2 a 3 displaystyle a 3 x 2 b 3 x 3 c 3 x 4 b 2 b 1 c 1 a 2 b 2 b 1 c 1 a 2 x 2 c 2 b 1 x 3 a 3 d 3 b 2 b 1 c 1 a 2 d 2 b 1 d 1 a 2 a 3 b 3 b 2 b 1 c 1 a 2 c 2 b 1 a 3 x 3 c 3 b 2 b 1 c 1 a 2 x 4 d 3 b 2 b 1 c 1 a 2 d 2 b 1 d 1 a 2 a 3 displaystyle b 3 b 2 b 1 c 1 a 2 c 2 b 1 a 3 x 3 c 3 b 2 b 1 c 1 a 2 x 4 d 3 b 2 b 1 c 1 a 2 d 2 b 1 d 1 a 2 a 3 Esta vez se ha eliminado x 2 displaystyle x 2 El procedimiento se puede repetir hasta la fila enesima dejando cada ecuacion con solo dos incognitas menos la ultima que solo tiene una incognita Entonces es inmediata la resolucion de esta y desde ahi la de las anteriores Formulas para coeficientes Editar La determinacion de los coeficientes en las ecuaciones generales es mas complicada Examinando el procedimiento se pueden definir de forma recursiva a i 0 displaystyle tilde a i 0 b 1 b 1 displaystyle tilde b 1 b 1 b i b i b i 1 c i 1 a i displaystyle tilde b i b i tilde b i 1 tilde c i 1 a i c 1 c 1 displaystyle tilde c 1 c 1 c i c i b i 1 displaystyle tilde c i c i tilde b i 1 d 1 d 1 displaystyle tilde d 1 d 1 d i d i b i 1 d i 1 a i displaystyle tilde d i d i tilde b i 1 tilde d i 1 a i Para acelerar la resolucion b i displaystyle tilde b i puede ser dividido si no hay problemas por division por cero y los nuevos coeficientes indicados con primas seran a i 0 displaystyle a i 0 b i 1 displaystyle b i 1 c 1 c 1 b 1 displaystyle c 1 frac c 1 b 1 c i c i b i c i 1 a i displaystyle c i frac c i b i c i 1 a i d 1 d 1 b 1 displaystyle d 1 frac d 1 b 1 d i d i d i 1 a i b i c i 1 a i displaystyle d i frac d i d i 1 a i b i c i 1 a i Lo que da el siguiente sistema con las mismas incognitas y los coeficientes definidos en funcion de los originales x i c i x i 1 d i i 1 n 1 x n d n i n displaystyle begin array lcl x i c i x i 1 d i qquad amp amp i 1 ldots n 1 x n d n qquad amp amp i n end array Donde la ultima ecuacion solo afecta a una incognita Resolviendola podemos resolver la anterior y asi sucesivamente x n d n displaystyle x n d n x i d i c i x i 1 i n 1 n 2 1 displaystyle x i d i c i x i 1 qquad i n 1 n 2 ldots 1 Variantes EditarEn algunas situaciones particularmente con condiciones de contorno periodicas se busca resolver una forma perturbada de la matriz tridiagonal a 1 x n b 1 x 1 c 1 x 2 d 1 a i x i 1 b i x i c i x i 1 d i i 2 n 1 a n x n 1 b n x n c n x 1 d n displaystyle begin aligned a 1 x n b 1 x 1 c 1 x 2 amp d 1 a i x i 1 b i x i c i x i 1 amp d i quad quad i 2 ldots n 1 a n x n 1 b n x n c n x 1 amp d n end aligned Para este caso se usa la Formula Sherman Morrison para evitar las operaciones adicionales de una eliminacion gaussiana y poder seguir usando el algoritmo de Thomas Este metodo requiere resolver una version no ciclica del sistema para la entrada y un vector de correccion y combinar los resultados Todo ello se puede hacer eficientemente de una vez dado que ambos problemas compartan el barrido hacia delante de la matriz triangular En otras situaciones el sistema de ecuaciones puede ser tridiagonal por bloques con submatrices como elementos formando tres diagonales Este tipo de problemas suelen darse cuando se quiere extender los metodos de discretizacion a dos dimensiones y puede verse tambien como una matriz pentadiagonal Variantes de este algoritmo se usan para estas situaciones El libro Numerical Mathematics de Quarteroni Sacco y Saleri recoge una version modificada para multiplicaciones en vez de divisiones lo que es util en ciertas arquitecturas Referencias EditarConte S D and deBoor C 1972 Elementary Numerical Analysis McGraw Hill New York ISBN 0070124469 Este articulo incluye texto del articulo Tridiagonal matrix algorithm TDMA Thomas algorithm publicado con licencia GNU en CFD online wiki Press WH Teukolsky SA Vetterling WT Flannery BP 2007 Section 2 4 Numerical Recipes The Art of Scientific Computing 3rd edicion New York Cambridge University Press ISBN 978 0 521 88068 8 Enlaces externos EditarExample with VBA code Datos Q1819156Obtenido de https es wikipedia org w index php title Algoritmo para matrices tridiagonales amp oldid 125249284, wikipedia, wiki, leyendo, leer, libro, biblioteca,

    español

    , española, descargar, gratis, descargar gratis, mp3, video, mp4, 3gp, jpg, jpeg, gif, png, imagen, música, canción, película, libro, juego, juegos