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