Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
6
Добавлен:
18.08.2022
Размер:
6.41 Кб
Скачать
#include <iostream>
#include <cmath>
#include <vector>
#include <iomanip>

using namespace std;

vector <vector <float>> CreateMatr_3_diagonal(vector <float> a, vector <float> b, vector <float> c, int m) {
	vector <vector <float>> res(m);
	int k = -1;
	for (int i = 0; i < m; i++, k++) {

		for (int j = 0; j < k; j++)
			res[i].push_back(0);

		if (k > -1)
			res[i].push_back(a[i]);

		res[i].push_back(b[i]);

		if (k < m - 2)
			res[i].push_back(c[i]);

		while (res[i].size() < m)
			res[i].push_back(0);
	}
	return res;
}

void print(pair <vector <vector <float>>, vector <float>> para) { // Вывод матрицы со столбцом
	vector <vector <float>> result = para.first;
	vector <float> b = para.second;

	for (int i = 0; i < result.size(); i++, cout << endl) {
		for (int j = 0; j < result[i].size(); j++) {
			cout << setw(7) << result[i][j];
		}
		cout << setw(7) << "| " << b[i];
	}
	cout << endl;
}

void print2(vector <vector <float>> result) { // Вывод матрицы без столбца
	for (int i = 0; i < result.size(); i++, cout << endl) {
		for (int j = 0; j < result[i].size(); j++) {
			cout << setw(7) << result[i][j];
		}
	}
	cout << endl;
}

pair <vector <vector <float>>, vector <float>> iter_str (pair <vector <vector <float>>, vector <float>> para, int m, int i, int j) { // Функция замены i и j строк матрицы
	vector <vector <float>> mas = para.first;
	vector <float> b = para.second;
	vector <vector <float>> mas1 = mas;
	vector <float> b1 = b;

	for (int k = 0; k < m; k++) {
		if (k == i) {
			mas[k] = mas1[j];
			b[k] = b1[j];
		}
		else if (k == j) {
			mas[k] = mas1[i];
			b[k] = b1[i];
		}
		else {
			mas[k] = mas1[k];
			b[k] = b1[k];
		}
	}
	pair <vector <vector <float>>, vector <float>> para1(mas, b);
	return para1;
}

pair <vector <vector <float>>, vector <float>> Gauss(vector <vector <float>> mas, vector <float> b, int m, vector <float> res) {

	vector <vector <float>> mas1 = mas; // Копия для замены строк

	for (int k = 0; k < m; k++) {

		if (mas1[k][k] == 0) { // Если знаменатель равен нулю
			float max = 0;
			int max_str = k;

			for (int x = k; x < m; x++) { // Поиск в столбце максимального по модулю значения
				if (abs(mas1[x][k]) > 0) {
					max_str = x;
					max = abs(mas1[x][k]);
				}
			}
			if (max > 0) {
				pair <vector <vector <float>>, vector <float>> para(mas1, b);
				mas1 = iter_str(para, m, k, max_str).first;
				b = iter_str(para, m, k, max_str).second;
				mas = mas1;
			}
		}

		for (int j = k; j < m; j++) {
			mas[k][j] /= mas1[k][k];
		}

		b[k] /= mas1[k][k];

		for (int i = k + 1; i < m; i++) {
			for (int j = k; j < m; j++) {
				mas[i][j] -= mas1[i][k] * mas[k][j];
			}
			b[i] -= mas1[i][k] * b[k];
		}
		mas1 = mas;
	}
	pair <vector <vector <float>>, vector <float>> para(mas, b);
	return para;
}

vector <float> inverse_vector(vector <float> mas, int m) { // Reverse
	vector <float> res;
	for (int i = m - 1; i >= 0; i--) {
		res.push_back(mas[i]);
	}
	return res;
}

