Нахождение определителя редукцией.
Количество действий
(n-1)*n+(n-2)*(n-1)+..+3*2+2*1
где n - размерность квадратной матрицы
Код:
#include <stdio.h>
#include <windows.h>
#include <time.h>
#define XYZZ 10
void print_matrix(double **m);
void random_matrix(double **m);
double opredelitel(double **m, int sz);
int poww(int,int);
void change_lines(double **m, int d,int t);
void main()
{
double mainopr;
int size=XYZZ;
double** matrix;
matrix = new double*[size];
for(int k=0;k<size;k++)
{
matrix[k]=new double[size];
}
random_matrix(matrix);
print_matrix(matrix);
mainopr=opredelitel(matrix,XYZZ);
printf("%f\n",mainopr);
for(k=0;k<XYZZ;k++)
{
delete[] matrix[k];
}
delete[] matrix;
}
void print_matrix(double **m)
{
int i,j;
for (i=0 ; i<XYZZ; i++)
{
for (j=0; j<XYZZ;j++)
{
printf("%f ", m[i][j]);
}
printf("\n");
}
}
void random_matrix(double **m)
{
int i,j;
srand (time(NULL));
for (i=0 ; i<XYZZ; i++)
for (j=0; j<XYZZ;j++)
m[i][j]=rand()%10;
}
double opredelitel(double **m, int sz)
{
double x,result;
int i,j,k,l,n, num_of_changes;
result = 1;
num_of_changes=0;
if ( sz > 2)
{
for(i=0,j=0;i<sz-1;i++,j++)
{
if (m[i][j]==0)
{
//ищем строку, где не равны нулю, и переставляем
for(k=i+1;k<sz;k++)
{
if(m[k][j]!=0)
{
change_lines(m,i,k);
num_of_changes++;
break;
}
}
}
//m[i][j] не равен 0
//проход по строке l
for(l=i+1;l<sz;l++)
{
if (m[l][j] != 0)
{
//m[0][0]*x+m[1][0]=0 => x=-m[1][0]/m[0][0]
//x=-m[1][0]/m[0][0];
x=-m[l][j]/m[i][j];
//проход по столбцу
for (n=j;n<sz;n++)
{
m[l][n]=m[i][n]*x+m[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 *= m[i][j] ;
}
result *= poww(-1,num_of_changes);
return(result);
}
void change_lines(double **m, int d,int t)
{
int i;
double temp;
for (i=0;i< XYZZ;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);
}