Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
курсовая.docx
Скачиваний:
71
Добавлен:
01.04.2015
Размер:
292.61 Кб
Скачать
  1. Метод Якоби

Постановка задачи

Возьмём систему линейных уравнений:

, где

Или

Описание метода

Для того, чтобы построить итеративную процедуру метода Якоби, необходимо провести предварительное преобразование системы уравнений к итерационному виду. Оно может быть осуществлено по одному из следующих правил:

где в принятых обозначениях D означает матрицу, у которой на главной диагонали стоят соответствующие элементы матрицы A, а все остальные нули; тогда как матрицы U и L содержат верхнюю и нижнюю треугольные части A, на главной диагонали которых нули, Eединичная матрица.

Тогда процедура нахождения решения имеет вид:

где k счётчик итерации.

В отличие от метода Гаусса-Зейделямы не можем заменятьнав процессе итерационной процедуры, т.к. эти значения понадобятся для остальных вычислений. Это наиболее значимое различие между методом Якоби и методом Гаусса-Зейделя решенияСЛАУ. Таким образом на каждой итерации придётся хранить оба вектора приближений: старый и новый.

Условие сходимости

Приведем достаточное условие сходимости метода.

Теорема. Пусть. Тогда при любом выборе начального приближения:

  1. метод сходится;

  2. скорость сходимости метода равна скорости сходимости геометрической прогрессиисо знаменателем;

  3. верна оценка погрешности: .

Условие остановки

Условие окончания итерационного процесса при достижении точности ε в упрощённой форме имеет вид:

(Существует более точное условие окончания итерационного процесса, которое более сложно и требует дополнительных вычислений)

Алгоритм

Ниже приведён алгоритм реализации на C++

#include <math.h>

const double eps = 0.001; ///< желаемая точность

/// N - размерность матрицы; A[N][N] - матрица коэффициентов, F[N] - столбец свободных членов,

/// X[N] - начальное приближение, ответ записывается также в X[N];

void Jacobi (int N, double **A, double *F, double *X)

{

double * TempX = new double[N];

double norm; // норма, определяемая как наибольшая разность компонент столбца иксов соседних итераций.

do {

for (int i = 0; i < N; i++) {

TempX[i] =- F[i];

for (int g = 0; g < N; g++) {

if (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);

delete[] TempX;

}

    1. Решение на однопроцессорных компьютерах

#include <fstream>

#include <math.h>

#include <iostream>

using namespace std;

void main()

{ double x[100], x0[100], b[100], a[100][100],

s, d, eps=1e-8, max, k;

int n, i, j ;

freopen("input.txt","r",stdin);

cin>>n;

for (i=1;i<=n;i++)

{

for (j=1;j<=n;j++) cin>>a[i][j];

cin>>b[i];

}

for (i=1;i<=n;i++)

{

for (j=1;j<=n;j++) cout<<a[i][j]<<" ";

cout<<b[i]<<endl;

}

k=0;

for (i=1;i<=n;i++) x[i]=0; // Начальное приближение

do

{ k++;

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

max=0;

for (i=1;i<=n;i++)

{ s=0;

for (j=1;j<=n;j++) if (i!=j) s=s+a[i][j]*x0[j];

x[i]=(b[i]-s)/a[i][i];

d=fabs(x[i]-x0[i]); if (max<d) max=d;

}

} while (max>eps);

for (i=1;i<=n;i++) cout<<"x"<<i<<"="<<x[i]<<endl;

cout<<endl<<"k="<<k<<endl;

cout<<"d="<<d<<endl;

}

???

#include <fstream>

#include <math.h>

#include <iomanip>

#include <iostream>

#include <stdio.h>

using namespace std;

void main()

{ double x[100], x0[100], b[100], a[100][100],

s, d, eps=1e-8, max, k, h, pi=3.1415926;

int n, i, j ;

// freopen("input.txt","r",stdin);

freopen("output.txt","w",stdout);

n=50;

h=1.0/n;

memset(a,0,sizeof(a));

for (i=1;i<=n-1;i++)

{

if (i>1) a[i][i-1]=1;

a[i][i]=-2;

if(i<n-1) a[i][i+1]=1;

b[i]=-4*pi*pi*h*h*sin(2*pi*i*h);

}

k=0;

for (i=1;i<=n-1;i++) x[i]=0; // Начальное приближение

do

{ k++;

for (i=1;i<=n-1;i++) x0[i]=x[i];

max=0;

for (i=1;i<=n-1;i++)

{ s=0;

for (j=1;j<=n;j++) if (i!=j) s=s+a[i][j]*x0[j];

x[i]=(b[i]-s)/a[i][i];

d=fabs(x[i]-x0[i]); if (max<d) max=d;

}

} while (max>eps);

for (i=1;i<=n-1;i++) printf("%6.2lf",x[i]);

cout<<endl;

for (i=1;i<=n-1;i++) printf("%6.2lf",sin(2*pi*i*h));

cout<<endl<<"k="<<k<<endl;

cout<<"d="<<d<<endl;

}

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]