- •Министерство образования республики беларусь
- •Код программы
- •Результат работы программы
- •Лабораторная работа №2
- •Лабораторная работа №3
- •Лабораторная работа №4
- •Лабораторная работа №5
- •Лабораторная работа №6
- •Лабораторная работа №7
- •Лабораторная работа №8
- •Лабораторная работа №9
- •Лабораторная работа №10
Лабораторная работа №7
Постановка задачи
Решить систему линейных алгебраических уравнений методом ортогонализации

Теоретические сведения
Этот метод используется для решения систем с произвольной невырожденной матрицей, но по скорости уступает многим прямым методам примерно в 1,5-3 раза. Метод основан на построении вспомогательной системы векторов, связанных с матрицей исходной системы уравнений и ортогональные в некоторой метрике.
Рассмотрим систему (4.1) и запишем ее в виде
,
(4.19)
где
,
.
Обозначим
,
,
.
Тогда система (4.19) перепишется в виде

Решение системы уравнений с невырожденной
матрицей
сводится к нахождению такого вектора
,
который имеет последнюю координату,
равную единице, и ортогонален к линейно
независимым векторам
.
Ортогональность вектора
к векторам
влечет за собой ортогональность ко
всему подпространству
,
натянутому на них, и, следовательно, к
любому его базису. И наоборот,
ортогональность вектора
к некоторому базису подпространства
влечет ортогональность ко всем векторам
.
Поэтому для решения системы достаточно
построить ненулевой вектор
,
ортогональный к какому-нибудь базису
подпространства
.
Если
- последняя координата вектора
,
то
.
Добавим к системе векторов
линейно независимый с ними вектор
,
а затем будем последовательно строить
систему ортонормированных векторов
,
что для всех
векторы
являются базисом подпространства
,
натянутого на вектора
.
В этом случае вектор
и будет искомым вектором
.
Применим
правило Шмидта для построения
ортонормированного базиса пространства,
натянутого на заданные линейно независимые
векторы. Обозначим через
ортогональный базис подпространства
,
а через
- ортонормированный в евклидовой метрике
базис того же подпространства. Так как
векторы
нормированы, то их можно представить в
виде
,
.
(4.20)
На
первом шаге метода положим
,
.
Пусть для некоторого шага
уже построен ортогональный базис
и ортонормированный базис
подпространства
.
Вектор
будем искать как линейную комбинацию
векторов![]()
![]()
Условие
ортогональности вектора
к ортогональным векторам
или, что то же самое, к векторам
дает
.
Поэтому
.
(4.21)
Таким
образом, с помощью этого итерационного
процесса и соотношения (4.20) строится
ортонормированная система векторов
.
Векторы
являются базисом подпространства
.
Следовательно, решение исходной системы
имеет вид
,
,
где
и
- соответственно
-я
и
я
координаты
вектора
.
Метод
ортогонализации легко реализуется на
ЭВМ и для решения системы
уравнений требует
операций умножения и деления и
извлечений квадратного корня. Однако
удовлетворительные по точности результаты
этот метод дает не для всех матриц
.
Это связано с неустойчивостью рекуррентного
процесса (2.21), нарушающей ортогональность
векторов
.
Чтобы избежать этого недостатка
используется алгоритм Уилкинсона. В
соответствии с этим алгоритмом векторы
вычисляются из соотношения
,
где
,
.
При
метод ортогонализации принимает обычный
вид и может быть неустойчивым. Значительно
лучшие результаты дает
.
Обычно же для достижения хорошей точности
достаточно сделать две-три итерации.
Код программы
Unit1.cpp:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include "Unit1.h"
#include "math.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
int n;
//float pr=0,nor=0;
float sk_pr(float* q1, float* q2){
float pr=0;
for(int i=0;i<=n;i++)
pr+=q1[i]*q2[i];
return pr;
}
float norm(float* q){
float nor=0;
nor=sqrt(sk_pr(q,q));
return nor;
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
const float EPS=0.00000001;
float a[10][10],ac[10][10],f[10],u[10],u1[10],x[10],c[10];
n = StrToInt(Edit1->Text);
for(int i=0; i<=n-1; i++)
for(int j=0; j<=n-1; j++)
a[i][j] = StrToFloat(SG1->Cells[j][i]) ;
for(int i=0; i<=n-1; i++)
for(int j=0; j<=n-1; j++)
ac[i][j]=a[i][j];
for(int i=0; i<n; i++){
c[i]=0;
u[i]=0;
u1[i]=0;
}
//for(int i=0; i<1; i++)
for(int j=0; j<n; j++)
f[j] = StrToFloat(SG1->Cells[n][j]);
for(int i=0;i<=n;i++){
a[i][n]=-f[i];
a[n][i]=0;
}
a[n][n]=1;
float s;
float norm0=norm(*a);
for(int k=0;k<=n;k++)
a[0][k]=a[0][k]/norm0;
for(int k=0;k<=n-1;k++){
for(int i=0;i<=k;i++){
s=0;
for(int j=0;j<=n;j++)
s+=a[k+1][j]*a[i][j];
c[i]=-s;
}
for(int j=0;j<=n;j++){
s=0;
for(int i=0;i<=k;i++)
s+=c[i]*a[i][j];
u[j]=a[k+1][j]+s;
}
do{
for(int j=0;j<=k;j++)
c[j]=sk_pr(u,*(a+j));
for(int j=0;j<=n;j++){
s=0;
for(int i=0;i<=k;i++)
s+=c[i]*a[i][j];
u1[j]=u[j]-s;
}
s=0;
for(int i=0;i<=n;i++)
s+=pow(u1[i]-u[i],2);
for(int j=0;j<=n;j++)
u[j]=u1[j];
}
while(s>EPS);
for(int j=0;j<=n;j++){
norm0=norm(u);
a[k+1][j]=u[j]/norm0;
}
}
for(int j=0;j<=n;j++)
x[j]=a[n][j]/a[n][n];
for (int i = 0; i < 1; i++)
for (int j=0; j<=n;j++){
TSG1->Cells[i][j] = FloatToStr(x[j]);
}
float f1[50];
for(int i=0;i<=n-1; i++){
f1[i]=0;
for(int j=0;j<=n-1;j++)
f1[i]+=ac[i][j]*x[j];
}
for (int i = 0; i < 1; i++)
for (int j=0; j<=n;j++){
TSG2->Cells[i][j] = FloatToStr(f1[j]);
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::UpDown1Click(TObject *Sender, TUDBtnType Button)
{
SG1->RowCount = StrToInt(Edit1->Text);
//StringGrid1->RowCount = StrToInt(Edit1->Text);
SG1->ColCount = StrToInt(Edit1->Text)+1;
TSG1->RowCount = StrToInt(Edit1->Text);
TSG2->RowCount = StrToInt(Edit1->Text);
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button3Click(TObject *Sender)
{
SG1->Cells[0][0] = "3,6";
SG1->Cells[1][0] = "0,8";
SG1->Cells[2][0] = "-0,7";
SG1->Cells[0][1] = "0,8";
SG1->Cells[1][1] = "3,6";
SG1->Cells[2][1] = "0,9";
SG1->Cells[0][2] = "-0,7";
SG1->Cells[1][2] = "0,9";
SG1->Cells[2][2] = "3,3";
SG1->Cells[3][0] = "3,8";
SG1->Cells[3][1] = "0,4";
SG1->Cells[3][2] = "-1,76";
}
Результат работы программы

