Jacobi - menetelmä on muunnelma yksinkertaisesta iteraatiomenetelmästä lineaaristen algebrallisten yhtälöiden ratkaisemiseksi . Nimetty Carl Gustav Jacobin mukaan .
Otetaan lineaarinen yhtälöjärjestelmä:
, missä
Tai
Jacobin menetelmän iteratiivisen proseduurin rakentamiseksi on tarpeen suorittaa alustava yhtälöjärjestelmän muunnos iteratiiviseen muotoon . Se voidaan tehdä jollakin seuraavista säännöistä:
missä hyväksytyssä merkinnässä tarkoittaa matriisia, jonka päädiagonaali sisältää vastaavat matriisin elementit ja kaikki muut nollat; kun taas matriisit ja sisältävät ylemmän ja alemman kolmion muotoisen osan , jonka päädiagonaalissa nollia, on identiteettimatriisi .
Sitten menettely ratkaisun löytämiseksi on:
Tai elementtikohtaisena kaavana:
missä on iteraatiolaskuri.
Toisin kuin Gauss-Seidel-menetelmässä, emme voi korvata arvolla iteratiivisen prosessin aikana, koska näitä arvoja tarvitaan lopuissa laskelmissa. Tämä on merkittävin ero Jacobi-menetelmän ja Gauss-Seidel-menetelmän välillä SLAE :n ratkaisemiseksi . Siten jokaisessa iteraatiossa molemmat approksimaatiovektorit on tallennettava: vanha ja uusi.
Esitetään riittävä ehto menetelmän konvergenssille.
Lause . Anna. Sitten mistä tahansa alkuperäisen likiarvon valinnasta:
|
Iteratiivisen prosessin päättymisen ehto, kun tarkkuus saavutetaan , on muotoa:
Riittävän hyvin käsitellylle matriisille (kohdalle ), se pätee for
Tämä kriteeri ei vaadi matriisinormin laskemista ja sitä käytetään usein käytännössä. Tässä tapauksessa iteratiivisen prosessin päättymisen tarkalla ehdolla on muoto
ja vaatii ylimääräistä matriisi-vektori kertolaskua jokaisessa iteraatiossa, mikä noin kaksinkertaistaa algoritmin laskennallisen monimutkaisuuden.
Alla on toteutusalgoritmi C++:ssa
#include <math.h> const double eps = 0,001 ; ///< haluttu tarkkuus .......................... /// N - matriisin ulottuvuus; A[N][N] - kertoimien matriisi, F[N] - vapaiden termien sarake, /// X[N] - alkuperäinen approksimaatio, vastaus kirjoitetaan myös X[N]; tyhjä Jacobi ( int N , double ** A , double * F , double * X ) { double * TempX = uusi tupla [ N ]; kaksinkertainen normi ; // normi, joka määritellään suurimmaksi eroksi viereisten iteraatioiden x-sarakekomponenttien välillä. do { for ( int i = 0 ; i < N ; i ++ ) { TempX [ i ] = F [ i ]; for ( int g = 0 ; g < N ; g ++ ) { jos ( i != g ) TempX [ i ] -= A [ i ][ g ] * X [ g ]; } TempX [ i ] /= A [ i ][ i ]; } norm = fabs ( X [ 0 ] - TempX [ 0 ]); for ( int h = 0 ; h < N ; h ++ ) { if ( fabs ( X [ h ] - TempX [ h ]) > norm ) norm = fabs ( X [ h ] - TempX [ h ]); X [ h ] = TempX [ h ]; } } while ( norm > eps ); poista [] TempX ; }Seuraavassa on toteutusalgoritmi Pythonissa
from collections.abc Import Sequence , MutableSequence def Jacobi ( A : Sequence [ Sequence [ float ]], b : Sequence [ float ], eps : float = 0.001 , x_init : MutableSequence [ float ] | None = Ei mitään ) -> list [ float ]: """ Jacobi-menetelmä kohteelle A*x = b(*) :param A: Matriisi (*) vasemmalla :param b: tunnettu vektori (*) oikealla :param x_init: alkuperäinen approksimaatio :return: likimääräinen x-arvo (*) """ def summa ( a : Sequence [ float ], x : Sequence [ float ], j : int ) -> float : S : float = 0 for i , ( m , y ) in enumerate ( zip ( a , x )): jos i != j : S += m * y palauttaa S def norm ( x : sekvenssi [ float ], y : sekvenssi [ float ]) -> float : paluu max (( abs ( x0 - y0 ) x0 , y0 zip -muodossa ( x , y ) )) jos x_init on Ei mitään : y = [ a / A [ i ] [ i ] i : lle , a luettelossa ( b )] else : y = x . kopioi () x : lista [ float ] = [ - ( summa ( a , y , i ) - b [ i ]) / A [ i ][ i ] for i , a in enumerate ( A )] kun taas normi ( y , x ) > eps : i : lle elem in enumerate ( x ): y [ i ] = elem i : lle , a luettelossa ( A ): x [ i ] = - ( summa ( a , y , i ) ) - b [ i ]) / A [ i ][ i ] palauttaa xSLAE :n ratkaisemiseksi | Menetelmät|
---|---|
Suorat menetelmät | |
Iteratiiviset menetelmät | |
Kenraali |
|