You are on page 1of 12

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

Національний університет «Львівська політехніка»


Інститут комп’ютерних наук та інформаційних технологій
Кафедра автоматизованих систем управління

Лабораторна робота №1
З дисципліни «Чисельні методи»
Тема:
«Розв’язування системи лінійних алгебраїчних рівнянь
методом Гауса. Схема Жордана»

Виконав: Москаленко О.О


Група: КН-203
Перевірив: Балич Б.І.

Львів 2019
Мета роботи: ● вивчити і засвоїти Методи Гауса і Жордана – Гауса
розв’язування СЛАР.
Короткі теоретичні відомості. Алгоритми
Метод Гауса
Ідея методу Гауса полягає в тому, щоб СЛАР за допомогою еквівалентних
перетворень звести до системи з трикутною матрицею, оскільки розв’язання
такої системи не вимагає жодних зусиль. Процес зведення системи до
трикутного вигляду називається прямим ходом. А відшукання розв’язку
зведеної системи – зворотним ходом. Прямий хід складається із (n-1)-го кроку,
на кожному з яких із частин рівнянь системи вилучається одне із невідомих.
На першому кроці вилучаємо х1 із усіх рівнянь, крім першого Щоб
вилучити х1 з і-го р-ня системи, треба перше рівняння помножити на коефіцієнт

і додати до і-го р-ня. Отримуємо систему

І т.д. Через n-1 кроків маємо систему, матриця якої є трикутною.

Тепер, виконуємо зворотний хід. З останнього р-ня отриманої системи


визначимо xn і т.д. Підставивши знайдені значення, визначимо x1.
Зазначимо, якщо у процесі виконання прямого ходу на якомусь кроці в
новій системі з’явилось р-ня, в якому всі коефіцієнти лівої частини = 0, а права
частина не = 0, то система є несумісною. Якщо ж і права частина дорівнює
нулеві, то таке р-ня можна вилучити.
Метод Жордана-Гауса
Модифікацією методу Гауса є метод Жордана-Гауса (схема Жордана), що
полягає в наступному: в матриці А вибираємо відмінний від нуля елемент ,
який називають її провідним елементом (l-тий стовпець – провідним стовпцем,
а k-тий рядок – провідним рядком). СЛАР (1) перетворюють так, щоб
коефіцієнти при невідомих і вільні члени визначалися за наступними
формулами:
' '
' ail ⋅ akj ' ail ⋅ b k ' ak j ' bk (4)
a =aij −
ij ;bi=b i− ; a il =0 , якщо i≠ k ,a k j= ;b = , якщо i=k .
a kl akl a k k k ak k

Тобто, коефіцієнти при в усіх рівняннях СЛАР, крім k-го,


дорівнюватимуть нулю. Подібно до цього перетворюють СЛАР на наступному
кроці, прийнявши за провідний елемент . Після цього перетворення всі
коефіцієнти при , крім дорівнюють нулю і т.д. Таким чином отримаємо СЛАР
у вигляді таблиці, з якої знаходимо значення всіх невідомих. Наприклад, для
СЛАР із трьох рівнянь матимемо:
1 0 0 d1 x 1=d1
0 1 0 d2 x 2=d 2
0 0 1 d3 ⇒ x 3=d 3 .

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


Метод Гауса та Метод Жордана-Гауса
#include "pch.h"
#include<iostream>
#include<vector>
#include <string>
using namespace std;

void printsym(int sz, char sm) {


while ((sz--) > 0) { printf("%c", sm); }
}

template<class type>
void format(type num) {
printf("%.2f", num); printsym(6 - to_string((int)num).length(), ' ');
}

vector<vector<double>> init2DVector(int x, int y) {


return *(new vector<vector<double>>(y, vector<double>(x, 0)));
}

template <class type>


void printVector(std::vector<type> arr, std::string separator) {
for (type el : arr) format(el), std::cout << separator;
}

template <class type>


void print2DVector(vector<vector<type>> matrix) {
cout << " ";
for (int i = 0; i < matrix[0].size(); i++)printf("| %d ", i);
std::cout << "|\n";
int k = 0;
for (vector<type> vec : matrix) printf("%d |", ++k), printVector(vec,"|"), std::cout << std::endl;
std::cout << std::endl;
}

template <class type>


