//---------------------Последовательная версия метода
Гаусса--------------------
//------------------------------------------------------------------------------
#include "stdafx.h"
#include < stdio.h>
#include < conio.h>
#include < math.h>
#include < time.h>
#include < fstream>
enum solution {NO_SOLUTION,ONE_SOLUTION,MANY_SOLUTIONS};
int g_size; ///< размерность исходной системы
double **g_matrix; ///< матрица коэффициентов системы
double *g_vector; ///< вектор свободных членов
double *g_result; ///< вектор значений неизвестных
solution g_isConsistent; ///< признак совместности системы
int *g_pivotRowIndex; ///< индекс ведущей строки системы на
соответствующей итерации
int *g_pivotRowIteration; ///< номер итерации, на которой строка системы
была выбрана в качестве ведущей */
double g_timeStart, ///< время начала работы алгоритма
g_timeFinish, ///< время завершения работы алгоритма
g_timeSolving; ///< время решения исходной задачи
/// Прямой ход метода Гаусса
void ForwardGauss()
{
for (int i = 0; i< g_size; i++)
{
/// Определяем индекс максимального по модулю элемента в i-м столбце, который
может быть выбран как управляющий
int PivotRowPosition = -1;
double MaxValue = 0;
int tmp_index = -1;
for (int j = 0; j< g_size; j++)
{
if (g_pivotRowIteration[j] == -1)
{
tmp_index = j;
if (fabs(g_matrix[j][i])>MaxValue)
{
MaxValue = fabs(g_matrix[j][i]);
PivotRowPosition = j;
}
}
}
/// Если все элементы в строке нулевые
if (PivotRowPosition == -1)
{
/// Система имеет много решений
g_isConsistent = MANY_SOLUTIONS;
/// Запоминаем номер итерации,на которой столбец был использован
g_pivotRowIteration[tmp_index] = i;
/// Запоминаем номер столбца использованного на этой итерации
g_pivotRowIndex[i] = tmp_index;
}
else
{
/// запоминаем номер итерации и столбец
g_pivotRowIteration[PivotRowPosition] = i;
g_pivotRowIndex[i] = PivotRowPosition;
for (int j = 0; j< g_size; j++)
{
/// Если строка ещё может изменяться
if (g_pivotRowIteration[j] == -1)
{
/// Вычисляем множитель для текущей строки так, чтобы i-й элемент
занулился
double Multiplier = g_matrix[j][i]/g_matrix[PivotRowPosition][i];
/// вычитаем из j-й строки главную с коэффициентом
for (int k = i; k< g_size; k++)
g_matrix[j][k] -= Multiplier*g_matrix[PivotRowPosition][k];
/// Аналогично изменяем вектор свободных коэффицинетов
g_vector[j] -= Multiplier*g_vector[PivotRowPosition];
}
}
}
}
}
/// Обратный ход метода Гаусса
void BackGauss()
{
/// Вычисляем значения элементов начиная с конца
for (int i = g_size-1; i>=0; i--)
{
/// получаем индекс неизвестной, которая была выбрана в качестве ведущей
int RowIndex = g_pivotRowIndex[i];
/// Если на месте ведущего элемента - 0...
if (g_matrix[RowIndex][i] == 0)
{
/// и на месте свободного коэффициента - 0
if (g_vector[RowIndex] == 0)
///
g_result[i] = 0;
else
{
/// Если же свободный коэффициент != 0
g_isConsistent = NO_SOLUTION;
break;
}
}
else
/// вычисляем значение i-й координаты результирующего вектора
g_result[i] = g_vector[RowIndex]/g_matrix[RowIndex][i];
for (int j = 0; j< i; j++)
{
/// корректируем значение вектора свободных коэффициентов
double val = g_matrix[g_pivotRowIndex[j]][i]*g_result[i];
g_vector[g_pivotRowIndex[j]] -= val;
}
}
}
int _tmain(int argc, char* argv[])
{
printf("Serial version of Gauss method\n\n");
printf("Matrix size -> ");
scanf_s("%d", &g_size);
printf("\nCalculating...");
g_matrix = new double* [g_size];
for (int i = 0; i< g_size; i++)
g_matrix[i] = new double [g_size];
g_vector = new double [g_size];
g_result = new double [g_size];
g_pivotRowIndex = new int [g_size];
g_pivotRowIteration = new int [g_size];
for (int i = 0; i< g_size; i++)
g_pivotRowIteration[i] = -1;
srand(unsigned(clock()));
std::fstream file;
file.open("..\\..\\input.txt", std::ios::out);
for (int i = 0; i< g_size; i++)
{
g_vector[i] = rand()/double(1000);
for (int j = 0; j< g_size; j++)
{
g_matrix[i][j] = rand()/double(1000);
file < < " " < < g_matrix[i][j];
}
file < < " " < < g_vector[i] < < "\n";
}
file.close();
g_timeStart = clock();
g_isConsistent = ONE_SOLUTION;
ForwardGauss();
BackGauss();
g_timeFinish = clock();
g_timeSolving = (g_timeFinish-g_timeStart)/CLOCKS_PER_SEC;
if (g_isConsistent == ONE_SOLUTION)
{
printf("\nSystem has one solution: \n\n");
}
else if (g_isConsistent == NO_SOLUTION)
printf("\nSystem has no solutions.\n");
else if (g_isConsistent == MANY_SOLUTIONS)
{
printf("\nSystem has infinitely many solutions. Particular solution is:
\n\n");
}
printf("\nWorking time: %f\n\n", g_timeSolving);
delete [] g_pivotRowIteration;
delete [] g_pivotRowIndex;
delete [] g_result;
delete [] g_vector;
for (int i = 0; i< g_size; i++)
delete [] g_matrix[i];
printf("Press any key to exit...");
_getch();
return 0;
}