vector <float> progonka(vector <float> a, vector <float> b, vector <float> c, vector <float> d) { // Прямая прогонка
	vector <float> x; //результат
	float P = - c[0] / b[0], Q = d[0] / b[0];
	pair<float, float> para(P, Q);
	vector <pair<float, float>> res;

	res.push_back(para);
	for (int i = 1; i < a.size(); i++) {
		Q = (a[i] * Q - d[i]) / (-b[i] - a[i] * P);
		P = c[i] / (-b[i] - a[i] * P);
		pair<float, float> para1(P, Q);
		res.push_back(para1);
	}

	x.push_back(res[res.size() - 1].second); // Обратная прогонка
	for (int i = res.size()-2; i >= 0; i--) {
		x.push_back(res[i].first * x[x.size()-1] + res[i].second);
	}

	return inverse_vector (x, x.size());
}

vector<float> Gauss_osn(pair <vector <vector <float>>, vector <float>> para, int m, vector <float> res) {
	vector <vector <float>> mas = para.first;
	vector <float> b = para.second;
	vector <vector <float>> mas1 = mas; // Вспомогательный вектор
	cout << "Процесс прямого хода: " << endl;

	for (int k = 0; k < m; k++) {

		if (mas1[k][k] == 0) { // Если знаменатель равен нулю
			float max = 0;
			int max_str = k;

			for (int x = k; x < m; x++) { // Поиск в столбце максимального по модулю значения
				if (abs(mas1[x][k]) > 0) {
					max_str = x;
					max = abs(mas1[x][k]);
				}
			}
			if (max > 0) {
				pair <vector <vector <float>>, vector <float>> para(mas1, b);
				mas1 = iter_str(para, m, k, max_str).first;
				b = iter_str(para, m, k, max_str).second;
				cout << "Меняем местами строки с номерами " << k << " и " << max_str << endl;
				pair <vector <vector <float>>, vector <float>> para1(mas1, b);
				print(para1);
				mas = mas1;
			}
		}

		for (int j = k; j < m; j++) {
			mas[k][j] /= mas1[k][k];
		}

		b[k] /= mas1[k][k];

		for (int i = k + 1; i < m; i++) {
			for (int j = k; j < m; j++) {
				mas[i][j] -= mas1[i][k] * mas[k][j];
			}
			b[i] -= mas1[i][k] * b[k];
		}
		mas1 = mas;
		pair <vector <vector <float>>, vector <float>> para(mas, b);
		print(para);
	}

	cout << "Процесс обратного хода: " << endl;
	float raz = 0;

	for (int k = m - 1; k >= 0; k--) {
		cout << "x[" << k << "] = " << b[k];

		for (int x = 0; x < m - 1 - k; x++) {
			raz += res[x] * mas[k][m - x - 1];
			cout << " - x[" << m - x - 1 << "] * " << mas[k][m - x - 1];
		}

		res.push_back(b[k] * 1.0 - raz);
		cout << " = " << res[res.size() - 1] << endl;
		raz = 0;
	}
	return res;
}

int main() {
	setlocale(LC_ALL, "RUS");
	int m, i, j, val;
	vector <float> a, b, c, d, res1, res2;

	cout << "Введите размерность квадратной матрицы: ";
	cin >> m;

	for (int i = 0; i < m; i++) {
		cout << "a" << i << " = ";
		cin >> val;
		a.push_back(val);
		cout << "b" << i << " = ";
		cin >> val;
		b.push_back(val);
		cout << "c" << i << " = ";
		cin >> val;
		c.push_back(val);
		cout << "d" << i << " = ";
		cin >> val;
		d.push_back(val);
	}

	a[0] = 0;
	c[m - 1] = 0;

	vector <vector <float>> mas = CreateMatr_3_diagonal(a, b, c, m);
	pair <vector <vector <float>>, vector <float>> para(mas, d);
	print(para);

	res1 = Gauss_osn(para, m, res1);
	cout << endl;
	cout << "Метод прогонки:\n";

	res2 = progonka(a, b, c, d);

	for (int i = 0; i < m; i++) {
		cout << "x[" << i << "] = " << res2[i] << endl;
	}

	system("pause");
	return 0;
}
Соседние файлы в папке методы вычислений Поплавский