#include <iostream>
#include <ctime>
#include <vector>
#include <iomanip> // std::setw
using namespace std;
void input();
void my_matrix();
void show_matrix(vector<vector <double>>& matrix, int n, int m);
double* LU(vector<vector <double>>& matrix, int n, int m);
int main() {
int answ, n, m;
cout << "1 - Input your matrix\n2 - God's matrix \n";
cin >> answ;
cout << endl;
switch (answ) {
case 1: input(); break;
case 2: my_matrix(); return 0;
}
system("pause");
return 0;
}
void my_matrix() {
vector <vector <double>> my_matrix = { { 2, 4, 4, -9, 21 },
{ 4, -9, -9, -8, -2 },
{ 4, -9, 5, 6, 40 },
{ -9, -8, 6, -3, 25 } };
cout << endl << "God's matrix:" << endl;
show_matrix(my_matrix, 4, 5);
vector <vector <double>> LU_matrix = my_matrix;
clock_t start = clock();
double *solutions = LU(LU_matrix, 4, 5);
for (int i = 0; i < 4; i++)
cout << "X" << i + 1 << " = " << solutions[i] << endl;
cout << "Duration " << ((double)(clock()-start) / CLOCKS_PER_SEC) << " sec" << endl;
system("pause");
}
void input() {
int n = 0;
cout << "Input matrix size \n";
cin >> n;
cout << "Input matrix please \n";
vector <vector <double>> matrix;
matrix.assign(n, vector<double>(n+1));
for (int i = 0; i < n; i++) {
for (int k = 0; k < n+1; k++) {
cin>> matrix[i][k];
}
}
cout << "Your matrix:" << endl;
show_matrix(matrix, n, n+1);
clock_t start = clock();
double* solutions = LU(matrix, n, n+1);
for (int i = 0; i < n; i++)
cout << "X" << i + 1 << " = " << solutions[i] << endl;
cout << "Duration " << ((double)(clock() - start) / CLOCKS_PER_SEC) << " sec" << endl;
system("pause");
}
double* LU(vector<vector <double>>& matrix, int n, int m) {
double ratio, * temp_line = new double[m];
vector <vector <double>> L(n, vector<double>(n, 0)); //нижний треугольний вид
for (int i = 0; i < n - 1; i++) {
L[i][i] = 1; //в матрице L главная диагональ состоит из единиц
if (matrix[i][i] == 0) { //если на диагонали 0, то меняем строку со следубщей местами
for (int j = 0; j < m; j++)
temp_line[j] = matrix[i][j]; //временная строка
for (int j = 0; j < m; j++)
matrix[i][j] = matrix[i + 1][j];
for (int j = 0; j < m; j++)
matrix[i + 1][j] = temp_line[j];
}
for (int j = i + 1; j < n; j++) {
if (matrix[i][i] != 0) { //если в столбце не нули
ratio = matrix[j][i] / matrix[i][i];
L[j][i] = ratio; //L состоит из множетелей matrix, которые мы используем для перевода ее к треугольному виду
for (int k = i; k < m - 1; k++) //m-1 т.к. столбец свободных членов не трогаем
matrix[j][k] = matrix[j][k] - ratio * matrix[i][k]; //делаем нули в matrix, переводя ее к верхнему треугольному виду
}
}
}
L[n - 1][n - 1] = 1; //последний элемент главной диагонали = 0
double * temp_column = new double[n];
for (int i = 0; i < n; i++)
temp_column[i] = 0;
for (int i = 0; i < n; i++) {
double sum = 0;
for (int j = 0; j < i; j++) //проходим ниже главной диагонали L
sum += temp_column[j] * L[i][j]; //находим сумму элементов строки L
temp_column[i] = (matrix[i][m - 1] - sum) / L[i][i]; //находим значения Y, где L * Y = B, где B-столбец свободных членов
}
if (matrix[n - 1][m - 3] != 0) { //проверяем на решаемость
cout << "Infinitely many roots" << endl;
system("pause");
exit(0);
}
else if (matrix[n - 1][m - 2] == 0) { //проверяем на решаемость
cout << "No roots" << endl;
system("pause");
exit(0);
}
double* roots = new double[n]; //массив корней
for (int i = 0; i < n; i++)
roots[i] = 0;
for (int i = m - 2; i >= 0; i--) { //находим значения X, где Y= U * X, где U=matrix, X-столбец(x1,x2...xn)
double sum = 0;
for (int j = m - 2; j > i; j--) //m-1 элемент = xn
sum += matrix[i][j] * roots[j]; //сумма элементов строки
roots[i] = (temp_column[i] - sum) / matrix[i][i]; //находим корни
}
return roots;
}
void show_matrix(vector <vector <double>>& matrix, int n, int m) {
for (int i = 0; i < n; i++) {
for (int k = 0; k < m; k++)
cout << setw(4) << matrix[i][k];
cout << endl;
}
}