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