Метод Гаусса решения систем линейных алгебраических уравнений

Системы линейных алгебраических уравнений. Код программы для решения систем линейных алгебраических уравнений. Математические и алгоритмические основы решения задачи методом Гаусса. Программная реализация решения. Алгоритмы запоминания коэффициентов.

Рубрика Программирование, компьютеры и кибернетика
Вид лабораторная работа
Язык русский
Дата добавления 23.09.2014
Размер файла 23,5 K

Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже

Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.

Размещено на http://www.allbest.ru

Размещено на http://www.allbest.ru

Белорусский государственный университет

Факультет прикладной математики и информатики

Кафедра вычислительной математики

Лабораторная работа №1

Тема: «Метод Гаусса решения систем линейных алгебраических уравнений»

Подготовил: студент 2 курса 2 группы

Зинькович И.А.

Преподаватель: Самусенко А.В.

Минск

2014

Теоретический материал

Пусть есть система:

Прямой ход состоит из n 1 шагов исключения.

1-й шаг. Целью этого шага является исключение неизвестного x1 из уравнений с номерами i = 2, 3, …, n. Предположим, что коэффициент a11 0. Будем называть его главным элементом 1-го шага.

Найдем величины qi1 = ai1/a11 (i = 2, 3, …, n), называемые множителями 1-го шага. Вычтем последовательно из второго, третьего, …, n-го уравнений системы первое уравнение, умноженное соответственно на q21, q31, …, qn1. Это позволит обратить в нуль коэффициенты при x1 во всех уравнениях, кроме первого. В результате получим эквивалентную систему

a11x1 + a12x2 + a13x3 + … + a1nxn = b1,

a22(1)x2 + a23(1)x3 + … + a2n(1)xn = b2(1),

a32(1)x2 + a33(1)x3 + … + a3n(1)xn = b3(1),

an2(1)x2 + an3(1)x3 + … + ann(1)xn = bn(1).

в которой aij(1) и bij(1) вычисляются по формулам

aij(1) = aij ? qi1a1j, bi(1) = bi ? qi1b1.

2-й шаг. Целью этого шага является ислючение неизвестного x2 из уравнений с номерами i = 3, 4, …, n. Пусть a22(1) ? 0, где a22(1) - коэффициент, называемый главным (или ведущим) элементом 2-го шага. Вычислим множители 2-го шага

qi2 = ai2(1) / a22(1) (i = 3, 4, …, n)

и вычтем последовательно из третьего, четвертого, …, n-го уравнения системы второе уравнение, умноженное соответственно на q32, q42, …, qm2. В результате получим систему

a11x1 + a12x2 + a13x3 + … + a1nxn = b1 ,

a22(1)x2 + a23(1)x3 + … + a2n(1) xn = b2(1) ,

a33(2)x3 + … + a3n(2)xn = b3(2) ,

an3(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-й шаг. В предположении, что главный (ведущий) элемент 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)-го шага исключения получим систему уравнений

a11x1 + a12x2 + a13x3 + … + a1nxn = b1 ,

a22(1)x2 + a23(1)x3 + … + a2n(1)xn = b2(1) ,

a33(2)x3 + … + a3n(2)xn = b3(2) ,

ann(n-1)xn = bn(n-1) .

матрица A(n-1) которой является верхней треугольной. На этом вычисления прямого хода заканчиваются.

Обратный ход. Из последнего уравнения системы находим xn. Подставляя найденное значение xn в предпоследнее уравнение, получим xn-1. Осуществляя обратную подстановку, далее последовательно находим xn-1, xn-2, …, x1. Вычисления неизвестных здесь проводятся по формулам

xn = bn(n-1) / ann(n-1),

xk = (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>

using namespace std;

double round(double x) {

return (x < 0) ? ceil(x-0.5): floor(x+0.5);

}

int main(){

int SIZE;

double** A;

double** copy;

double* b;

double* result;

double* delta;

double k = 0.2;

ifstream in("in.txt");

in >> SIZE;

A = new double*[SIZE];

copy = new double*[SIZE];

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

A[i] = new double[SIZE];

copy[i] = new double[SIZE];

}

double** D = new double*[SIZE];

for (int i = 0; i < SIZE; i++)

D[i] = new double[SIZE];

for (int i = 0; i < SIZE; i++)

for (int j = 0; j < SIZE; j++)

in >> D[i][j];

double** C = new double*[SIZE];

for (int i = 0; i < SIZE; i++)

C[i] = new double[SIZE];

for (int i = 0; i < SIZE; i++)

for (int j = 0; j < SIZE; j++)

in >> C[i][j];

for (int i = 0; i < SIZE; i++)

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

A[i][j] = D[i][j] + C[i][j] * k;

copy[i][j] = A[i][j];

}

b = new double[SIZE];

result = new double[SIZE];

delta = new double[SIZE];

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

in >> b[i];

result[i] = b[i];

}

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

if (A[i][i]!= 0) {

result[i] /= A[i][i];

for (int j = SIZE - 1; j >= i; --j) {

A[i][j] /= A[i][i];

}

}

else {

return 0;

}

for (int j = i + 1; j < SIZE; ++j) {

for (int k = i; k < SIZE; k++) {

if (i == k)

continue;

A[j][k] -= A[j][i] * A[i][k];

}

result[j] -= result[i] * A[j][i];

A[j][i] = 0;

}

}

for (int j = SIZE - 1; j >= 0; j--){

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

result[i] -= A[i][j] * result[j];

A[i][j] = 0;

}

}

ofstream out("out.txt");

FILE* f = fopen("out.txt", "w");

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

result[i] = round(result[i] * 100000) / 100000;

}

for (int i = 0; i < SIZE; i++)

fprintf(f, "%.5lf\n", result[i]);

for (int i = 0; i < SIZE; i++)

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

double sum = 0;

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

sum += copy[i][k] * result[k];

delta[i] = abs(b[i] - sum);

}

for (int i = 0; i < SIZE; i++)

fprintf(f, "\n%.10lf", delta[i]);

fclose(f);

}

В результате получили X:

0.9169573287

0.2508817999

-1.1237128647

0.0277923094

1.0872656987

-0.2322239583

Округляя до пяти знаков после запятой:

0.91696

0.25088

-1.12371

0.02779

1.08727

-0.23222

При вычислении AX - B, где X - округлённые данные, получим:

0.0000061000

0.0000061000

0.0000057000

0.0000022000

0.0000035000

0.0000031000

Размещено на Allbest.ru


Подобные документы

Работы в архивах красиво оформлены согласно требованиям ВУЗов и содержат рисунки, диаграммы, формулы и т.д.
PPT, PPTX и PDF-файлы представлены только в архивах.
Рекомендуем скачать работу.