Գաուս-Զեյդելի մեթոդ

testwiki-ից
00:44, 4 սեպտեմբերի 2024 տարբերակ, imported>InternetArchiveBot
(տարբ) ←Նախորդ տարբերակ | Ընթացիկ տարբերակ (տարբ) | Հաջորդ տարբերակ→ (տարբ)
Jump to navigation Jump to search

Գաուս-Զեյդելի մեթոդը (Զեյդելի մեթոդ, Լիբմանի պրոցես, հաջորդական փոխարինումների մեթոդ) հանդիսանում է դասական իտերացիոն մեթոդով հավասարումների համակարգի լուծում[1]։ Այն անվանվում է ի պատիվ Զեյդելի և Գաուսի։

Խնդրի դրվածքը

Դիտարկենք հավասարումների համակարգը՝

Ax=b, где A=(a11a1nan1ann),b=(b1bn)

կամ

{a11x1++a1nxn=b1an1x1++annxn=bn

և ցույց տանք, թե ինչպես կարելի է լուծել այն Գաուս-Զեյդելի մեթոդով։

Մեթոդը

Մեթոդի էությունը պարզաբանելու համար առաջադրանքը գրենք հետևյալ տեսքով՝

{a11x1=a12x2a13x3a1nxn+b1a21x1+a22x2=a23x3a2nxn+b2a(n1)1x1+a(n1)2x2++a(n1)(n1)xn1=a(n1)nxn+bn1an1x1+an2x2++an(n1)xn1+annxn=bn

Այստեղ j-րդ հավասարումում մենք աջ մաս տեղափոխեցինք բոլոր այն xi անդամները, որտեղ բավարարում էր i>j պայմանը։ Այս գրառումը կարող է ներկայացվել հետևյալ ձևով՝

(L+D)x=Ux+b,

որտեղ ընդունված նշանակումներով Dմատրից է, որում գլխավոր անկյունագծի վրա գրված են A մատրիցի համապատասխան անդամները, իսկ մնացած անդամները զրոներ են, այնինչ U և L մատրիցները պարունակում են A մատրիցի վերևի և ներքևի եռանկյունային մասերը, որոնց գլխավոր անկյունագծի վրա զրոներ են։ Գաուս-Զեյդելի մեթոդում իտերացիոն պրոցեսը ստեղծվում է հետևյալ բանաձևով՝

(L+D)x(k+1)=Ux(k)+b,k=0,1,2,

համապատասխան x(0) սկզբնական մոտարկման ընտրությամբ։

Գաուս-Զեյդելի մեթոդը կարելի է դիտարկել որպես Յակոբիի մեթոդի մոդիֆիկացիա։ Մոդիֆիկացիայի հիմնական գաղափարը կայանում է նրանում, որ այստեղ x(i) նոր արժեքները օգտագործվում են անմիջապես ստանալուց հետո, այնինչ Յակոբիի մեթոդում այն չի օգտագործվում մինչև հաջորդ իտերացիան՝

{x1(k+1)=c12x2(k)+c13x3(k)++c1nxn(k)+d1x2(k+1)=c21x1(k+1)+c23x3(k)++c2nxn(k)+d2xn(k+1)=cn1x1(k+1)+cn2x2(k+1)++cn(n1)xn1(k+1)+dn,

որտեղ

cij={aijaii,ji,0,j=i.di=biaii,i=1,,n.

Այսպիսով, i-րդ կոմպոնենտի (k+1)-րդ մոտարկման հաշվարկը կատարվում է

xi(k+1)=j=1i1cijxj(k+1)+j=incijxj(k)+di,i=1,,n

բանաձևով։

Օրինակ, n=3-ի դեպքում`

x1(k+1)=j=111c1jxj(k+1)+j=13c1jxj(k)+d1, այսինքն x1(k+1)=c11x1(k)+c12x2(k)+c13x3(k)+d1,
x2(k+1)=j=121c2jxj(k+1)+j=23c2jxj(k)+d2, այսինքն x2(k+1)=c21x1(k+1)+c22x2(k)+c23x3(k)+d2,
x3(k+1)=j=131c3jxj(k+1)+j=33c3jxj(k)+d3, այսինքն x3(k+1)=c31x1(k+1)+c32x2(k+1)+c33x3(k)+d3:

Զուգամիտության պայման

Բերենք զուգամիտության մեթոդի բավարար պայման։ Կաղապար:Message box

Դադարեցման պայմանը

Զեյդելի պրոցեսի իտերացիայի ավարտի պայմանը անհրաժեշտ ε ճշգրտության դեպքում կրճատ ձևով ունի այսպիսի տեսք՝

x(k+1)x(k)ε

Իտերացիոն պրոցեսի առավել ճշգրիտ պայմանը ունի այսպիսի տեսք՝

Ax(k)bε

և պահանջում է ավելի շատ հաշվարկներ։ Այն բավականին հարմար է կտրտված մատրիցների համար։

Իրականացման օրինակ C++ - ում

#include <iostream>
#include <cmath>

using namespace std;

// Ավարտի պայման
bool converge(double xk[10], double xkp[10], int n, double eps)
{
	double norm = 0;
	for (int i = 0; i < n; i++)
		norm += (xk[i] - xkp[i]) * (xk[i] - xkp[i]);
	return (sqrt(norm) < eps);
}

double okr(double x, double eps)
{
	int i = 0;
	while (eps != 1)
	{
		i++;
		eps *= 10;
	}
	int okr = pow(double(10), i);
	x = int(x * okr + 0.5) / double(okr);

	return x;
}

bool diagonal(double a[10][10], int n)
{
	int i, j, k = 1;
	double sum;
	for (i = 0; i < n; i++) {
		sum = 0;
		for (j = 0; j < n; j++) sum += a[i][j];
		sum -= a[i][i];
		if (sum > a[i][i]) 
		{
			k = 0; 
			cout << a[i][i] << " < " << sum << endl;
		}
		else
		{
			cout << a[i][i] << " > " << sum << endl;
		}
		

	}

	return (k == 1);

}

int main()
{
	setlocale(LC_ALL, "");

	double eps, a[10][10], b[10], x[10], p[10];
	int n, i, j, m = 0;
	int method;
	cout << "Մուտքագրել քառակուսի մատրիցի չափը՝ ";
	cin >> n;
	cout << "Մուտքագրել հաշվարկի ճշտությունը՝ ";
	cin >> eps;
	cout << "Մուտքագրել А մատրիցն՝ " << 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 << " Ձեր А մատրիցն՝ " << endl << endl;
	for (i = 0; i < n; i++)
	{
		for (j = 0; j < n; j++)
			cout << a[i][j] << " ";
		cout << endl;
	}

	cout << endl;

	cout << "Լրացրեք ազատ անդամների սյունը՝ " << endl << endl;
	for (i = 0; i < n; i++)
	{
		cout << "В[" << i + 1 << "] = ";
		cin >> b[i];
	}

	cout << endl << endl;

	/*
	Քայլ մեթոդ, որտեղ։
	a[n][n] - մատրիցի գործակիցներն են
	x[n], p[n] - Ընթացիկ և նախորդ լուծումները
	b[n] - Աջ մասերի սյունը
	Բոլոր թվարկված զանգվածները իրական են և
	պետք է որոշված լինեն հիմնական ծրագրում,
	ինչպես նաև x[n] մասիվում անհրաժեշտ է լրացնել սկզբնական
	սյան լուծումի մոտարկումը (օրիակ, բոլորը զրոներ)
	*/

	for (int i = 0; i < n; i++)
		x[i] = 1;

	cout << "Անկյունագծային գերակշռություն՝ " << endl;
	if (diagonal(a, n)) {
		do
		{
			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 < i; j++)
					var += (a[i][j] * x[j]);
				for (int j = i + 1; j < n; j++)
					var += (a[i][j] * p[j]);
				x[i] = (b[i] - var) / a[i][i];
			}
			m++;
		} while (!converge(x, p, n, eps));

		cout << "Համակարգի լուծում՝" << endl << endl;
		for (i = 0; i < n; i++) cout << "x" << i << " = " << okr(x[i], eps) << "" << endl;
		cout << "Իտերացիա՝ " << m << endl;
	}
	else {
		cout << "Չի կատարվում անկյունագծերի գերակշռություն։" << endl;
	}

	system("pause");
	return 0;
}

Իրականացման օրինակ Python - ում

from math import sqrt
import numpy as np

def seidel(A, b, eps):
    n = len(A)
    x = [.0 for i in range(n)]

    converge = False
    while not converge:
        x_new = np.copy(x)
        for i in range(n):
            s1 = sum(A[i][j] * x_new[j] for j in range(i))
            s2 = sum(A[i][j] * x[j] for j in range(i + 1, n))
            x_new[i] = (b[i] - s1 - s2) / A[i][i]

        converge = sqrt(sum((x_new[i] - x[i]) ** 2 for i in range(n))) <= eps
        x = x_new

    return x

Տես նաև

Ծանոթագրություններ

Կաղապար:Ծանցանկ

Արտաքին հղումներ

Կաղապար:Մաթեմատիկա–ներքև

  1. Ա․Գ․ Կուրոշ, Բարձրագույն հանրահաշվի դասընթաց, «Լույս» հրատարակչություն, Երևան, 1965