Gauss-Seidel módszer lineáris egyenletrendszer megoldására

A Gauss-Seidel módszer (Seidel-módszer, Libman-folyamat, szekvenciális helyettesítési módszer) egy klasszikus iteratív módszer lineáris egyenletrendszer megoldására .

Seidelről és Gaussról kapta a nevét .

A probléma leírása

Vegyük a rendszert: , hol

Vagy

És megmutatjuk, hogyan lehet ezt Gauss-Seidel módszerrel megoldani.

Módszer

A módszer lényegének tisztázására átírjuk a problémát az űrlapba

Itt az egyenletben átvittük a jobb oldalra az összes olyan kifejezést, amelyek tartalmazzák a , for . Ez a bejegyzés a következővel ábrázolható

ahol az elfogadott jelölésben olyan mátrixot jelent, amelynek főátlója tartalmazza a mátrix megfelelő elemeit és az összes többi nullát; míg a és mátrixok felső és alsó háromszög alakú részeket tartalmaznak , amelyek főátlóján nullák vannak.

Az iteratív folyamat a Gauss-Seidel módszerben a képlet szerint épül fel

a megfelelő kezdeti közelítés kiválasztása után .

A Gauss-Seidel módszer a Jacobi-módszer módosításaként tekinthető . A módosítás fő gondolata, hogy az új értékeket a beérkezésükkor használjuk fel, míg a Jacobi-módszerben csak a következő iterációig:

ahol

Így a -edik közelítés i -edik komponensét a képlet számítja ki

Például amikor :

, vagyis , vagyis , vagyis

Konvergencia feltétel

Tegyünk egy elégséges feltételt a módszer konvergenciájához.

Tétel .
Legyen, ahola mátrix inverze -re. Ezután a kezdeti közelítés bármely választásához:
  1. a Gauss-Seidel módszer konvergál;
  2. a módszer konvergencia sebessége megegyezik egy geometriai haladás nevezővel való konvergenciájának sebességével ;
  3. helyes hibabecslés: .

Felmondási feltétel

A Seidel iteratív folyamat befejezésének feltétele, ha a pontosság egyszerűsített formában érhető el, a következő:

Az iteratív folyamat befejezésének pontosabb feltétele a forma

és több számítást igényel. Ritka mátrixokhoz jó .

Megvalósítási példa C++ nyelven

#include <iostream> #include <cmath> névtér használata std ; // Végfeltétel bool konverge ( double xk [ 10 ], double xkp [ 10 ], int n , double eps ) { kettős norma = 0 ; for ( int i = 0 ; i < n ; i ++ ) norma += ( xk [ i ] - xkp [ i ]) * ( xk [ i ] - xkp [ i ]); return ( sqrt ( norma ) < eps ); } dupla okr ( double x , double eps ) { int i = 0 ; double neweps = eps ; míg ( új hírek < 1 ) { i ++ ; neweps *= 10 ; } int okr = pow ( double ( 10 ), i ); x = int ( x * okr + 0,5 ) / double ( okr ); visszatér x ; } bool átló ( dupla a [ 10 ][ 10 ], int n ) { int i , j , k = 1 ; dupla összeg ; for ( i = 0 ; i < n ; i ++ ) { összeg = 0 ; for ( j = 0 ; j < n ; j ++ ) összeg += abs ( a [ i ][ j ]); összeg -= absz ( a [ i ][ i ]); if ( összeg > a [ i ][ i ]) { k = 0_ _ cout << a [ i ][ i ] << " < " << összeg << endl ; } más { cout << a [ i ][ i ] << " > " << összeg << endl ; } } return ( k == 1 ); } int main () { setlocale ( LC_ALL , "" ); dupla eps , a [ 10 ][ 10 ], b [ 10 ], x [ 10 ], p [ 10 ]; int n , i , j , m = 0 ; int metódus _ cout << "Adja meg a négyzetmátrix méretét: " ; cin >> n ; cout << "Adja meg a számítási pontosságot: " ; cin >> eps ; cout << "A mátrix kitöltése: " << endl << endl ; for ( i = 0 ; i < n ; i ++ ) for ( j = 0 ; j < n ; j ++ ) { cout << "A[" << i << "][" << j << "] = " ; cin >> a [ i ][ j ]; } cout << endl << endl ; cout << "Az A mátrixod: " << endl << endl ; for ( i = 0 ; i < n ; i ++ ) { for ( j = 0 ; j < n ; j ++ ) cout << a [ i ][ j ] << " " ; cout << endl ; } cout << endl ; cout << "Töltsd ki az ingyenes tagok oszlopot: " << endl << endl ; for ( i = 0 ; i < n ; i ++ ) { cout << "B[" << i + 1 << "] = " ; cin >> b [ i ]; } cout << endl << endl ; /* A módszer előrehaladása, ahol: a[n][n] - Együtthatók mátrixa x[n], p[n] - Jelenlegi és korábbi megoldások b[n] - Jobb oldali részek oszlopa A fenti tömbök mindegyike valós és meg kell határozni a főprogramban, az x[n] tömbbe is be kell tenni a kezdőbetűt megoldás oszlop közelítése (pl. minden nulla) */ for ( int i = 0 ; i < n ; i ++ ) x [ i ] = 1 ; cout << "Diagonális dominancia: " << endl ; if ( átlós ( a , n )) { csináld { for ( int i = 0 ; i < n ; i ++ ) p [ i ] = x [ i ]; for ( int i = 0 ; i < n ; i ++ ) { double var = 0 ; for ( int j = 0 ; j < n ; j ++ ) if ( j != i ) var += ( a [ i ][ j ] * x [ j ]); x [ i ] = ( b [ i ] - var ) / a [ i ][ i ]; } m ++ ; } while ( ! konverge ( x , p , n , eps )); cout << "Rendszerdöntés:" << endl << endl ; for ( i = 0 ; i < n ; i ++ ) cout << "x" << i << " = " << okr ( x [ i ], eps ) << "" << endl ; cout << "Iterációk: " << m << endl ; } else { cout << "Nincs átlós dominancia" << endl ; } system ( "szünet" ); return 0 ; }


Megvalósítási példa Pythonban

import numpy mint np def seidel ( A , b , eps ): n = len ( A ) x = np . nullák ( n ) # nulla vektor converge = Hamis , miközben nem konvergál : x_new = np . másolás ( x ) i - re az ( n tartományban ): s1 = összeg ( A [ i ][ j ] * x_új [ j ] j esetén az ( i ) tartományban ) s2 = összeg ( A [ i ][ j ] * x [ j ] j esetén az ( i + 1 , n ) tartományban ) x_új [ i ] = ( b [ i ] - s1 - s2 ) / A [ i ][ i ] konvergál = np . sqrt ( összeg (( x_új [ i ] - x [ i ]) ** 2 for i tartományban ( n ))) < = eps x = x_new vissza x

Lásd még

Jegyzetek

Linkek