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

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

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

A\vec{x}=\vec{b}, где A=\left(
\begin{array}{ccc}
a_{11} & \ldots & a_{1n} \\
\vdots & \ddots & \vdots \\
a_{n1} & \ldots & a_{nn} 
\end{array} \right),\quad \vec{b}=\left(
\begin{array}{c}
b_1 \\
\vdots \\
b_n 
\end{array} \right)

կամ

\left\{
\begin{array}{rcl}
a_{11}x_1 + \ldots + a_{1n}x_n& = & b_{1} \\
& &\\
a_{n1}x_1 + \ldots + a_{nn}x_n & = & b_{n} 
\end{array} \right.

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

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

:\left\{
\begin{array}{lcr}
a_{11}x_1 & = &-a_{12}x_2 - a_{13}x_3 -\ldots - a_{1n}x_n  +  b_1\\
a_{21}x_1 + a_{22}x_2 & = & -a_{23}x_3 - \ldots - a_{2n}x_n  +  b_2\\
\ldots & &\\
a_{(n-1)1}x_1 + a_{(n-1)2}x_2 +\ldots+ a_{(n-1)(n-1)}x_{n-1} & = & -a_{(n-1)n}x_n + b_{n-1}\\
a_{n1}x_1 + a_{n2}x_2 +\ldots+ a_{n(n-1)}x_{n-1}+ a_{nn}x_n & = & b_n
\end{array} \right.

Այստեղ j-րդ հավասարումում մենք աջ մաս տեղափոխեցինք բոլոր այն x_i անդամները, որտեղ բավարարում էր i > j պայմանը։ Այս գրառումը կարող է ներկայացվել հետևյալ ձևով՝
:(\mathrm{L} + \mathrm{D} )\vec{x} = -\mathrm{U} \, \vec{x} + \vec{b},
որտեղ ընդունված նշանակումներով \mathrm{D}-ն մատրից է, որում գլխավոր անկյունագծի վրա գրված են  A մատրիցի համապատասխան անդամները, իսկ մնացած անդամները զրոներ են, այնինչ \mathrm{U} և \mathrm{L} մատրիցները պարունակում են A մատրիցի վերևի և ներքևի եռանկյունային մասերը, որոնց գլխավոր անկյունագծի վրա զրոներ են։
Գաուս-Զեյդելի մեթոդում իտերացիոն պրոցեսը ստեղծվում է հետևյալ բանաձևով՝
:(\mathrm{L} + \mathrm{D})\vec{x}^{(k+1)} = -\mathrm{U} \vec{x}^{(k)} + \vec{b}, \quad k = 0, 1, 2, \ldots
համապատասխան \vec{x}^{(0)} սկզբնական մոտարկման ընտրությամբ։

Գաուս-Զեյդելի մեթոդը կարելի է դիտարկել որպես Յակոբիի մեթոդի մոդիֆիկացիա։ Մոդիֆիկացիայի հիմնական գաղափարը կայանում է նրանում, որ այստեղ \vec{x}^{(i)} նոր արժեքները օգտագործվում են անմիջապես ստանալուց հետո, այնինչ Յակոբիի մեթոդում այն չի օգտագործվում մինչև հաջորդ իտերացիան՝
:\left\{\begin{array}{ccccccccccc}
{x_{1}}^{(k+1)} &=& c_{12}{x_2^{(k)}} &+& c_{13}x_3^{(k)}&+& {\ldots}&+& c_{1n}{x_n}^{(k)} &+& d_1 \\
{x_{2}}^{(k+1)} &=& c_{21}{x_1^{(k+1)}} &+& c_{23}x_3^{(k)}&+& {\ldots}&+& c_{2n}{x_n}^{(k)} &+& d_2 \\
\ldots & & & & & & & & & & \\
{x_{n}}^{(k+1)} &=& c_{n1}{x_1^{(k+1)}} &+& c_{n2}{x_2^{(k+1)}}&+& {\ldots}&+& c_{n(n-1)}{x_{n-1}}^{(k+1)} &+& d_n
\end{array}\right.,

որտեղ

:c_{ij} = \begin{cases}
 -\frac{a_{ij}}{a_{ii}}, & j \neq i,\\
 0, & j = i.
\end{cases} \quad
d_i = \frac{b_i}{a_{ii}}, \quad
i = 1, \ldots, n.
Այսպիսով, i-րդ կոմպոնենտի (k+1)-րդ մոտարկման հաշվարկը կատարվում է 
:x_i^{(k+1)}=\sum_{j=1}^{i-1}c_{ij}x_{j}^{(k+1)}+\sum_{j=i}^{n}c_{ij}x_{j}^{(k)}+d_i, \quad i=1,\ldots,n
բանաձևով։

Օրինակ, n=3-ի դեպքում`
: x_1^{(k+1)}=\sum_{j=1}^{1-1}c_{1j}x_{j}^{(k+1)}+\sum_{j=1}^{3}c_{1j}x_{j}^{(k)}+d_1, այսինքն x_1^{(k+1)}=  c_{11}x_{1}^{(k)} + c_{12}x_{2}^{(k)}+ c_{13}x_{3}^{(k)}  +  d_1,
: x_2^{(k+1)}=\sum_{j=1}^{2-1}c_{2j}x_{j}^{(k+1)}+\sum_{j=2}^{3}c_{2j}x_{j}^{(k)}+d_2, այսինքն x_2^{(k+1)}=  c_{21}x_{1}^{(k+1)} + c_{22}x_{2}^{(k)}+ c_{23}x_{3}^{(k)}  +  d_2,
: x_3^{(k+1)}=\sum_{j=1}^{3-1}c_{3j}x_{j}^{(k+1)}+\sum_{j=3}^{3}c_{3j}x_{j}^{(k)}+d_3, այսինքն x_3^{(k+1)}=  c_{31}x_{1}^{(k+1)} + c_{32}x_{2}^{(k+1)}+ c_{33}x_{3}^{(k)}  +  d_3:

## Զուգամիտության պայման
Բերենք զուգամիտության մեթոդի բավարար պայման։

## Դադարեցման պայմանը
Զեյդելի պրոցեսի իտերացիայի ավարտի պայմանը անհրաժեշտ \varepsilon  ճշգրտության դեպքում կրճատ ձևով ունի այսպիսի տեսք՝
: \parallel x^{(k+1)}-x^{(k)}\parallel \le \varepsilon
Իտերացիոն պրոցեսի առավել ճշգրիտ պայմանը ունի այսպիսի տեսք՝
: \parallel Ax^{(k)}-b\parallel \le \varepsilon
և պահանջում է ավելի շատ հաշվարկներ։ Այն բավականին հարմար է կտրտված մատրիցների համար։

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

```cpp
#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 - ում

```python3
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
```


## Տես նաև
* Երկրաչափական պրոգրեսիա
* Պարզ իտերացիայի մեթոդ
* Յակոբիի մեթոդ
* Բանախի թեորեմ
* Իտերացիայի մեթոդ

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

## Արտաքին հղումներ
*https://www.maa.org/press/periodicals/loci/joma/iterative-methods-for-solving-iaxi-ibi-gauss-seidel-method 
*https://www3.nd.edu/~zxu2/acms40390F12/Lec-7.3.pdf
*http://mathworld.wolfram.com/Gauss-SeidelMethod.html

Կատեգորիա:Կառլ Գաուս
Կատեգորիա:Մաթեմատիկա
Կատեգորիա:Թվային մեթոդներ
Կատեգորիա:Գծային հանրահաշիվ
Կատեգորիա:Գիտություն