stringtranslate.com

Relajación excesiva sucesiva

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

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 sobre-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 , requiriendo cierta experiencia para asegurar la convergencia a la solución, lo que los hizo 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:

Luego A se puede descomponer en un componente diagonal D y componentes triangulares estrictamente inferior y superior L y U :

dónde

El sistema de ecuaciones lineales puede reescribirse como:

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

El método de relajación sucesiva es una técnica iterativa que resuelve el lado izquierdo de esta expresión para x , utilizando el valor anterior de x en el lado derecho. Analíticamente, esto se puede escribir 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 utilizando sustitución hacia adelante :

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

Convergencia

Radio espectral de la matriz de iteración del 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étrica y definida positiva, entonces para . Por lo tanto, se deduce la convergencia del proceso de iteración, pero en general nos interesa una convergencia más rápida en lugar de una simple 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 viene dado por

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

El último supuesto se satisface 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 funciona de la siguiente manera:

Entradas: A , b , ω
Salida: φElija una estimación inicial φ para la solución repita hasta la convergencia para  i  desde 1 hasta  n  haga establezca σ en 0 para  j  desde 1 hasta  n  haga  si  ji  entonces establezca σ en σ + a ij  φ j  fin si  fin ( j -loop) establezca φ i en (1 − ω ) φ i + ω ( b iσ ) / a ii  end ( i -bucle) comprobar si se alcanza la convergenciafin (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 aproximación inicial . De acuerdo con el algoritmo de sobre-relajació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 "long-float" para ;; garantizar el funcionamiento correcto en un rango más amplio de números. ( setf *read-default-float-format* 'long-float )  ( defparameter +MAXIMUM-NUMBER-OF-ITERATIONS+ 100 "El número de iteraciones más allá del cual el algoritmo debe dejar de  funcionar, independientemente de su solución actual. Un mayor número de  iteraciones puede proporcionar un resultado más preciso, pero impone mayores  requisitos de rendimiento." )   ( declaim ( tipo ( entero 0 * ) + NÚMERO MÁXIMO DE ITERACIONES + ))     ( defun get-errors ( calculated-solution exact-solution ) "Para cada componente del vector COMPUTED-SOLUTION, recupera su  error con respecto al vector EXACT-SOLUTION esperado, devolviendo un  vector de valores de error.  ---  Si bien ambos vectores de entrada 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, exactSolution.length)  Let resultVector = new vector of resultVectorSize  For i from 0 to (resultVectorSize - 1)  resultVector[i] = exactSolution[i] - calculatedSolution[i]  Return resultVector" ( declare ( type ( vector number * ) calculated-solution )) ( declare ( type ( vector number * ) exact-solution )) ( map ' ( vector number * ) #' - exact-solution calculated-solution ))                       ( defun is-convergent ( errors &key ( error-tolerance 0.001 )) "Comprueba si se alcanza la convergencia con respecto al  vector ERRORS 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 ERROR-TOLERANCE, es decir:  Para todo e en ERRORS, se cumple: abs(e) <= errorTolerance." ( declare ( type ( vector number * ) errors )) ( declare ( type number error-tolerance )) ( flet (( error-is-acceptable ( error ) ( declare ( type number error )) ( <= ( abs error ) error-tolerance ))) ( every #' error-is-acceptable errors )))                              ( defun make-zero-vector ( size ) "Crea y devuelve un vector del TAMAÑO con todos los elementos establecidos en 0." ( declare ( type ( entire 0 * ) size )) ( make-array size :initial-element 0.0 :element-type 'number ))               ( defun successive-over-relaxation ( A b omega &key ( phi ( make-zero-vector ( length b ))) ( convergence-check #' ( lambda ( iteration phi ) ( declare ( ignore phi )) ( >= iteration +MAXIMUM-NUMBER-OF-ITERATIONS+ )))) "Implementa el método de sobre-relajación sucesiva (SOR), aplicado sobre  las ecuaciones lineales definidas por la matriz A y el vector del lado derecho  B, empleando el factor de relajación OMEGA, devolviendo el  vector solución calculado.  ---  El primer paso del algoritmo, la elección de una estimación inicial 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 es implementada por CONVERGENCE-CHECK,  un predicado opcional  lambda(iteration phi) => booleano generalizado  que devuelve T, lo que significa la terminación inmediata, al lograr  la convergencia, o NIL, lo que indica una operación continua, en caso contrario. En  su configuración predeterminada, CONVERGENCE-CHECK simplemente respeta la  ascensión de la iteración al ``+MÁXIMO-NÚMERO-DE-ITERACIONES+'',  ignorando la precisión lograda del vector PHI. ( declare ( type ( array number ( * * )) A )) ( declare ( type ( vector number * ) b )) ( declare ( type number omega )) ( declare ( type ( vector number * ) phi )) ( declare ( type ( function (( entero 1 * ) ( vector number * )) * ) convergence-check )) ( let (( n                                                         ( array-dimension A 0 ))) ( declare ( type ( whole 0 * ) n )) ( loop for iteration from 1 for 1 do ( loop for i from 0 below n for 1 do ( let (( rho 0 )) ( declare ( type number rho )) ( loop for j from 0 below n for 1 do ( when ( /= 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 )))))) ( format T "~&~d. solution = ~a" iteration phi ) ;; Comprueba si se alcanza la convergencia. ( cuando ( funcall convergence-check iteration phi ) ( return )))) ( el ( vector number * ) phi ))                                                                                                       ;; Invoca la función con los parámetros de ejemplo. ( let (( A ( make-array ( list 4 4 ) :initial-contents ' (( 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 ) ( exact-solution ( vector 3 -2 2 1 ))) ( sucesiva-sobre-relajación A b omega :convergence-check #' ( lambda ( iteración phi ) ( declare ( type ( entero 0 * ) iteración )) ( declare ( type ( vector número * ) phi )) ( let (( errors ( get-errors phi exact-solution ))) ( declare ( type ( vector número * ) errores )) ( format T "~&~d. errores = ~a" iteración errores ) ( or ( errores convergentes : tolerancia a errores 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 ,  initial_guess ,  convergence_criteria ): """  Esta es una implementación del pseudocódigo proporcionado en el artículo de Wikipedia.  Argumentos:  A: matriz numpy de nxn.  b: vector numpy de n dimensiones.  omega: factor de relajación.  initial_guess: una estimación de solución inicial con la que el solucionador debe comenzar.  convergence_criteria: la discrepancia máxima aceptable para considerar que la solución actual es adecuada.  Devuelve:  phi: vector de solución de dimensión n.  """ step = 0 phi = initial_guess [:] residual = linalg . norm ( A @ phi - b ) # Residuo inicial while residual > convergence_criteria : para i en rango ( A . shape [ 0 ]): sigma = 0 para j en rango ( A . shape [ 1 ]): si j != i : sigma += A [ i , j ] * phi [ j ] phi [ i ] = ( 1 - omega ) * phi [ i ] + ( omega / A [ i , i ]) * ( b [ i ] - sigma ) residual = linalg . norm ( A @ phi - b ) paso += 1 print ( "Paso {} Residual: {:10.6g} " . format ( 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 ,  estimación_inicial ,  convergencia_residual ) print ( phi )

Relajación excesiva sucesiva simétrica

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

se denomina Sobre-relajació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 se utiliza esta formulación en su lugar, la ecuación para calcular el siguiente vector será similar a

donde . 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 de sobreimpulso .

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 fallan para otros.

Véase 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. Recuperado el 20 de mayo de 2024 .
  3. ^ Hackbusch, Wolfgang (2016). "4.6.2". Solución iterativa de grandes sistemas dispersos de ecuaciones | SpringerLink . Applied Mathematical Sciences. 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 . Frontiers in Applied Mathematics. Vol. 17. doi :10.1137/1.9781611970937. ISBN 978-0-89871-396-1.

Referencias

Enlaces externos