Gauss-Seidel metode til løsning af et system af lineære ligninger
Gauss-Seidel-metoden (Seidel-metoden, Libman-processen, successiv substitutionsmetode) er en klassisk iterativ metode til løsning af et system af lineære ligninger .
Opkaldt efter Seidel og Gauss .
Udtalelse af problemet
Tag systemet:
, hvor
Eller
Og vi vil vise, hvordan det kan løses ved hjælp af Gauss-Seidel-metoden.
Metode
For at tydeliggøre essensen af metoden omskriver vi problemet i formularen
Her, i den th ligning, har vi overført til højre side alle led, der indeholder , for . Denne post kan repræsenteres som
hvor, i den accepterede notation, betyder en matrix, hvis hoveddiagonal indeholder de tilsvarende elementer i matrixen og alle andre nuller; mens matricerne og indeholder øvre og nedre trekantede dele , på hvis hoveddiagonal er nuller.
Den iterative proces i Gauss-Seidel metoden er bygget efter formlen
efter at have valgt den passende indledende tilnærmelse .
Gauss-Seidel-metoden kan ses som en modifikation af Jacobi-metoden . Hovedideen med modifikationen er, at nye værdier bruges her, så snart de er modtaget, mens de i Jacobi-metoden ikke bruges før næste iteration:
hvor
Således beregnes
den i -te komponent af den -te tilnærmelse af formlen
For eksempel, når :
, det er
, det er
, det er
Konvergensbetingelse
Lad os præsentere en tilstrækkelig betingelse for metodens konvergens.
|
Sætning . Lad, hvorer matrixen invers til. Så for ethvert valg af indledende tilnærmelse:
- Gauss-Seidel-metoden konvergerer;
- metodens konvergenshastighed er lig med konvergenshastigheden for en geometrisk progression med nævneren ;
- korrekt fejlvurdering :.
|
|
Opsigelsesbetingelse
Betingelsen for afslutning af Seidel iterative proces, når nøjagtighed er opnået i en forenklet form, har formen:
En mere præcis betingelse for afslutningen af den iterative proces har formen
og kræver mere beregning. God til sparsomme matricer .
Implementeringseksempel i C++
#include <iostream>
#include <cmath>
bruger navneområde std ;
// Sluttilstand
bool konvergere ( dobbelt xk [ 10 ], dobbelt xkp [ 10 ], int n , dobbelt eps )
{
dobbelt norm = 0 ;
for ( int i = 0 ; i < n ; i ++ )
norm += ( xk [ i ] - xkp [ i ]) * ( xk [ i ] - xkp [ i ]);
return ( sqrt ( norm ) < eps ;
}
dobbelt okr ( dobbelt x , dobbelt eps )
{
int i = 0 ;
dobbelt neweps = eps ;
mens ( neweps < 1 )
{
i ++ ;
neweps *= 10 ;
}
int okr = pow ( dobbelt ( 10 ), i );
x = int ( x * okr + 0,5 ) / dobbelt ( okr );
returnere x ;
}
bool diagonal ( dobbelt a [ 10 ][ 10 ], int n )
{
int i , j , k = 1 ;
dobbelt sum ;
for ( i = 0 ; i < n ; i ++ ) {
sum = 0 ;
for ( j = 0 ; j < n ; j ++ ) sum += abs ( a [ i ][ j ]);
sum -= abs ( a [ i ][ i ]);
if ( sum > a [ i ][ i ])
{
k = 0 _
cout << a [ i ][ i ] << " < " << sum << endl ;
}
andet
{
cout << a [ i ][ i ] << " > " << sum << endl ;
}
}
return ( k == 1 );
}
int main ()
{
setlocale ( LC_ALL , "" );
dobbelt eps , a [ 10 ][ 10 ], b [ 10 ], x [ 10 ], p [ 10 ];
int n , i , j , m = 0 ;
int metode _
cout << "Indtast størrelsen af den kvadratiske matrix: " ;
cin >> n ;
cout << "Indtast beregningspræcisionen: " ;
cin >> eps ;
cout << "Fyld matrix A: " << 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 << "Din matrix A er: " << endl << endl ;
for ( i = 0 ; i < n ; i ++ )
{
for ( j = 0 ; j < n ; j ++ )
cout << a [ i ][ j ] << " " ;
cout << endl ;
}
cout << endl ;
cout << "Udfyld kolonnen for gratis medlemmer: " << endl << endl ;
for ( i = 0 ; i < n ; i ++ )
{
cout << "B[" << i + 1 << "] = " ;
cin >> b [ i ];
}
cout << endl << endl ;
/*
Metodefremskridt, hvor:
a[n][n] - Matrix af koefficienter
x[n], p[n] - Nuværende og tidligere løsninger
b[n] - Kolonne af højre dele
Alle ovenstående arrays er ægte og
skal defineres i hovedprogrammet,
også i arrayet x[n] skal du sætte initialen
løsningskolonnetilnærmelse (f.eks. alle nuller)
*/
for ( int i = 0 ; i < n ; i ++ )
x [ i ] = 1 ;
cout << "Diagonal dominans: " << endl ;
if ( diagonal ( a , n )) {
gør
{
for ( int i = 0 ; i < n ; i ++ )
p [ i ] = x [ i ];
for ( int i = 0 ; i < n ; i ++ )
{
dobbelt 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 ++ ;
} mens ( ! konvergerer ( x , p , n , eps ));
cout << "Systembeslutning:" << endl << endl ;
for ( i = 0 ; i < n ; i ++ ) cout << "x" << i << " = " << okr ( x [ i ], eps ) << "" << endl ;
cout << "Iterations: " << m << endl ;
}
andet {
cout << "Ingen diagonal dominans" << endl ;
}
system ( "pause" );
returnere 0 ;
}
Implementeringseksempel i Python
import numpy som np
def seidel ( A , b , eps ):
n = len ( A )
x = np . nuller ( n ) # nul vektor
converge = Falsk
, mens den ikke konvergerer :
x_new = np . kopi ( x )
for i i område ( n ):
s1 = sum ( A [ i ][ j ] * x_ny [ j ] for j i område ( i ))
s2 = sum ( A [ i ][ j ] * x [ j ] for j i området ( i + 1 , n ))
x_new [ i ] = ( b [ i ] - s1 - s2 ) / A [ i ][ i ]
konvergere = np . sqrt ( sum (( x_new [ i ] - x [ i ]) ** 2 for i i området ( n ))) <= eps
x = x_new
returnere x
Se også
Noter
Links
Metoder til løsning af SLAE |
---|
Direkte metoder |
|
---|
Iterative metoder |
|
---|
Generel |
|
---|