void enterMatrixData(vector<vector<type>>& matrix) {
std::cout << std::endl;
for (int i = 0; i < matrix.size(); i++)
for (int k = 0; k < matrix[i].size(); k++) {
std::cout << "A[" << i + 1 << ", " << k + 1 << " ]=";
std::cin >> matrix[i][k];
}
}

template <class type>


void makeStairMatrix(vector<vector<type>>& matrix, bool printResult) {

int squareMatrixSize = matrix.size();


int rowSize = matrix[0].size();

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


for (int i = 0; i < squareMatrixSize; i++) {
if (i != j) {
type toDecrementCoef = matrix[i][j] / matrix[j][j];

for (int k = 0; k < rowSize; k++)


matrix[i][k] = matrix[i][k] - matrix[j][k] * toDecrementCoef;
if (printResult) print2DVector(matrix);
}
}
}

if (printResult)
std:cout << "THE RESULT OF FINDING THE DIAGONAL ELEMENTS IS:\n\n",
print2DVector(matrix);

template <class type>


type CalcToDecrement(vector<type> solutions, vector<vector<type>> matrix, int row) {

type toDecrement = 0;
for (int i = solutions.size() - 1; i >= 0 ; i--) {
if (i == row) continue;
toDecrement += solutions[i] * matrix[row][i];
}
return toDecrement;
}
template <class type>
vector<type>* calculateSolutionsForGauss(vector<vector<type>> matrix, bool printResult) {

int MatrixHeight = matrix.size();

std::vector<type> solutions = std::vector<type>(MatrixHeight, 0);

std::cout << "\nThe solutions are:\n";


for (int i = MatrixHeight - 1; i >= 0; i--) {
solutions[i] = (matrix[i][MatrixHeight] - CalcToDecrement(solutions, matrix, i)) / (matrix[i][i]);
std::cout << std::endl << "x" << i << "=" << solutions[i] << std::endl;
}

return &solutions;
}

template <class type>


vector<type>* calculateSolutions(vector<vector<type>> matrix, bool printResult) {

int size = matrix[0].size();

vector<type> solutions = vector<type>(size, 0);

cout << "\nThe solution is:\n";

for (int i = 0; i < size - 1; i++) {


solutions[i] = (double)matrix[i][size - 1] / (double)matrix[i][i];
std::cout << std::endl << "x" << i << "=" << solutions[i] << std::endl;
}

return &solutions;
}
template <class type>
void makeMatrixForGauss(vector<vector<type>>& matrix, bool printResult) {

int squareMatrixSize = matrix.size();


int rowSize = matrix[0].size();

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


for (int i = j + 1; i < squareMatrixSize; i++) {
if (i != j) {
type toDecrementCoef = matrix[i][j] / matrix[j][j];

for (int k = 0; k < rowSize; k++)


matrix[i][k] = matrix[i][k] - matrix[j][k] * toDecrementCoef;
if (printResult) print2DVector(matrix);
}
}
}

if (printResult)
std:cout << "THE RESULT OF FINDING THE DIAGONAL ELEMENTS IS:\n\n",
print2DVector(matrix);

void makeValidInput(int& toStore) {


do {
cin >> toStore;
} while (toStore != 1 && toStore != 2);
}

int main() {
int n;
printf("\nEnter the size of matrix: ");
cin >> n;
vector<vector<double>> matrix = init2DVector(n + 1, n);

//print2DVector(matrix);

printf("\nEnter the elements of augmented matrix (rowwise):\n");

enterMatrixData(matrix);

print2DVector(matrix);

cout << "How would you like to solve matrix?\n";


cout << "1 is Gauss, 2 is Gauss-Jordan\n";
makeValidInput(n);

if (n == 2) {

makeStairMatrix(matrix, true);

calculateSolutions(matrix, true);

}
else {

makeMatrixForGauss(matrix, true);

calculateSolutionsForGauss(matrix, true);

return 0;
}
Результат:
Метод Гауса
Метод Жордана-Гауса
Висновок
Під час виконання даної лабораторної роботи я вивчив та засвоїв
Методи Гауса і Жордана – Гауса розв’язування СЛАР. Усі
розрахунки я спочатку виконав вручну, а потім використавши
програмні коди записав туди свої дані. Порівнявши результати, можу
сказати, що розв’язки рівнянь я отримав однакові, як із програмного,
так і з розв’язку вручну. Проте, результати, що показали програми,
виявились більш точними.
Якщо брати до уваги лише два різних методи, то результати
СЛАР були отримані однаково точні.

You might also like