Войти

Показать полную графическую версию : Изменение двухмерных массивов


mrcnn
01-07-2008, 21:45
Как сделать так, чтобы была задействована только одна матрица?

Поэлементно что ли копировать? Предположим я поэлементно копирую в матрицу из промежуточного одномерного массива? А потом опять поэлементно заменять содержимое одномерного массива и снова копировать в матрицу?

int matrix[X][Y] = {
{4,-3,-3,4},
{4,-1,0,5},
{5,1,5,9}};
kramer(matrix);

int matrix1[X][Y] = {
{3,-5,0,8},
{3,-5,1,9},
{-4,1,1,4}};
kramer(matrix1);

int matrix2[X][Y] = {
{-4,2,-5,-11},
{-1,2,-2,-5},
{5,4,1,2}};
kramer(matrix2);

int matrix3[X][Y] = {
{-2,3,-5,-20},
{-5,1,5,-2},
{-2,3,-3,-16}};
kramer(matrix3);

int matrix4[X][Y] = {
{-2,4,0,-12},
{2,3,1,0},
{3,5,-1,-6}};
kramer(matrix4);

int matrix5[X][Y] = {
{5,4,3,8},
{-4,2,1,-10},
{2,4,4,4}};
kramer(matrix5);

int matrix6[X][Y] = {
{3,5,3,3},
{3,5,-5,-21},
{2,0,1,9}};
kramer(matrix6);/**/

Я хотел сначала сделать так, но так нельзя
int matrix[X][Y] = {
{4,-3,-3,4},
{4,-1,0,5},
{5,1,5,9}};
kramer(matrix);

matrix[X][Y] = {
{3,-5,0,8},
{3,-5,1,9},
{-4,1,1,4}};
kramer(matrix);

mrcnn
02-07-2008, 19:03
1. как объявить указатель на двухмерный массив?

2. как передать двухмерный массив в функцию?

3. как описать функцию, которая получает указатель на двухмерный массив?


/*
вычеркивание из матрицы d строки и i столбца и
копирование полученной вычеркиванием матрицы в data
*/

#include <stdio.h>

#define X 3

void main()
{
int matrix[X][X] = {
{4,-3,-3},
{4,-1,0},
{5,1,5}};

int size=X-1;
int **data; /*как описать этот указатель правильно*/
int d=0;
int i=0;
int k,l,datai,dataj;

data = new int[size][size];

datai=0;
dataj=0;

for (k=0 ; k<X; k++) //проход про строкам
{


if (k != d){

for (l=0; l<X;l++) //проход по столбцам строки
{

if (l!=i){

data[datai][dataj]=matrix[k][l];

dataj++;

}

}


datai++;
dataj=0;

}



}

for (k=0;k<size;k++)
{
for(l=0;l<size;l++)
{
printf("%d ",data[k][l]);
}
printf("\n");
}

delete[] data;
}

mrcnn
02-07-2008, 19:51
С первым вопросом вроде бы разобрался.


#include <stdio.h>

#define X 3

void main()
{
int matrix[X][X] = {
{4,-3,-3},
{4,-1,0},
{5,1,5}};

int size=X-1;
int** data; /*как описать этот указатель правильно*/
int d=0;
int i=0;
int k,l,datai,dataj;

data = new int*[size];

for(k=0;k<size;k++)
{
data[k]=new int[size];
}

datai=0;
dataj=0;

for (k=0 ; k<X; k++) //проход про строкам
{


if (k != d){

for (l=0; l<X;l++) //проход по столбцам строки
{

if (l!=i){

*((*(data+datai))+dataj)=matrix[k][l];

dataj++;
//printf ("matrix[%d][%d]=%d\n", k,l,matrix[k][l]);

}

}


datai++;
dataj=0;

}



}

for (k=0;k<size;k++)
{
for(l=0;l<size;l++)
{
printf("%d ",data[k][l]);
}
printf("\n");
}

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

delete[] data;
}

mrcnn
02-07-2008, 21:10
Написал нахождение определителя разложением по строке заодно разобрался с двухмерными массивами. Хотя алгоритм очень неэффективный из-за копирования . Можно и без копирования обойтись, но там нужно как-то пересчет индексов для алгебраического дополнения делать, чтобы -1 возвести в нужную степень.



#include <stdio.h>
#include <windows.h>
#include <time.h>

#define XYZZ 10

void print_matrix(int **m);
void random_matrix(int **m);
int opredelitel(int **m, int d,int sz);
int poww(int,int);

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

for(int k=0;k<size;k++)
{
matrix[k]=new int[size];
}

random_matrix(matrix);
print_matrix(matrix);
mainopr=opredelitel(matrix,0,XYZZ);
printf("%d\n",mainopr);
}

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

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

}

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

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

}


