Foster w wątku
Odwracanie macierzy
napisał kod programu odwracającego macierz na podstawie znalezionego u Knutha pomysłu wykorzystującego osiowanie
Próbowałem przełożyć ten kod na C
ale dostaję gdzieś błąd Segmentation fault
#include<stdio.h>
#include<stdlib.h>
#include <math.h>
#define ZERO 1e-7
typedef enum {FALSE,TRUE} boolean;
boolean OdwracanieMacierzy(double** Macierz, unsigned int Stopien)
{
unsigned int w,k,w1,k1,i; // Zmienne wykorzystywane przy iteracji
unsigned int p,q; // Wspolrzedne elementu osiowego
unsigned int *c;
boolean *BylaJuzKolOsiowa;
double Max;
double **MacPom;
MacPom = (double**)malloc(Stopien * sizeof(double*));
for(i = 0;i < Stopien;i++)
MacPom[i] = (double*)malloc(Stopien * sizeof(double));
BylaJuzKolOsiowa = (boolean *)malloc(Stopien * sizeof(boolean));
c = (unsigned int *)malloc(Stopien * sizeof(unsigned int));
for(i=0;i<Stopien;i++);
{
BylaJuzKolOsiowa[i] = FALSE;
}
for(w = 0;w < Stopien;w++)
{
c[w] = 0;
Max = 0.0;
for(k = 0;k < Stopien;k++)
{
if(!BylaJuzKolOsiowa[k])
if(Max < fabs(Macierz[w][k]))
{
Max = fabs(Macierz[w][k]);
p = w;
q = k;
}
}
if(Max < ZERO)
{
return FALSE;
}
for(w1 = 0;w1 < Stopien;w1++)
for(k1 = 0;k1 < Stopien;k1++)
if(w1 != p && k1 != q)
Macierz[w1][k1] -= Macierz[p][k1]*Macierz[w1][q]*1.0/Macierz[p][q];
for(w1 = 0;w1 < Stopien;w++)
if(w1 != p) Macierz[w1][q] *= (-1.0)/Macierz[p][q];
for(k1 = 0;k1 < Stopien;k++)
if(k1 != q) Macierz[p][k1] *= (-1.0)/Macierz[p][q];
Macierz[p][q] = 1.0/Macierz[p][q];
c[w] = q;
BylaJuzKolOsiowa[q] = TRUE;
}
// Permutowanie macierzy
for(i = 0;i < Stopien;i++)
for(k = 0;k < Stopien;k++)
MacPom[i][k] = Macierz[i][k];
for(k = 0; k < Stopien;k++)
for(i = 0;i < Stopien;i++)
Macierz[c[k]][i] = MacPom[k][i];
for(i = 0;i < Stopien;i++)
for(k = 0;k < Stopien;k++)
MacPom[i][k] = Macierz[i][k];
for(k = 0; k < Stopien;k++)
for(i = 0;i < Stopien;i++)
Macierz[i][k] = MacPom[i][c[k]];
for(i = 0;i < Stopien;i++)
free(MacPom[i]);
free(MacPom);
free(BylaJuzKolOsiowa);
free(c);
return TRUE;
}
void Wczytaj(char* path,double** Macierz,unsigned int *Stopien)
{
FILE *in;
unsigned int i,j,stopien;
if((in = fopen(path,"rt")) == NULL)
{
fprintf(stderr,"Nie mozna otworzyc pliku do odczytu");
return;
}
fscanf(in,"%d",stopien);
Macierz = (double **)malloc(stopien*sizeof(double*));
for(i = 0; i < stopien;i++)
Macierz[i] = (double *)malloc(stopien * sizeof(double));
for(i = 0;i < stopien;i++)
for(j = 0;j < stopien;j++)
fscanf(in,"%lf",&Macierz[i][j]);
fclose(in);
*Stopien = stopien;
}
void Zapisz(char* path,double **Macierz,unsigned int Stopien,boolean OK)
{
FILE *out;
unsigned int i,j;
if((out = fopen(path,"wt")) == NULL)
{
fprintf(stderr,"Nie mozna otworzyc pliku do zapisu");
return;
}
if(OK)
for(i = 0;i < Stopien;i++)
{
for(j = 0;j < Stopien;j++)
fprintf(out,"%lf ",Macierz[i][j]);
fprintf(out,"\n");
}
else
fprintf(out,"Macierz osobliwa \n");
fclose(out);
}
int main()
{
double **Macierz;
unsigned int Stopien;
unsigned int i;
Wczytaj("inverse_matrix_Knuth_in.txt",Macierz,&Stopien);
if(OdwracanieMacierzy(Macierz,Stopien))
Zapisz("inverse_matrix_Knuth_out.txt",Macierz,Stopien,TRUE);
else
Zapisz("inverse_matrix_Knuth_out.txt",Macierz,Stopien,FALSE);
for(i = 0;i < Stopien;i++)
free(Macierz[i]);
free(Macierz);
return 0;
}