stringtranslate.com

Sobrerelajación sucesiva

En álgebra lineal numérica , el método de sobrerelajación sucesiva ( SOR ) es una variante del método de Gauss-Seidel para resolver un sistema lineal de ecuaciones , lo que resulta en una convergencia más rápida. Se puede utilizar un método similar para cualquier proceso iterativo que converja lentamente .

Fue ideado simultáneamente por David M. Young Jr. y por Stanley P. Frankel en 1950 con el propósito de resolver automáticamente sistemas lineales en computadoras digitales. Los métodos de excesiva relajación se habían utilizado antes del trabajo de Young y Frankel. Un ejemplo es el método de Lewis Fry Richardson y los métodos desarrollados por RV Southwell . Sin embargo, estos métodos fueron diseñados para el cálculo por calculadoras humanas , lo que requería cierta experiencia para garantizar la convergencia a la solución, lo que los hacía inaplicables para la programación en computadoras digitales. Estos aspectos se discuten en la tesis de David M. Young Jr. [1]

Formulación

Dado un sistema cuadrado de n ecuaciones lineales con x desconocida :

dónde:

Entonces A se puede descomponer en una componente diagonal D y en las componentes triangulares estrictamente inferior y superior L y U :

dónde

El sistema de ecuaciones lineales se puede reescribir como:

para una constante ω > 1, llamado factor de relajación .

El método de sobrerelajación sucesiva es una técnica iterativa que resuelve el lado izquierdo de esta expresión para x , utilizando el valor anterior para x en el lado derecho. Analíticamente, esto puede escribirse como:

donde es la k -ésima aproximación o iteración de y es la siguiente o k + 1 iteración de . Sin embargo, aprovechando la forma triangular de ( D + ωL ), los elementos de x ( k +1) se pueden calcular secuencialmente mediante sustitución directa :

Esto se puede escribir nuevamente analíticamente en forma de matriz-vector sin la necesidad de invertir la matriz : [2]

Convergencia

Radio espectral de la matriz de iteración para el método SOR . El gráfico muestra la dependencia del radio espectral de la matriz de iteración de Jacobi .

La elección del factor de relajación ω no es necesariamente fácil y depende de las propiedades de la matriz de coeficientes. En 1947, Ostrowski demostró que si es simétrico y definido positivo entonces para . Por lo tanto, se produce la convergencia del proceso de iteración, pero generalmente estamos interesados ​​en una convergencia más rápida en lugar de simplemente convergencia.

Tasa de convergencia

La tasa de convergencia del método SOR se puede derivar analíticamente. Es necesario asumir lo siguiente [3] [4]

Entonces la tasa de convergencia se puede expresar como

donde el parámetro de relajación óptimo está dado por

En particular, para ( Gauss-Seidel ) se cumple que . Para el óptimo obtenemos , lo que muestra que SOR es aproximadamente cuatro veces más eficiente que Gauss-Seidel.

El último supuesto se cumple para matrices tridiagonales ya que para diagonales con entradas y .

Algoritmo

Dado que los elementos se pueden sobrescribir a medida que se calculan en este algoritmo, solo se necesita un vector de almacenamiento y se omite la indexación de vectores. El algoritmo es el siguiente:

Entradas: A , b , ω
Salida: φElija una suposición inicial φ para la solución repita hasta la convergencia para  i  desde 1 hasta  n  establezca σ en 0 para  j  desde 1 hasta  n  haga  si  ji  luego establezca σ en σ + a ij  φ j  end if  end ( j -loop ) establezca φ i en (1 − ω ) φ i + ω ( b iσ ) / a ii  end ( i -bucle) comprobar si se alcanza la convergenciaterminar (repetir)
Nota
También se puede escribir , ahorrando así una multiplicación en cada iteración del bucle for externo .

Ejemplo

Se nos presenta el sistema lineal.

Para resolver las ecuaciones, elegimos un factor de relajación y un vector de estimación inicial . Según el algoritmo de sobrerelajación sucesiva, se obtiene la siguiente tabla, que representa una iteración ejemplar con aproximaciones, que idealmente, pero no necesariamente, encuentra la solución exacta, (3, −2, 2, 1) , en 38 pasos.

A continuación se ofrece una implementación simple del algoritmo en Common Lisp.

