You are on page 1of 10

Міністерство освіти й науки України

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


Кафедра автоматизації проектування енергетичних процесів і систем

Лабораторна робота №5
Обчислення власних значень та власних векторів матриць
Варіант № 16

Виконав:
студент 2-го курсу
ТЕФ групи ТМ-81
Онищенко Н.Р.
Перевірила:
Залевська О.В.

Київ – 2020
Завдання
1.Допрограмовий етап: визначити кількість дійсних коренів рівняння,
відокремити корені рівняння (письмово) (див. теореми про верхню та нижню
границі, Гюа, метод поліномів Штурма). Результатом є висновок: перший
корінь належить проміжку […], другий корінь належить проміжку […] і т.д.
2.Програмний етап: уточнити корені рівняння:
2.1.Методом бісекції. 2.2.Методом хорд.
2.3.Методом Ньютона (дотичних).

Критерієм закінчення мають бути нерівності


для методу бісекції (інтервальний метод; a та b - кінці інтервалу)
| b - a | < ɛ та | f(xk) | < ɛ
для методiв хорд та дотичних
| xk - xk-1 | < ɛ та | f(xk) | < ɛ
3. Порівняти отримані результати, зробити висновки, який метод приводить
до меншої кількості ітерацій і чим це зумовлено.

Вихідне рівняння:
f(x) = 2𝑥 3 − 4𝑥 2 − 𝑥 + 1 = 0
Виконання допрограмового етапу:
Розв'язок методом бісекції:
\

Розв'язок методом хорд:


Розв'язок методом Ньютона:
Код програми:
#include <iostream>
#include <iomanip>
#include <cmath>
#include <fstream>

using namespace std;

void show(int* a, int n) {


cout << endl;
for (int i = 0; i < n; i++) {
cout << " " << a[i];
}
cout << endl;
}

void filling(int*& a, int A, int K, int &n, double* start, double* end, int &amount) {
fstream file("coef.txt");
for (int i = 0; i < n; i++) {
file >> a[i];
}
file.close();
a[0] *= 1 + A;
a[n - 1] *= K;
file.open("intrval.txt");
file >> amount;
for (int i = 0; i < amount; i++) {
file >> start[i];
file >> end[i];
}
file.close();

class Method {
public:

double eps = pow(10, -6);

void iter(double k, double a, double b) {


cout << endl << "[" << k << "] => " << "[" << a << "; " << b << "]";
}

double func(int* a, int n, double x) {


double f = 0;
for (int i = 0; i < n; i++) {
f += a[i] * pow(x, n - i - 1);
}
return f;
}

void method_b(int* a, double s, double e, int n) {

double c; // c = (s + e) / 2;
int k = 0;
if (fabs(s) < fabs(e)) {
double temp = s;
s = e;
e = temp;
}
do {
//iter(k, s, e);
c = (s + e) / 2.;
double f = func(a, n, s);
double fc = func(a, n, c + eps);
if (f * fc < 0) {
e = c;
}
else {
s = c;
}
k++;

} while (fabs(e - s) >= eps && fabs(func(a, n, c)) >= eps);


//iter(k, s, e);
cout << endl << "X[" << k << "]: " << c;
cout << endl << "F = " << func(a, n, c);
cout << endl;
}
void method_h(int* a, double s, double e, int n) {
int k = 0;
double c;
do {
//iter(k, s, e);
double fa = func(a, n, s);
double fb = func(a, n, e);
c = s - fa / (fb - fa) * (e - s);
double fc = func(a, n, c);
if (fa * fc < 0) {
e = c;
}
else {
s = c;
}
k++;
} while (fabs(e - s) >= eps && fabs(func(a, n, c)) >= eps);
//iter(k, s, e);
cout << endl << "X[" << k << "]: " << c;
cout << endl << "F = " << func(a, n, c);
cout << endl;
}

double funcP(int* a, int n, double x) {


double f = 0;
for (int i = 0; i < n; i++) {
f += a[i] * pow(x, n - i - 1);
}
return f;
}

void method_n(int* a, double s, double e, int n) {


int k = 0;
double c;
int* ap = new int[n - 1];
for (int i = 0; i < n - 1; i++) {
ap[i] = a[i] * (n - 1 - i);
}
double det = 0;
do {
c = e - func(a, n, e) / funcP(ap, n - 1, e);
k++;
det = fabs(e - c);
if (det >= eps) {
e = c;
}
} while (det >= eps);
//iter(k, s, e);
cout << endl << "X[" << k << "]: " << c;
cout << endl << "F = " << func(a, n, c);
cout << endl;
}
};

void task(int a, int k) {


Method own;
int n = 6;
int amount;
int* A = new int[n];
double *start = new double[3];
double *end = new double [3];
filling(A, a, k, n, start, end, amount);
show(A, n);
cout << endl << "\\Bisection/";
for (int i = 0; i < amount; i++) {
own.method_b(A, start[i], end[i], n);
}
cout << endl << "\\Hords/";
for (int i = 0; i < amount; i++) {
own.method_h(A, start[i], end[i], n);
}
cout << endl << "\\Nuthon/";
for (int i = 0; i < amount; i++) {
own.method_n(A, start[i], end[i], n);
}
}

int main() {
int k = 81 - 81 / 10 * 10;
long int a = 81264 / 10000;
task(a, k);
cout << endl;
return EXIT_SUCCESS;
}
Діапазони координат точок:

Заданий поліном:
Результат програми:

Висновок: я визначив кількість дійсних коренів рівняння, відокремив корені


рівняння, порівняв методи і дійшов до такого висновку, що
1)метод бісекції ефективний для знаходження більш точного розв’язку
рівняння, але це потребує більшої кількості ітерацій, ніж інші методи
2)метод хорд значно швидший ніж перший, але існують
проміжки(відрізки),на яких цей ітеративний метод для конкретної функції
потребує значно більшу кількість ітерацій для проведення обчислень з
заданою точністю
3)метод Ньютона дозволяє за малу кількість ітерацій провести обчислення та
отримати результат порівняно з попередніми методами. Більш того він
здатний самостійно підвищувати точність підрахунку: швидкість наближення
до кореня рівняння часом дозволяє знаходити результат з точністю більшою
ніж задана. Недолік цього методу полягає в збільшені кількості потрібних
ітерацій зі збільшенням степеням полінома від чого інші методи не залежать

You might also like