Имя пользователя:
Пароль:
 

Показать сообщение отдельно

Ветеран


Сообщения: 1405
Благодарности: 135

Профиль | Отправить PM | Цитировать


Нахождение обратной матрицы
В качестве матрицы взята матрица из №840 учебника Проскурякова

Код: Выделить весь код
#include <stdio.h>
#include <windows.h>
#include <time.h>

#define XYZZ 3

void print_matrix(double **m, int sz);
void random_matrix(double **m, int sz);
double opredelitel(double **m, int sz);
void obratnaya_matrix(double **m, double **newm, double mainopr, int sz);
int poww(int,int);
void change_lines(double **m, int sz, int d,int t);
void copy_matrix(double **m, double **newm, int sz);
void copy_matrix(double **m, double **newm, int sz, int d, int i);

void main()
{
	double mainopr;
	int size=XYZZ;
	double** matrix;
	double** newmatrix;
	matrix = new double*[size];
	newmatrix = new double*[size];

	for(int k=0;k<size;k++)
		{
		matrix[k]=new double[size];
		newmatrix[k]=new double[size];
		}
	
	matrix[0][0]=2;matrix[0][1]=5;matrix[0][2]=7;
	matrix[1][0]=6;matrix[1][1]=3;matrix[1][2]=4;	
	matrix[2][0]=5;matrix[2][1]=-2;matrix[2][2]=-3;/*Учебник Проскурякова №840*/

	//random_matrix(matrix);
	print_matrix(matrix,size);
	mainopr=opredelitel(matrix,size);
	printf("Main determinant: %f\n",mainopr);

	/*Обратная матрица существует, если определитель не равен нулю*/
	if (mainopr !=0)
	{
		obratnaya_matrix(matrix, newmatrix, mainopr, size);
		printf("Obratnaya matritsa: \n");
		print_matrix(newmatrix,size);
	}
	else
	{
		printf("Net obratnoy matricy\n");
	}


	for(k=0;k<size;k++)
	{
		delete[] matrix[k];
		delete[] newmatrix[k];
	}

	delete[] matrix;
	delete[] newmatrix;

	
}

void print_matrix(double **m, int sz)
{
int i,j;

for (i=0 ; i<sz; i++)
	{
		for (j=0; j<sz;j++)
		{
			printf("%f ", m[i][j]);
		}
		printf("\n");
	}

}

void random_matrix(double **m, int sz)
{
int i,j;
srand (time(NULL));

for (i=0 ; i<sz; i++)	
	for (j=0; j<sz;j++)		
		m[i][j]=rand()%10;

}

void copy_matrix(double **m, double **newm, int sz)
{
	int i,j;
	for (i=0 ; i<sz; i++)	
		for (j=0; j<sz;j++)		
			newm[i][j]=m[i][j];

}
void copy_matrix(double **m, double **newm, int sz, int d, int i)
{
	int k,l,newmi,newmj;

	newmi=0;
	newmj=0;

	for (k=0 ; k<sz; k++) 
		{
		if (k != d)
			{
				for (l=0; l<sz;l++)
				{
					if (l!=i)
					{
						newm[newmi][newmj]=m[k][l];
						newmj++;
					}
				}
				newmi++;
				newmj=0;						
			}
		}
}

double opredelitel(double **m, int sz)
{
	double x,result;
	int i,j,k,l,n, num_of_changes;
	double** matrix_copy;

	matrix_copy = new double*[sz];
	for(k=0;k<sz;k++)
		matrix_copy[k]=new double[sz];
	copy_matrix(m,matrix_copy,sz);
	
	result = 1;
	num_of_changes=0;

	if ( sz > 2)
		{
			for(i=0,j=0;i<sz-1;i++,j++)
				{
					if (matrix_copy[i][j]==0)
						{						
							for(k=i+1;k<sz;k++)
							{
								if(matrix_copy[k][j]!=0)
								{
									change_lines(matrix_copy,sz,i,k);
									num_of_changes++;
									break;
								}
							}
						}
					for(l=i+1;l<sz;l++)
						{							
								if (matrix_copy[l][j] != 0)
									{
										x=-matrix_copy[l][j]/matrix_copy[i][j];
										for (n=j;n<sz;n++)
										{
											matrix_copy[l][n]=matrix_copy[i][n]*x+matrix_copy[l][n];
										}
									}
						}
				}
		}
	else if (sz==2)
		{
		return (m[0][0]*m[1][1]-m[0][1]*m[1][0]);
		}
	else if (sz==1)
		{
		return (m[0][0]);
		}			
	else 
		{
		printf ("Error");
		return (-1);
		}

	for(i=0,j=0;i<sz;i++,j++)
	{
		result *= matrix_copy[i][j] ;
	}
	result *= poww(-1,num_of_changes);

	for(k=0;k<sz;k++)
		delete[] matrix_copy[k];	
	delete[] matrix_copy;

	return(result);	
}

void change_lines(double **m, int sz, int d,int t)
{
	int i;
	double temp;
	for (i=0;i< sz;i++)
	{
		temp=m[d][i];
		m[d][i]=m[t][i];
		m[t][i]=temp;
	}
}


int poww(int d,int t){
	int st=1;
	int result=1;

	for(st=1; st<=t; st++)
	{
		result*=d;
	}
	return (result);

}



void obratnaya_matrix(double **m, double **newm, double mainopr, int sz)
{	
	/*
	Алгоритм
	1. находим алгебраической дополнение
	2. делим алг. дополнение на определитель
	3. заносим в новую матрицу
	*/

	double** data;
	int size, i,j,k,reali,realj,correction;
	double opr, obr_element;

	size = sz - 1;//Размер алгебраического дополнения


	for (i=0;i<sz;i++)
	{
		for( j=0;j<sz;j++)
		{
			//алгебраическое дополнение
			data = new double*[size]; 

			for(k=0;k<size;k++)
			{
				data[k]=new double[size];
			}
			// Находим алгебраическое дополнение
			// Вычеркиваемая строка  i,j
			copy_matrix(m, data,sz,i,j);

			//Находим определитель алгебраического дополнения
			opr=opredelitel(data,size);	

			reali=i+1;
			realj=j+1;
			
			correction = poww(-1,reali+realj);

			//Уничтожаем алгебраическое дополнение
			for(k=0;k<size;k++)
				{
					delete[] data[k];
				}
			delete[] data;

			//Находим обратный элемент
			obr_element = (opr*correction)/mainopr;

			//Заносим в обратную матрицу
			newm[j][i]=obr_element;
		}
	}
}

-------
Ehhh.. what's up, doc?..


Отправлено: 10:25, 03-07-2008 | #6