Лабораторная работа №1
По вычислительной математике
«Метод Гаусса»
Студента группы ПВ – 22
Воробьева Романа
-
Решить «вручную» системы линейных уравнений соответствующего варианта методом Гаусса
-
Выполнить действия над матрицами соответствующего варианта
-
Создать модуль для работы с матрицами произвольного порядка, содержащий подпрограммы: для умножения матриц, умножения числа на матрицу, сложения матриц, транспонирования матриц.
-
Создать модуль GAUSS, содержащий в интерфейсе функции:
-
Для нахождения единственного решения системы линейных уравнений методом Гаусса с частичным выбором главного элемента по столбцу для произвольного числа столбцов свободных членов;
-
Вычисления определителя;
-
Нахождения обратной матрицы.
Создать программу для демонстрации работы описанных в модуле GAUSS подпрограмм. Результаты ручного счета использовать как тестовые данные.
Спецификации подпрограмм:
-
Функция DecisionSystems:
Заголовок: bool DecisionSystems(double **a,double **rez,int N,int M)
Назначение: Функция возвращает 1, если M систем порядка N с одной и той же матрицей коэффициентов, но разными правыми частями имеет единственное решение, решение записывает в матрицу rez; в противном случае возвращает 0.
-
Функция Determinant:
Заголовок: double Determinant(double **a,int N)
Назначение: Функция возвращает определитель n-ого порядка, матрицы a размером n*n.
-
Функция ReturnMatrix:
Заголовок: bool ReturnMatrix(double **a,double **rez,int N)
Назначение: Функция возвращает 1, если обратная матрица для данной матрицы a размером N*N существует, и записывает обратную матрицу в rez; возвращает 0 в противном случае.
Main.c
#include "stdafx.h"
#include <iostream>
#include "gauss.h"
using namespace std;
using namespace System;
int main(array<System::String ^> ^args)
{
int n,m;
Console::WriteLine(L"Введите размер матрицы :"); scanf("%d",&n);
Console::WriteLine(L"Введите количество правых частей :"); scanf("%d",&m);
double **a,**rez;
a=Get_Mem(n,n+m);
rez=Get_Mem(n,n+m);
Console::WriteLine(L"Введите матрицу размером "+n+" x "+ (n+m));
InputMatrix(a,n,n+m);
if (DecisionSystems(a,rez,n,m))
OutputMatrix(rez,m,n);
else
Console::WriteLine(L"Единственное решение не найдено");
Free_Mem(a,n);
Free_Mem(rez,n);
system("pause");
return 0;
}
Matrix.h
#if !defined(__MATRIX_H)
#define __MATRIX_H
void CopyMatrix(double **a,double **b,int N,int M); //Копирование матриц
void SwapColumn(double **a, int N, int i, int j); //Обмен колоками матрицы
void SwapRow(double **a,int M,int i,int j); //Обмен строками матрицы
void OutputMatrix(double **a,int N,int M); //Вывод матрицы
void InputMatrix(double **a,int N,int M); //Ввод матрицы
void AddMatrix(double **a,double **b,double **c,int n,int m); //сложение матриц
void SubMatrix(double **a,double **b,double **c,int n,int m); //вычитание матриц
void MulMatrixNumber(double **a,double **b,double **c,int number,int n,int m); //умножение матрицы на число
void MulMatrix(double **a,double **b,double **c,int n,int m); //умножение матриц
void TranspositionMatrix(double **a,double **c,int n,int m); //транспонирование матриц
bool Get_Mem(int n,int m); //выделение памяти по матрицу
void Free_Mem(double **a,int n); //освобождение памяти из-под матрицу
#endif
double** Get_Mem(int n,int m)
{
double **a;
a=(double**)malloc(n*sizeof(double*));
for (int i=0; i<n; i++)
a[i]=(double*)malloc(m*sizeof(double));
return a;
}
void Free_Mem(double **a,int N)
{
for (int i=0; i<N; i++)
free(a[i]);
free(a);
}
void AddMatrix(double **a,double **b,double **c,int n,int m)
{
for (int i=0; i<n; i++)
for (int j=0; j<m; j++)
c[i][j]=a[i][j]+b[i][j];
}
void SubMatrix(double **a,double **b,double **c,int n,int m)
{
for (int i=0; i<n; i++)
for (int j=0; j<m; j++)
c[i][j]=a[i][j]-b[i][j];
}
void MulMatrixNumber(double **a,double **c,double number,int n,int m)
{
for (int i=0; i<n; i++)
for (int j=0; j<m; j++)
c[i][j]=a[i][j]*number;
}
void MulMatrix(double **a,double **b,double **c,int n,int m)
{
for (int l=0; l<n; l++)
for (int i=0; i<m; i++)
{
c[l][i]=0;
for (int j=0; j<n; j++)
c[l][i]+=a[l][j]*b[j][i];
}
}
void TranspositionMatrix(double **a,double **c,int n,int m)
{
for (int i=0; i<n; i++)
for (int j=0; j<m; j++)
c[i][j]=a[j][i];
}
void InputMatrix(double **a,int N,int M)
{
for (int i=0; i<N; i++)
for (int j=0; j<M; j++)
scanf("%lf",&a[i][j]);
}
void OutputMatrix(double **a,int N,int M)
{
for (int i=0; i<N; i++)
{
for (int j=0; j<M; j++)
printf("%lf ",a[i][j]);
printf("\n");
}
}
void SwapRow(double **a,int M,int i,int j)
{
int l;
double buf;
for (l=0; l<M; l++)
{
buf=a[i][l];
a[i][l]=a[j][l];
a[j][l]=buf;
}
}
void SwapColumn(double **a, int N, int i, int j)
{
int l;
double buf;
for (l=0; l<N; l++)
{
buf=a[l][i];
a[l][i]=a[l][j];
a[l][j]=buf;
}
}
void CopyMatrix(double **a,double **b,int N,int M)
{
int i, j;
for (i=0; i<N; i++)
for (j=0; j<M; j++)
b[i][j]=a[i][j];
}
GAUSS.h
#if !defined(__TREE_H)
#define __TREE_H
#include "matrix.h"
bool DecisionSystems(double **a,double **rez,int N,int M);
double Determinant(double **a,int N);
bool ReturnMatrix(double **a,double **rez,int N);
#endif
static signed char sign;
bool Transpos(double **a,int N,int M) //false, если ноль на главной диагонали, =>A^(-1) не существует и =>det A=0
{
int i,j,l;
double k,max;
sign=1;
for (i=0; i<N; i++)
{
max=0;
for (j=i; j<N-1; j++)
{
if (fabs(a[j][i])>max)
{
max=fabs(a[j][i]);
l=j;
}
}
if (max==0)
return false;
if (i!=l)
{
SwapRow(a,N+M,i,l);
sign=-sign;
}
for (j=i; j<N; j++)
{
k=-1*a[j][i]/a[i][i];
for (l=i; l<N+M; l++)
a[j][l]+=a[i][l]*k;
}
}
return true;
}
bool DecisionSystems(double **a,double **rez,int N,int M) //Возвращает true, если существуют единственные решения систем линейных уравнений, иначе - false.
{
int i,j,t;
int f;
double *x,**b;
x=(double*)malloc(N*sizeof(double));
b=Get_Mem(N,N+M);
CopyMatrix(a,b,N,N+M);
if (Transpos(b,N,M))
{
f=N+1;
for (t=0; t<M; t++)
{
for (i=0; i<N; i++)
x[i]=1;
for (i=N-1; i>=0; i--)
{
for (j=N-1; j>i; j--)
{
b[i][j]*=x[j];
b[i][N]-=b[i][j];
}
if (b[i][j]==0)
return false;
x[j]=b[i][N]/b[i][j];
}
for (i=0; i<N; i++)
rez[t][i]=x[i];
printf("\n");
SwapColumn(a,N,N+t,f);
f++;
}
Free_Mem(b,N);
free(x);
return true;
}
else
{
Free_Mem(b,N);
free(x);
return false;
}
}
double Determinant(double **a,int N) //Возвращает детерминант матрицы a.
{
double r=1,**b;
b=Get_Mem(N,N);
CopyMatrix(a,b,N,N);
Transpos(b,N,0);
for (int i=0; i<N; i++)
r*=b[i][i];
Free_Mem(b,N);
return r*sign;
}
bool ReturnMatrix(double **a,double **rez,int N) //Возвращает true и rez=A^(-1), если существует обратная матрица матрицы а, иначе - false.
{
int i,j,l;
double max,k,**b;
b=Get_Mem(N,N);
CopyMatrix(a,b,N,N);
if (Transpos(a,N,0))
{
for (i=0; i<N; i++)
{
for (j=0; j<N; j++)
rez[i][j]=0;
rez[i][i]=1;
}
for (i=0; i<N-1; i++)
{
for (j=i+1; j<N; j++)
{
k=-1*b[j][i]/b[i][i];
for (l=i; l<N; l++)
{
b[j][l]+=b[i][l]*k;
rez[j][l]+=rez[i][l]*k;
}
}
}
Free_Mem(b,N);
return true;
}
Free_Mem(b,N);
return false;
}