- •Министерство образования республики беларусь
- •Код программы
- •Результат работы программы
- •Лабораторная работа №2
- •Лабораторная работа №3
- •Лабораторная работа №4
- •Лабораторная работа №5
- •Лабораторная работа №6
- •Лабораторная работа №7
- •Лабораторная работа №8
- •Лабораторная работа №9
- •Лабораторная работа №10
Лабораторная работа №10
Постановка задачи
а) Найти собственные числа и собственные векторы матрицыAметодом
непосредственного вычисления определителя (ε = 0.5 · 10-3).
б) Методом А. Н. Крылова найти характеристический полином матрицы
Работу выполнить на задачах лабораторной работы № 7
Теоретические сведения
а) метод непосредственного вычисления определителя
Собственным значением (или характеристическим числом) квадратной матрицы А называется такое число λ, что для некоторого ненулевого вектора х имеет место равенство
Ах= λ х. (5.0)
Любой ненулевой вектор х, удовлетворяющий этому равенству, называется собственным вектором матрицы А, соответствующим (или принадлежащим) собственному значению λ. Очевидно, что все собственные векторы матрицы определены с точностью до числового множителя.
Условием существования у однородной системы (5.0) ненулевого решения (для наглядности запишем эту систему в виде (А— λ Е)х = 0 является требование
|А- λ Е| =
Это уравнение обычно называют вековым (или характеристическим) уравнением матрицы А. Такие уравнения часто встречаются в приложениях. Левая часть векового уравнения
|А- λ Е| = (-1)n (λn – p1 λn-1- p2 λn-2 - …., - рп)
носит название характеристического полинома матрицы А. Старший коэффициент этого полинома равен (—1)п. Иногда вместо характеристического полинома рассматривают полином, отличающийся от характеристического множителем (-1)п. Этот полином
Р( λ ) = λn – p1 λn-1- p2 λn-2 - …., - рп
обычно называют собственным многочленом матрицы. Собственные значения матрицы являются корнями собственного многочлена. Совокупность всех собственных значений λ1, λг, .... , λп матрицы А, где каждое собственное значение выписано столько раз, какова его кратность как корня собственного многочлена, называется спектром этой матрицы. Собственными же векторами матрицы А являются нетривиальные решения однородной системы (5.0), в которой вместо λ подставлены собственные значения λi матрицы. В том случае, когда для данного собственного значения система (5.0) имеет несколько линейно независимых решений, этому собственному значению принадлежит несколько собственных векторов.
Задачу вычисления собственных значений и собственных векторов матрицы А можно разбить на три естественных этапа:
1) строение собственного многочлена Р( λ ) матрицы;
2) решение уравнения Р(λ)=0 и нахождение собственных значений λi (i=1, 2,... , п) матрицы;
3) отыскание нетривиальных решений однородных систем (А- λi Е)х = 0),(i=1,2.. ,n),
т. е. нахождение собственных векторов матрицы.
Каждый из трех отмеченных этапов решения проблемы собственных значений представляет собой достаточно сложную вычислительную задачу.
Таким образом, задача отыскания собственных значений и собственных векторов матрицы сводится к отысканию коэффициентов характеристического уравнения, определению его корней, и к отысканию нетривиальных решений системы Ах = Х, в которой вместо X рассматривают одно из найденных собственных значений.
б) Метод А. Н. Крылова
Пусть D(λ) ≡ det(λ E - A) = λn + p1 λn-1 + p2 λn-2 + …., + рп (5.1)
— характеристический полином (с точностью до знака) матрицы А. Согласно тождеству Гамильтона — Кели, матрица А обращает в нуль свой характеристический полином; поэтому
An + p1 An-1 +…+ pn E = 0. (5.2)
Возьмем теперь произвольный ненулевой вектор y (0) =
Умножая обе части равенства (5.2) справа на y(0) получим:
An y(0) + p1 An-1 y(0) +…+ pn y(0) = 0. (5.3)
Положим:
Ak y(0) = y(k) (k=1, 2, ..., п); (5.4)
тогда равенство (5.3) приобретает вид
y(n) + p1 y(n-1) +…+ pn y(0) = 0. (5.5)
или (5.5*)
где
y(k) =, (k=1, 2, ..., п).
Следовательно, векторное равенство (5.5*) эквивалентно системе уравнений
p1 yj (n-1) + p2 yj (n-2) + …., + рп yj(0) = - yj(n) (j = 1. 2. . . ., n), (5.6)
из которой можно определить неизвестные коэффициенты p1, p2,....., рп .
Так как на основании формулы (5.4)
y(k) =A y (k -1), где (k = 1, 2, . . ., п),
то координаты y1 (к) , y2 (к) , …, yn (к) вектораy(k) последовательно вычисляются по формулам
,,…,(5.7)
Таким образом, определение коэффициентов pj характеристического полинома (5.1) методом А. Н. Крылова сводится к решению линейной системы уравнений (5.6), коэффициенты которой вычисляются по формулам (5.7), причем координаты начального вектора
y (0) =
произвольны. Если система (6) имеет единственное решение, то ее корни р1, р2, ..., рп являются коэффициентами характеристического полинома (5.1). Это решение может быть найдено, например, методом Гаусса. Если система (5.6) не имеет единственного решения, то задача усложняется . В этом случае рекомендуется изменить начальный вектор.
Код программы
а) метод непосредственного вычисления определителя
Unit1.cpp:
//---------------------------------------------------------------------------
#include <vcl.h>
#pragma hdrstop
#include<math.h>
#include<iostream>
#define M_PI (3.141592653589793)
#define M_2PI (2.*M_PI)
#include "Unit1.h"
#include "math.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
float F(float x, float b,float c,float d){
return x*x*x-b*x*x-c*x+d;
}
float F1(float x, float b,float c){
return 3*x*x-2*b*x-c;
}
float F2(float x, float b)
{
return 6*x-2*b;
}
float *F3(float x, float A[10][10],float b[5])
{
int i,j,n = 3;
float s[50][50];
for ( i = 1; i <= n; i++)
for ( j = 1; j <= n; j++) {
if (i != j)
s[i][j] = A[i][j];
else
s[i][i] = A[i][i] - x;
}
b[1] = 1;
b[3] = (s[3][2]*s[1][1] - s[3][1]*s[1][2])/(s[3][3]*s[1][2] - s[3][2]*s[1][3]);
b[2] = -((s[1][1] + b[3]*s[1][3])/s[1][2]);
return b;
}
int Cubic(double *x,double a,double b,double c) {
double q,r,r2,q3;
q = (a*a-3*b)/9; r=(a*(2*a*a-9*b)+27*c)/54;
r2 = r*r; q3 = q*q*q;
if(r2 < q3) {
double t = acos(r/sqrt(q3));
a /= 3; q =- 2*sqrt(q);
x[0] = q*cos(t/3)-a;
x[1] = q*cos((t + M_2PI)/3) - a;
x[2] = q*cos((t - M_2PI)/3) - a;
return(3);
}
else {
double aa,bb;
if(r <= 0) r = -r;
aa = -pow(r + sqrt(r2 - q3),1/3);
if(aa != 0) bb = q/aa;
else bb = 0;
a /= 3; q = aa + bb; r = aa - bb;
x[0] = q - a;
x[1] = (-0.5)*q - a;
x[2] = (sqrt(3.)*0.5)*fabs(r);
if (x[2] == 0) return(2);
return(1);
}
}
//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int i,j,n;
float A[10][10], y, *m, q[5],z,k,l,w = 8,t,k1,l1,e;
n = StrToInt(Edit1->Text);
for (i = 1; i <= n; i++)
for(j = 1; j <= n; j++)
A[i][j] = StrToFloat(SG1->Cells[j-1][i-1]) ;
double b = 0 , c = 0 ,d = 0 ;
for (i = 1; i <= n; i++)
b += A[i][i];
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++) {
if (i < j)
c += A[i][j]*A[j][i];
if (i > j)
c -= A[i][i]*A[j][j];
}
d += A[1][1]*(A[2][2]*A[3][3] - A[2][3]*A[3][2]);
d -= A[1][2]*(A[2][1]*A[3][3] - A[2][3]*A[3][1]);
d += A[1][3]*(A[2][1]*A[3][2] - A[2][2]*A[3][1]);
Label5->Caption = "-x^3 + (" + FloatToStr(ceil(b*100)/100.0) + ")*x^2 + (" + FloatToStr(ceil(c*100)/100.0) + ")*x + (" + FloatToStr(ceil(d*100)/100.0) + ") = 0";
Label5->Visible = True;
Label6->Visible = True;
double x[5];
Cubic(x, -b, -c, -d);
for (i = 0; i < n; i++)
TSG1->Cells[0][i] = FloatToStr(x[i]);
for (int k = 0; k < n; k++) {
for (i = 1; i <= n; i++)
q[i] = 1;
F3(x[k],A,q);
TSG2->Cells[k][0] = IntToStr(k + 1) + "-é";
for (i = 1; i <= n; i++)
TSG2->Cells[k][i] = q[i];
}
}
//---------------------------------------------------------------------------
void __fastcall TForm1::UpDown1Click(TObject *Sender, TUDBtnType Button)
{
SG1->RowCount = StrToInt(Edit1->Text);
SG1->ColCount = StrToInt(Edit1->Text);
TSG1->RowCount = StrToInt(Edit1->Text);
TSG2->RowCount = StrToInt(Edit1->Text)+1;
TSG2->ColCount = 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";
}
//---------------------------------------------------------------------------
б) Метод А. Н. Крылова
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)
{
}
//---------------------------------------------------------------------------
void Umn(float **a,float *b,int n,float *buf){
for (int i = 1; i <= n; i++) {
buf[i]=0;
for (int j = 1 ; j <= n; j++)
buf[i] += ( a[i][j]*b[j]);
}
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
int n,i,j;
float **a,*b,**y,*buf,*x;
n = StrToInt(Edit1->Text);
a = new float*[n+1];
for (i = 0; i <= n; i++)
a[i] = new float[n+1];
y = new float*[n+1];
for (i = 0; i <= n; i++)
y[i] = new float[n+1];
for (i = 1; i <= n; i++)
for (j = 1; j <= n; j++)
a[i][j] = StrToFloat(SG1->Cells[j-1][i-1]);
b = new float[n+1];
buf = new float[n+1];
x = new float[n+1];
y[1][n]=1;
for (i = 2; i <= n; i++)
y[i][n]=0;
for (i = n - 1; i >= 0; i--){
for (j = 1; j <= n; j++)
b[j] = y[j][i+1];
Umn(a,b,n,buf);
for (j = 1; j <= n; j++)
y[j][i] = buf[j];
}
for (i = 1; i <= n; i++)
b[i] = -buf[i];
float del;
for (i = 1 ; i <= n; i++) {
if (i > 1) {
for (int i1 = i; i1 <= n; i1++){
del = y[i1][i-1];
for (int j1 = i-1;j1 <= n; j1++){
y[i1][j1] -= (y[i-1][j1]*del);
}
b[i1] -= (b[i-1]*del);
}
}
del = y[i][i];
for (int j = 1;j <= n; j++)
y[i][j] /= del;
b[i] /= del;
}
x[n] = b[n];
float sum;
for (i = n - 1; i > 0; i--) {
sum = 0;
for (int j = i + 1; j <= n; j++)
sum = sum + y[i][j]*x[j];
x[i] = b[i] - sum;
}
Label3->Caption = "x^3 + (" + FloatToStr(ceil(x[1]*100)/100.0) + ")*x^2 + (" + FloatToStr(ceil(x[2]*100)/100.0) + ")*x + (" + FloatToStr(ceil(x[3]*100)/100.0) + ") = 0";
Label2->Caption = "Характеристический многочлен Крылова:";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::UpDown1Click(TObject *Sender, TUDBtnType Button)
{
SG1->RowCount = StrToInt(Edit1->Text);
SG1->ColCount = StrToInt(Edit1->Text);
}
//---------------------------------------------------------------------------
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] = "";
Label3->Caption = "";
Label2->Caption = "";
}
//---------------------------------------------------------------------------
void __fastcall TForm1::Button4Click(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";
}
Результат работы программы
а) метод непосредственного вычисления определителя
б) Метод А. Н. Крылова