int opredelitel(int **m, int d,int sz)
{
int** data;
int result, size,i,k,l,reali,realj,datai,dataj,n,correction,t;

result = 0;

if ( sz > 2){
for( i = 0 , reali = d+1 , realj = i+1; i < sz ; i++ , realj=i+1)
{
correction = poww(-1,reali+realj); // (-1)^(i+j)

// копирование матрицы
size = sz - 1;

data = new int*[size];

for(k=0;k<size;k++)
{
data[k]=new int[size];
}

datai=0;
dataj=0;

for (k=0 ; k<sz; k++) //проход про строкам
{
if (k != d){
for (l=0; l<sz;l++) //проход по столбцам строки
{
if (l!=i){
data[datai][dataj]=m[k][l];
dataj++;
}
}
datai++;
dataj=0;
}
}
n=opredelitel(data,0,size);
t=m[d][i]*correction*n;
result+=t;
}

}
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);
}
}

}

return(result);
}

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

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

}

mrcnn
02-07-2008, 23:02
Нахождение определителя редукцией.
Количество действий
(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);

}

mrcnn
03-07-2008, 10:25
Нахождение обратной матрицы
В качестве матрицы взята матрица из №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;
}
}
}

mrcnn
03-07-2008, 11:21
Решение системы линейных уравнений методом Крамера


#include <stdio.h>
#include <windows.h>
#include <time.h>

#define XYZZ 4

void print_matrix(double **m, int sz);
void print_vector(double *m, int sz);
void random_matrix(double **m, int sz);
void random_vector(double *m, int sz);
double opredelitel(double **m, int sz);
void change_lines(double **m, int sz, int d,int t);
int poww(int,int);
void copy_matrix(double **m, double **newm, int sz);
void change_column_matrix(double **m, double **newm, double *line, int num_column, int sz);
void kramer(double **m, double *line, double mainopr,int sz);

void main()
{
double mainopr;
int size=XYZZ;
double* line;
double** matrix;

matrix = new double*[size];

for(int k=0;k<size;k++)
{
matrix[k]=new double[size];
}

line = new double[size];



/* Проскуряков #567*/
/*matrix[0][0]=3;matrix[0][1]=-2;matrix[0][2]=-5;matrix[0][3]=1;
matrix[1][0]=2;matrix[1][1]=-3;matrix[1][2]=1;matrix[1][3]=5;
matrix[2][0]=1;matrix[2][1]=2;matrix[2][2]=0;matrix[2][3]=-4;
matrix[3][0]=1;matrix[3][1]=-1;matrix[3][2]=-4;matrix[3][3]=9;
line[0]=3; line[1]=-3; line[2]=-3;line[3]=22;/**/
/* Проскуряков #568*/
/*matrix[0][0]=4;matrix[0][1]=-3;matrix[0][2]=1;matrix[0][3]=5;
matrix[1][0]=1;matrix[1][1]=-2;matrix[1][2]=-2;matrix[1][3]=-3;
matrix[2][0]=3;matrix[2][1]=-1;matrix[2][2]=2;matrix[2][3]=0;
matrix[3][0]=2;matrix[3][1]=3;matrix[3][2]=2;matrix[3][3]=-8;
line[0]=7; line[1]=3; line[2]=-1;line[3]=-7;/**/

random_matrix(matrix,size);
printf("Matrix:\n");
print_matrix(matrix,size);
random_vector(line,size);
printf("Vector:\n");
print_vector(line,size);

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


if (mainopr !=0)
{
printf("Reshenie: \n");
kramer(matrix, line,mainopr, size);
}
else
{
printf("Systema nekramerovskaya\n");
}

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

delete[] matrix;
delete[] line;
}


void kramer(double **m, double *line, double mainopr,int sz)
{
int i;
double** newmatrix;
double x;

newmatrix = new double*[sz];
for(int k=0;k<sz;k++)
{
newmatrix[k]=new double[sz];
}

for(i=0; i<sz;i++)
{
change_column_matrix(m, newmatrix, line, i, sz);
x=opredelitel(newmatrix,sz)/mainopr;
printf("x[%d]=%f\n",i,x);
}

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

delete[] newmatrix;

}

void change_column_matrix(double **m, double **newm, double *line, int num_column, int sz)
{

int i,j;

if (num_column <sz){
for (i=0 ; i<sz; i++)
{
for (j=0; j<sz;j++)
{
if (j != num_column)
{
newm[i][j]=m[i][j];
}
else
{
newm[i][j]=line[i];
}

}
}
}
else
{
printf("Error\n");
}

}

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 print_vector(double *m, int sz)
{
int i;

for (i=0 ; i<sz; i++)
printf("%f ", m[i]);
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 random_vector(double *m, int sz)
{
int i;
srand (time(NULL));

for (i=0 ; i<sz; i++)
m[i]=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];

}


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);

}