;; Establezca el formato de punto flotante predeterminado en "flotación larga" para ;; garantizar el funcionamiento correcto en una gama más amplia de números. ( setf *read-default-float-format* 'long-float )  ( defparameter +NÚMERO-MÁXIMO-DE-ITERACIONES+ 100 "El número de iteraciones más allá del cual el algoritmo debe dejar de  funcionar, independientemente de su solución actual. Un número mayor de  iteraciones puede proporcionar un resultado más preciso, pero impone requisitos de rendimiento más altos  ." )   ( declamar ( tipo ( entero 0 * ) +NÚMERO-MÁXIMO-DE-ITERACIONES+ ))     ( defun get-errors ( solución-calculada- solución-exacta ) "Para cada componente del vector SOLUCIÓN-COMPUTADA, recupera su  error con respecto al vector SOLUCIÓN-EXACTA esperado, devolviendo un  vector de valores de error.  ---  Mientras ambos ingresan los vectores deben ser iguales en tamaño, esta condición  no se verifica y el más corto de los dos determina el  número de elementos del vector de salida.  ---  La fórmula establecida es la siguiente:  Let resultVectorSize = min(computedSolution.length, exactitudSolution.length)  Let. VectorResultado = nuevo vector de TamañoVectorResultado  Para i de 0 a (TamañoVectorResultado - 1)  VectorResultado[i] = Soluciónexacta[i] - Solucióncalculada[i]  Devuelve VectorResultado" ( declarar ( tipo ( número de vector * ) solución-calculada )) ( declarar ( escriba ( número de vector * ) solución-exacta )) ( mapa ' ( número de vector * ) #' - solución-exacta solución -calculada ))                       ( defun is-convergent ( errores &key ( error-tolerance 0.001 )) "Comprueba si se alcanza la convergencia con respecto al  vector ERRORES que registra la discrepancia entre el  vector solución calculado y el exacto.  ---  La convergencia se cumple si y solo si cada componente de error absoluto  es menor o igual a la TOLERANCIA DE ERRORES, es decir:  Para todo e en ERRORES, se cumple: abs(e) <= errorTolerance." ( declarar ( escribir ( número de vector * ) errores )) ( declarar ( escribir número de error-tolerancia )) ( flet (( el error-es-aceptable ( error ) ( declarar ( escribir número de error )) ( <= ( abs error ) error-tolerancia ))) ( cada #' error-es -errores aceptables )))                              ( defun make-zero-vector ( tamaño ) "Crea y devuelve un vector de TAMAÑO con todos los elementos establecidos en 0." ( declara ( tipo ( entero 0 * ) tamaño )) ( tamaño de creación de matriz : elemento inicial 0.0 : tipo de elemento 'número ))               ( defun relajación excesiva sucesiva ( A b omega & clave ( phi ( make-zero-vector ( longitud b ))) ( verificación de convergencia #' ( lambda ( iteración phi ) ( declarar ( ignorar phi )) ( >= iteración + NÚMERO-MÁXIMO-DE-ITERACIONES+ )))) "Implementa el método de sobre-relajación sucesiva (SOR), aplicado sobre  las ecuaciones lineales definidas por la matriz A y el vector B del lado derecho  , empleando el factor de relajación OMEGA, devolviendo el  vector de solución calculado.  ---  El primer paso del algoritmo, la elección de una estimación inicial de PHI, está  representada por el parámetro de palabra clave opcional PHI, que por defecto  es un vector cero de la misma estructura que B. Si se proporciona, este  vector será modificado destructivamente. En cualquier caso, el vector PHI  constituye el valor del resultado de la función.  ---  La condición de terminación se implementa mediante CONVERGENCE-CHECK,  un predicado opcional  lambda(iteración phi) => booleano generalizado  que devuelve T, lo que significa lo inmediato. terminación, al lograr  la convergencia, o NIL, que indica operación continua, en caso contrario. En  su configuración predeterminada, CONVERGENCE-CHECK simplemente respeta la  ascensión de la iteración al ``+NÚMERO-MÁXIMO-DE-ITERACIONES+'',  ignorando la precisión lograda del vector PHI." ( declarar ( tipo ( número de matriz ( * * ) ) A )) ( declarar ( tipo ( número de vector * ) b )) ( declarar ( número de tipo omega )) ( declarar ( tipo ( número de vector * ) phi )) ( declarar ( tipo ( función (( entero 1 * ) ( vector número * )) * ) verificación de convergencia )) ( let (( n                                                         ( dimensión-matriz A 0 ))) ( declarar ( tipo ( entero 0 * ) n )) ( bucle para iteración de 1 por 1 hacer ( bucle para i desde 0 debajo de n por 1 hacer ( let (( rho 0 )) ( declarar ( escriba el número rho )) ( bucle para j desde 0 debajo de n por 1 hacer ( cuando ( /= j i ) ( let (( a[ij] ( aref A i j )) ( phi[j] ( aref phi j ))) ( incf rho ( * a[ij] phi[j] ))))) ( setf ( aref phi i ) ( + ( * ( - 1 omega ) ( aref phi i )) ( * ( / omega ( aref A i i )) ( - ( aref b i ) rho )))))) ( formato T "~&~d. solución = ~a" iteración phi ) ;; Compruebe si se alcanza la convergencia ( cuando ( funcall convergence-. comprobar iteración phi ) ( retorno )))) ( el ( número de vector * ) phi ))                                                                                                       ;; Invoque la función con los parámetros de ejemplo. ( let (( A ( make-array ( lista 4 4 ) : contenido-inicial ' (( 4 -1 -6 0 ) ( -5 -4 10 8 ) ( 0 9 4 -2 ) ( 1 0 -7 5 ) ))) ( b ( vector 2 21 -12 -6 )) ( omega 0.5 ) ( solución exacta ( vector 3 -2 2 1 ))) ( sobre-relajación sucesiva A b omega :verificación-de-convergencia #' ( lambda ( iteración phi ) ( declarar ( tipo ( entero 0 * ) iteración )) ( declarar ( tipo ( número de vector * ) phi )) ( let (( errores ( get-errors phi solución-exacta ))) ( declarar ( tipo ( vector número * ) errores )) ( formato T "~&~d. errores = ~a" errores de iteración ) ( o ( errores es-convergentes :tolerancia-error 0.0 ) ( >= iteración +NÚMERO-MÁXIMO-DE-ITERACIONES+ )) ))))                                                                                        

Una implementación simple en Python del pseudocódigo proporcionado anteriormente.

importar  numpy  como  np desde  scipy  importar  linalgdef  sor_solver ( A ,  b ,  omega ,  inicial_guess ,  convergence_criteria ): """  Esta es una implementación del pseudocódigo proporcionado en el artículo de Wikipedia.  Argumentos:  A: matriz numpy nxn.  b: vector numpy de n dimensiones.  omega: relajación factor.inicial_guess :  una suposición  de solución inicial para  que el solucionador  comience  . ] residual = nalg . norma ( A @ phi - b ) # Residual inicial mientras residual > criterios_convergencia : para i en el rango ( A. forma [ 0 ]): sigma = 0 para j en el rango ( A. forma [ 1 ] ): si j ! = i : sigma += A [ i , j ] * phi [ j ] phi [ i ] = ( 1 - omega ) * phi [ i ] + ( omega / A [ i , i ]) * ( b [ i ] - sigma ) residual = nalg . norma ( A @ phi - b ) paso += 1 print ( "Paso {} Residual: {:10.6g} " . formato ( paso , residual )) return phi                                                                      # Un caso de ejemplo que refleja el del artículo de Wikipedia residual_convergence  =  1e-8 omega  =  0.5  # Factor de relajaciónA  =  np . matriz ([[ 4 ,  - 1 ,  - 6 ,  0 ],  [ - 5 ,  - 4 ,  10 ,  8 ],  [ 0 ,  9 ,  4 ,  - 2 ],  [ 1 ,  0 ,  - 7 ,  5 ]])b  =  np . matriz ([ 2 ,  21 ,  - 12 ,  - 6 ])conjetura_inicial  =  np . ceros ( 4 )phi  =  sor_solver ( A ,  b ,  omega ,  conjetura_inicial ,  convergencia_residual ) print ( phi )

Sobrerelajación sucesiva simétrica

La versión para matrices simétricas A , en la que

se conoce como sobrerelajación sucesiva simétrica , o ( SSOR ), en la que

y el método iterativo es

Los métodos SOR y SSOR se atribuyen a David M. Young Jr.

Otras aplicaciones del método

Se puede utilizar una técnica similar para cualquier método iterativo. Si la iteración original tuviera la forma

entonces la versión modificada usaría

Sin embargo, la formulación presentada anteriormente, utilizada para resolver sistemas de ecuaciones lineales, no es un caso especial de esta formulación si se considera que x es el vector completo. Si en su lugar se utiliza esta formulación, la ecuación para calcular el siguiente vector se verá así

dónde . Los valores de se utilizan para acelerar la convergencia de un proceso de convergencia lenta, mientras que los valores de se utilizan a menudo para ayudar a establecer la convergencia de un proceso iterativo divergente o acelerar la convergencia de un proceso excesivo .

Existen varios métodos que establecen de forma adaptativa el parámetro de relajación en función del comportamiento observado del proceso convergente. Por lo general, ayudan a alcanzar una convergencia superlineal para algunos problemas, pero fracasan en otros.

Ver también

Notas

  1. ^ Young, David M. (1 de mayo de 1950), Métodos iterativos para resolver ecuaciones en diferencias parciales de tipo elíptico (PDF) , tesis doctoral, Universidad de Harvard , consultado el 15 de junio de 2009.
  2. ^ Törnig, Willi. Numerische Mathematik für Ingenieure und Physiker (1 ed.). Springer Berlín, Heidelberg. pag. 180.ISBN 978-3-642-96508-1. Consultado el 20 de mayo de 2024 .
  3. ^ Hackbusch, Wolfgang (2016). "4.6.2". Solución iterativa de grandes sistemas dispersos de ecuaciones | Enlace Springer . Ciencias Matemáticas Aplicadas. vol. 95. doi :10.1007/978-3-319-28483-5. ISBN 978-3-319-28481-1.
  4. ^ Greenbaum, Anne (1997). "10.1". Métodos iterativos para resolver sistemas lineales . Fronteras en Matemática Aplicada. vol. 17. doi :10.1137/1.9781611970937. ISBN 978-0-89871-396-1.

Referencias

enlaces externos