Download as docx, pdf, or txt
Download as docx, pdf, or txt
You are on page 1of 21

Національний технічний університет України «КПІ ім.

Ігоря Сікорського»
Факультет інформатики та обчислювальної техніки
Кафедра інформаційних систем та технологій

Лабораторна робота № 4
з дисципліни «Спеціальні розділи математики-2.
Чисельні методи»

на тему

«Обчислення власних значень та власних векторів


матриць»

Виконав:
студент гр. ІС-21
Заскалета Богдан
Викладач:
доц. Рибачук Л.В.

Київ – 2023
Зміст

1 Постановка задачі
Створити програму, для зведення матриці А до нормальної форми
Фробеніуса Р.

Отримане характеристичне рівняння розв’язати довільним способом у


Mathcad і отримати всі власні числа λі, і = 1,…,m з точністю 5 знаків після
коми. Для кожного власного числа знайти по одному власному вектору через
власні вектори матриці Р.
Перевірити точність знайдених результатів, підставляючи у рівняння Ax = λx
знайдені власні числа та власні вектори.
Знайти власні числа матриці А виключно за допомогою Mathcad і порівняти з
отриманими раніше результатами.
2 Розв’язок
Зведення матриці А до нормальної форми Фробеніуса Р:
Розв’язання характеристичного рівняння у Mathcad:

Знаходження власних векторів:


Похибка:
3 Розв’язок у Mathcad
Перевірка власних значень за допомогою вбудованої функції Mathcad(власні
значення розташовані в іншому порядку):
Пошук власних векторів:

Порівняння результатів методом середньоквадратичної похибки:


4 Висновок
В цій лабораторній роботі було досліджено процес обчислення власних
значень та власних векторів матриць. Для цього був використаний метод
Данилевського зі зведенням матриці А до нормальної форми Фробеніуса Р.
Отримані результати виявились доволі точними, що показує корисність цього
метода при знаходженні власних значень та власних векторів матриць.
5 Лістинг програми
#include <iostream>
#include <cmath>
using namespace std;

const int m = 4;

void findMatrixM(double A[m][m], int iter);


void multOfMatrix(double invM[m][m], double A[m][m], double M[m][m]);
void Matrix_Vector(double S[m][m], double yVectors[m][m]);
void findMistake(double A[m][m]);

double M[m][m] = { };
double M2[m][m] = { };
double M1[m][m] = { };
double M0[m][m] = { };
double S[m][m] = { };
double invM[m][m] = { };
double intermA[m][m] = { };
double sol[m] = { 4.44214, 9.20913, 2.68065, 5.62808 };
double yVectors[m][m] = { };
double xVectors[m][m] = { };
double mistake[m][m] = { };

int main()
{
//Matrix A

double A[m][m] = {
{6.37, 1.26, 0.81, 1.225},
{1.26, 4.05, 1.30, 0.16},
{0.81, 1.30, 5.55, 2.10},
{1.225, 0.16, 2.10, 5.99}
};

double ACopy[m][m] = {
{6.37, 1.26, 0.81, 1.225},
{1.26, 4.05, 1.30, 0.16},
{0.81, 1.30, 5.55, 2.10},
{1.225, 0.16, 2.10, 5.99}
};

//Find P matrix

for (int i = (m - 2); i > -1; i--) {

findMatrixM(A, i);

cout << "Matrix M" << i << ":" << endl;


for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
cout << M[i][j] << " ";
}
cout << endl;
}

cout << "Matrix M" << i << "^(-1):" << endl;


for (int i = 0; i < m; i++) {
for (int j = 0; j < m; j++) {
cout << invM[i][j] << " ";
}
cout << endl;
}

multOfMatrix(invM, A, M);

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


for (int j = 0; j < m; j++) {
A[i][j] = intermA[i][j];
}
}
}

cout << "P matrix:" << endl;

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


for (int j = 0; j < m; j++) {
printf("%.5lf", A[i][j]);
cout << " ";
}
cout << endl;
}

//Find P vectors
for (int i = 0; i < m; i++) {

cout << i + 1 << " P vector:" << endl;

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


yVectors[i][j] = pow(sol[i], (3 - j));
printf("%.5lf", yVectors[i][j]);
cout << endl;
}
}

//Find A vectors

multOfMatrix(M2, M1, M0);


Matrix_Vector(intermA, yVectors);

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


cout << "X" << i + 1 << ":" << endl;
for (int j = 0; j < m; j++) {
printf("%.5lf", xVectors[i][j]);
cout << endl;
}
cout << endl;
}

//Find mistake

findMistake(ACopy);
cout << "Mistake:" << endl;

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


cout << "X" << i + 1 << " mistake:" << endl;
for (int j = 0; j < m; j++) {
printf("%.5lf", mistake[i][j]);
cout << endl;
}
}
}

void findMatrixM(double A[m][m], int iter) {

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


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

if (i == iter) {
if (i == j) {
M[i][j] = 1 / A[i + 1][j];
invM[i][j] = A[i + 1][j];
}
else {
M[i][j] = ((-1) * A[i + 1][j]) / A[i + 1][i];
invM[i][j] = A[i + 1][j];
}
}
else if (i == j) {
M[i][j] = 1;
invM[i][j] = 1;
}
else {
M[i][j] = 0;
invM[i][j] = 0;
}

switch (iter) {
case 0:
M0[i][j] = M[i][j];
break;
case 1:
M1[i][j] = M[i][j];
break;
case 2:
M2[i][j] = M[i][j];
break;
default:
break;
}
}
}
}

void multOfMatrix(double invM[m][m], double A[m][m], double M[m][m]) {

double intermMatrix[m][m] = { };

for (int k = 0; k < m; k++) {

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

double elem = 0;

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


elem += (invM[k][j] * A[j][i]);
}

intermMatrix[k][i] = elem;
}
}

for (int k = 0; k < m; k++) {

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

double elem = 0;
for (int j = 0; j < m; j++) {
elem += (intermMatrix[k][j] * M[j][i]);
}

intermA[k][i] = elem;
}
}
}

void Matrix_Vector(double S[m][m], double yVectors[m][m]) {


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

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

double elem = 0;

for (int k = 0; k < m; k++) {


elem += S[j][k] * yVectors[i][k];
}

xVectors[i][j] = elem;
}
}
}

void findMistake(double A[m][m]) {

for (int k = 0; k < m; k++) {

double intermAX[m] = {};


double intermLambdaX[m] = { };

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

double elem = 0;
for (int j = 0; j < m; j++) {
elem += A[i][j] * xVectors[k][j];
}

intermAX[i] = elem;
}

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


intermLambdaX[i] = xVectors[k][i] * sol[k];
}

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


mistake[k][i] = intermAX[i] - intermLambdaX[i];
}
}
}

You might also like