Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
otchet_VMA.doc
Скачиваний:
17
Добавлен:
25.03.2015
Размер:
1.32 Mб
Скачать

Лабораторная работа №3

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

Решить систему линейных алгебраических уравнений методом прогонки

Теоретические сведения

Рассмотрим систему трехточечных уравнений

(4.44)

и предположим, что коэффициенты иотличны от нуля. Матрица этой системы является трехдиагональной и имеет вид

Системы вида (4.44) возникают при трехточечной аппроксимации краевых задач для обыкновенных дифференциальных уравнений второго порядка с постоянными и переменными коэффициентами, а также при реализации разностных схем для уравнений в частных производных. Эффективным методом решения системы (4.44) является метод исключения Гаусса, который приводит к формулам прогонки.

Предположим, что исвязаны рекуррентным соотношением

(4.45)

с неопределенными коэффициентами и.

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

Получим . После приведения подобных имеем

. (4.46)

Подставим теперь (4.45) в (4.46) и преобразуем полученное равенство

,

.

Последнее уравнение справедливо для любых , если

,

.

Отсюда получаем рекуррентную формулу для

,, (4.47)

и рекуррентную формулу для определения

,. (4.48)

В обоих случаях предполагается, что .

Если коэффициенты иизвестны и известно значение, то, двигаясь отк, получим последовательно все. Определим начальные значения для коэффициентови. Для этого используем первое уравнение системы (4.44) и равенство (4.45) при. Имеем

,

.

Сравнивая эти уравнения, получим

,. (4.49)

Используем теперь для определения значения последнее уравнение системы (4.44) и равенство (4.45) при. В результате получим систему уравнений

,

решая которую находим

. (4.50)

Описанный метод решения систем линейных алгебраических уравнений с трехдиагональной матрицей называется методом правой прогонки. Коэффициенты иназываются прогоночными коэффициентами, формулы (4.47)-(4.49) описывают прямой ход метода прогонки, а формулы (4.45) и (4.50) – обратный ход. Для решения системы (4.44) необходимо выполнитьопераций умножения и деления.

Алгоритм метода правой прогонки будет корректен, если в формулах (4.47) и (4.48) отличны от нуля значения . Кроме того, если всепо модулю больше единицы, то может произойти сильное увеличение погрешности, и, еслидостаточно велико, то полученное реальное решение будет значительно отличаться от искомого решения.

Теорема4.5 (достаточное условие корректности и устойчивости метода прогонки). Пусть коэффициенты системы (4.1) удовлетворяют условиям,,

,,,,,

, (4.51)

,, (4.52)

причем хотя бы в одном из неравенств (4.51) или (4.52) выполняется строгое неравенство, т. е. Матрица системы (4.44) имеет диагональное преобладание. Тогда для метода прогонки имеют место неравенства ,,, гарантирующие корректность и устойчивость метода.

Код программы

Unit1.cpp:

//---------------------------------------------------------------------------

#include <vcl.h>

#pragma hdrstop

#include "Unit1.h"

#include<stdio.h>

#include<math.h>

//---------------------------------------------------------------------------

#pragma package(smart_init)

#pragma resource "*.dfm"

TForm1 *Form1;

//---------------------------------------------------------------------------

__fastcall TForm1::TForm1(TComponent* Owner)

: TForm(Owner)

{

}

//---------------------------------------------------------------------------

void __fastcall TForm1::UpDown1Click(TObject *Sender, TUDBtnType Button)

{

SG1->RowCount = StrToInt(Edit1->Text);

SG2->RowCount = StrToInt(Edit1->Text);

SG1->ColCount = StrToInt(Edit1->Text);

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button1Click(TObject *Sender)

{

TSG1->RowCount = StrToInt(Edit1->Text);

TSG2->RowCount = StrToInt(Edit1->Text);

int i,j;

int n = StrToInt(Edit1->Text);

float **S = new float*[n];

float *A = new float[n];

float *B = new float[n];

float *C = new float[n];

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

S[i] = new float[n];

}

for (int i = 0; i < n; i++)

for (int j = 0; j < n; j++)

if(SG1->Cells[i][j] != "")

S[i][j] = StrToFloat(SG1->Cells[j][i]);

else

S[i][j] = 0;

float *F = new float[n];

float *q = new float[n];

float *t = new float[n];

float *X = new float[n];

for (int i = 0; i < 1; i++)

for (int j = 0; j < n; j++)

if(SG1->Cells[i][j] != "")

F[j] = StrToFloat(SG2->Cells[i][j]);

else

F[j] = 0;

for (i=0;i<n;i++){

B[i]=S[i][i];

C[i]=S[i][i+1];

//A[i+1]=S[i+1][i];

}

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

A[i]=S[i][i-1];

C[n-1]=0;

A[0]=0;

q[0]=-C[0]/B[0];

t[0]=F[0]/B[0];

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

q[i]=-C[i]/(B[i]+A[i]*q[i-1]);

t[i]=(F[i]-A[i]*t[i-1])/(B[i]+A[i]*q[i-1]);

}

X[n-1]=t[n-1];

for (i=n-2;i>=0;i--)

X[i]=q[i]*X[i+1]+t[i];

float *pr = new float[n];

for(i=0;i<n;i++){

float s=0;

for(j=0;j<n;j++)

pr[i]+=S[i][j]*X[j];

}

for (int i = 0; i < 1; i++)

for (int j = 0; j < n; j++){

TSG1->Cells[i][j] = FloatToStr(X[j]);

}

for (int i = 0; i < 1; i++)

for (int j = 0; j < n; j++){

TSG2->Cells[i][j] = FloatToStr(pr[j]);

}

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button2Click(TObject *Sender)

{

int n = StrToInt(Edit1->Text);

for(int i = 0; i < n; i++)

for(int j = 0; j < n; j++)

SG1->Cells[i][j] = "";

for(int i = 0; i < 1; i++)

for(int j = 0; j < n; j++)

SG2->Cells[i][j] = "";

for(int i = 0; i < 1; i++)

for(int j = 0; j < n; j++)

TSG2->Cells[i][j] = "";

for(int i = 0; i < 1; i++)

for(int j = 0; j < n; j++)

TSG1->Cells[i][j] = "";

}

//---------------------------------------------------------------------------

void __fastcall TForm1::Button3Click(TObject *Sender)

{

SG1->Cells[0][0] = "1";

SG1->Cells[1][0] = "-1";

SG1->Cells[2][0] = "0";

SG1->Cells[3][0] = "0";

SG1->Cells[0][1] = "1";

SG1->Cells[1][1] = "-2";

SG1->Cells[2][1] = "1";

SG1->Cells[3][1] = "0";

SG1->Cells[0][2] = "0";

SG1->Cells[1][2] = "1";

SG1->Cells[2][2] = "-2";

SG1->Cells[3][2] = "1";

SG1->Cells[0][3] = "0";

SG1->Cells[1][3] = "0";

SG1->Cells[2][3] = "0";

SG1->Cells[3][3] = "1";

SG2->Cells[0][0] = "0";

SG2->Cells[0][1] = "0";

SG2->Cells[0][2] = "0";

SG2->Cells[0][3] = "1";

}

Результат работы программы

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