Метод Гаусса решения систем линейных алгебраических уравнений
Белорусский
государственный университет
Факультет
прикладной математики и информатики
Кафедра
вычислительной математики
Лабораторная
работа №1
Тема:
«Метод Гаусса решения систем линейных алгебраических уравнений»
Подготовил: студент 2
курса 2 группы
Зинькович И.А.
Преподаватель: Самусенко
А.В.
Минск
Теоретический материал
Пусть есть система:
Прямой ход состоит из n - 1 шагов исключения.
-й шаг. Целью этого шага является
исключение неизвестного x1 из уравнений с номерами i = 2, 3, …, n.
Предположим, что коэффициент a11 ¹ 0. Будем называть его главным элементом 1-го шага.
Найдем величины qi1 = ai1/a11
(i = 2, 3, …, n), называемые множителями 1-го шага. Вычтем последовательно из
второго, третьего, …, n-го уравнений системы первое уравнение, умноженное
соответственно на q21, q31, …, qn1. Это
позволит обратить в нуль коэффициенты при x1 во всех уравнениях,
кроме первого. В результате получим эквивалентную систему
11x1 + a12x2 + a13x3
+ … + a1nxn = b1,22(1)x2
+ a23(1)x3 + … + a2n(1)xn
= b2(1),32(1)x2 +
a33(1)x3 + … + a3n(1)xn
= b3(1),n2(1)x2 +
an3(1)x3 + … + ann(1)xn
= bn(1).
в которой aij(1)
и bij(1) вычисляются по формулам
ij(1) = aij −
qi1a1j, bi(1) = bi −
qi1b1.
2-й шаг. Целью этого шага является
ислючение неизвестного x2 из уравнений с номерами i = 3, 4, …, n.
Пусть a22(1) ≠ 0, где a22(1)
- коэффициент, называемый главным (или ведущим) элементом 2-го шага. Вычислим
множители 2-го шага
i2 = ai2(1) / a22(1) (i
= 3, 4, …, n)
11x1 + a12x2 + a13x3
+ … + a1nxn = b1 ,22(1)x2
+ a23(1)x3 + … + a2n(1)
xn = b2(1) ,33(2)x3
+ … + a3n(2)xn = b3(2) ,n3(2)x3
+ … + ann(2)xn = bn(2) .
Здесь коэффициенты aij(2)
и bij(2) вычисляются по формулам: aij(2)
= aij(1) - qi2a2j(1), bi(2)
= bi(1) - qi2b2(1).
Аналогично проводятся остальные
шаги. Опишем очередной k-й шаг.й шаг. В предположении, что главный (ведущий)
элемент k-го шага akk(k-1) отличен от нуля, вычислим
множители k-го шага qik = aik(k-1) / akk(k-1)
(i = k + 1, …, n) и вычтем последовательно из (k + 1)-го, …, n-го уравнений
полученной на предыдущем шаге системы k-e уравнение, умноженное соответственно
на qk+1,k, qk+2,k, …, qnk.
После (n - 1)-го шага исключения
получим систему уравнений
11x1 + a12x2 + a13x3
+ … + a1nxn = b1 ,22(1)x2
+ a23(1)x3 + … + a2n(1)xn
= b2(1) ,33(2)x3
+ … + a3n(2)xn = b3(2) ,nn(n-1)xn
= bn(n-1) .
матрица A(n-1) которой
является верхней треугольной. На этом вычисления прямого хода заканчиваются.
Обратный ход. Из последнего уравнения
системы находим xn. Подставляя найденное значение xn в предпоследнее
уравнение, получим xn-1. Осуществляя обратную подстановку, далее
последовательно находим xn-1, xn-2, …, x1.
Вычисления неизвестных здесь проводятся по формулам
n = bn(n-1) / ann(n-1),k
= (bn(k-1) - ak,k+1(k-1)xk+1
- … - akn(k-1)xn) / akk(k-1),
(k = n - 1, …, 1).
Необходимость выбора главных
элементов. Заметим, что вычисление множителей, а также обратная подстановка
требуют деления на главные элементы akk(k-1). Поэтому
если один из главных элементов оказывыется равным нулю, то схема единственного
деления не может быть реализована. Здравый смысл подсказывает, что и в
ситуации, когда все главные элементы отличны от нуля, но среди них есть близкие
к нулю, возможен неконтролируемый рост погрешности.
линейный алгебраический уравнение
гаусс
Условие задания
Решить методом Гаусса систему
линейных уравнений Ax = b, где A = D + C*k. Матрицы D, C, b взяты из №41, k =
0,2.
Код программы (main.cpp)
#include <fstream>
#include <cmath>namespace std;round(double
x) {(x < 0) ? ceil(x-0.5): floor(x+0.5);
}main(){SIZE;** A;** copy;* b;*
result;* delta;k = 0.2;in("in.txt");>> SIZE;= new
double*[SIZE];= new double*[SIZE];(int i = 0; i < SIZE; i++){[i] = new
double[SIZE];[i] = new double[SIZE];
}** D = new double*[SIZE];(int i =
0; i < SIZE; i++)[i] = new double[SIZE];(int i = 0; i < SIZE; i++)(int j
= 0; j < SIZE; j++)>> D[i][j];** C = new double*[SIZE];(int i = 0; i
< SIZE; i++)[i] = new double[SIZE];(int i = 0; i < SIZE; i++)(int j = 0;
j < SIZE; j++)>> C[i][j];(int i = 0; i < SIZE; i++)(int j = 0; j
< SIZE; j++){[i][j] = D[i][j] + C[i][j] * k;[i][j] = A[i][j];
}= new double[SIZE];= new
double[SIZE];= new double[SIZE];(int i = 0; i < SIZE; i++){>> b[i];[i]
= b[i];
}(int i = 0; i < SIZE; ++i) {(A[i][i]!=
0) {[i] /= A[i][i];(int j = SIZE - 1; j >= i; --j) {[i][j] /= A[i][i];
}
}(int j = i + 1; j < SIZE; ++j)
{(int k = i; k < SIZE; k++) {(i == k);[j][k] -= A[j][i] * A[i][k];
}[j] -= result[i] * A[j][i];[j][i] =
0;
}
}(int j = SIZE - 1; j >= 0;
j--){(int i = 0; i < j; i++){[i] -= A[i][j] * result[j];[i][j] = 0;
}
}out("out.txt");* f =
fopen("out.txt", "w");(int i = 0; i < SIZE; i++){[i] =
round(result[i] * 100000) / 100000;
}(int i = 0; i < SIZE; i++)(f,
"%.5lf\n", result[i]);(int i = 0; i < SIZE; i++) (int j = 0; j
< SIZE; j++) {sum = 0; (int k = 0; k < SIZE; k++) += copy[i][k] *
result[k];[i] = abs(b[i] - sum);
}(int i = 0; i < SIZE; i++)(f,
"\n%.10lf", delta[i]);(f);
}
В результате получили X:
.9169573287
.2508817999
.1237128647
.0277923094
.0872656987
.2322239583
Округляя до пяти знаков после
запятой:
.91696
.25088
.12371
.08727
.23222
При вычислении AX - B, где X -
округлённые данные, получим:
.0000061000
.0000061000
.0000057000
.0000022000
.0000035000
.0000031000