- •Министерство образования республики беларусь
- •Код программы
- •Результат работы программы
- •Лабораторная работа №2
- •Лабораторная работа №3
- •Лабораторная работа №4
- •Лабораторная работа №5
- •Лабораторная работа №6
- •Лабораторная работа №7
- •Лабораторная работа №8
- •Лабораторная работа №9
- •Лабораторная работа №10
Лабораторная работа №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";
}
Результат работы программы