mrcnn
03-07-2008, 11:58
Решение системы линецных уравнений методом обратной матрицы


#include <stdio.h>
#include <windows.h>
#include <time.h>

#define XYZZ 4

void print_matrix(double **m, int sz);
void print_vector(double *m, int sz);
void random_matrix(double **m, int sz);
void random_vector(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 multiplicate_matrix_and_vector(double **m, double *line, double *result, double mainopr,int sz);

void main()
{
double mainopr;
int size=XYZZ;
double* line;
double* result;
double** matrix;

matrix = new double*[size];

for(int k=0;k<size;k++)
{
matrix[k]=new double[size];
}

line = new double[size];
result = new double[size];

/* Проскуряков #567*/
/*matrix[0][0]=3;matrix[0][1]=-2;matrix[0][2]=-5;matrix[0][3]=1;
matrix[1][0]=2;matrix[1][1]=-3;matrix[1][2]=1;matrix[1][3]=5;
matrix[2][0]=1;matrix[2][1]=2;matrix[2][2]=0;matrix[2][3]=-4;
matrix[3][0]=1;matrix[3][1]=-1;matrix[3][2]=-4;matrix[3][3]=9;
line[0]=3; line[1]=-3; line[2]=-3;line[3]=22;/**/
matrix[0][0]=4;matrix[0][1]=-3;matrix[0][2]=1;matrix[0][3]=5;
matrix[1][0]=1;matrix[1][1]=-2;matrix[1][2]=-2;matrix[1][3]=-3;
matrix[2][0]=3;matrix[2][1]=-1;matrix[2][2]=2;matrix[2][3]=0;
matrix[3][0]=2;matrix[3][1]=3;matrix[3][2]=2;matrix[3][3]=-8;
line[0]=7; line[1]=3; line[2]=-1;line[3]=-7;

//random_matrix(matrix,size);
printf("Matrix:\n");
print_matrix(matrix,size);
//random_vector(line,size);
printf("Vector:\n");
print_vector(line,size);

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

if (mainopr !=0)
{
printf("Reshenie metodom obratn matricy: \n");
multiplicate_matrix_and_vector(matrix, line,result, mainopr, size);
}
else
{
printf("Matritsa ne imeet obratnoy. Metod neprimenim\n");
}

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

delete[] matrix;
delete[] line;
delete[] result;
}



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 print_vector(double *m, int sz)
{
int i;

for (i=0 ; i<sz; i++)
printf("%f ", m[i]);
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 random_vector(double *m, int sz)
{
int i;
srand (time(NULL));

for (i=0 ; i<sz; i++)
m[i]=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;
}
}
}


void multiplicate_matrix_and_vector(double **m, double *line, double *result, double mainopr,int sz)
{
int i,j;
double x;
double** newmatrix;
newmatrix = new double*[sz];

for(int k=0;k<sz;k++)
{
newmatrix[k]=new double[sz];
}


if (mainopr !=0)
{
obratnaya_matrix(m, newmatrix, mainopr, sz);
printf("Obratnaya matritsa: \n");
print_matrix(newmatrix,sz);

for (i=0;i<sz;i++)
{
x=0;
for (j=0; j<sz;j++)
{
x += newmatrix[i][j]*line[j];
}
result[i]=x;
printf("result[%d]=%f\n",i,result[i]);
}
}
else
{
printf("Error\n");
}

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

delete[] newmatrix;

}

Drongo
03-07-2008, 15:08
mrcnn, Решение системы линецных уравнений методом обратной матрицы »Давно хотел посмотреть на это решение. Спасибо. Вот ещё ссылка на подобный вопрос - Нахождение обратной матрицы (http://forum.sources.ru/index.php?showtopic=55150&hl=обратной,and,матрицы), если это конечно, то?

mrcnn
03-07-2008, 17:16
Давно хотел посмотреть на это решение. Спасибо. Вот ещё ссылка на подобный вопрос - Нахождение обратной матрицы, если это конечно, то? »

Там по-видимому другой метод используют. Меня учили находить обратную матрицу через алгебраические дополнения. Другие методы я не знаю.

А системы еще можно решить методом блочной матрицы (воздействием на единичную), методом Гаусса. Метод Гаусса решения систем я тоже хочу реализовать, в принципе он простой.

Хочу создать классы для работы с векторами и матрицами, чтобы хорошо разобраться в ООП в С++.




© OSzone.net 2001-2012