liczenie wyznacznika macierzy w C

0

Witam.
Mam pały problem. Otóż nie działa mi funkcja liczaca wyznacznik macierzy. Wszystko powinno sie wykonywac bez problemu, ale z jakiegos powodu wywala mi program (kompilacja bez problemu). Jestem pewny ze błąd jest w tej wlasnie funkcji. Mozecie pomoc?

double det(double ** matrix, int n)
{
double** minor;
double sum=0.0;
double sign=1.0;
int i;
int x,y,a=0,b=0;
if(n==1) return matrix[0][0];
if(n==2) return (matrix[0][0]*matrix[1][1])-(matrix[0][1]*matrix[1][0]);
minor=matrix_alloc(n-1);
for(i=0;i<n;i++)
{

     //kopiowanie macierzy do minor
	 for(x=1;x<n-1;x++)
     {
     	b=0;
     	for(y=0;y<n;y++)
     	{
     		if(y==i) continue;
     		minor[a][b]=matrix[x][y];
			b++; 	
		}
		a++;
	 }
     //koniec kopiowania.
     
    sum+=sign*matrix[0][i]*det(minor,n-1);puts("test3");
     sign = -sign;

}
matrix_free(minor, n);
return sum;
}

0

Co mówi debugger?
Luźnym strzałem powiedziałbym, że zmienna a wychodzi poza zakres.

0

"program received signal sigsegv, segmentation fault."

0
minor=matrix_alloc(n-1);
matrix_free(minor, n);

strzelam, że to błąd. Dorzuć definicję matrix_alloc i matrix_free a wszystko będzie jasne.

0
Złoty Terrorysta napisał(a):

"program received signal sigsegv, segmentation fault."

Jak nie wiesz, nie zgaduj.
Sprawdź w internecie, co to jest debugger i wykorzystaj go.

0

void matrix_free(double** matrix, int n)
{
int i;
for (i=0;i<n;i++)
{
free(matrix[i]);
}
free(matrix);
}

double** matrix_alloc(int n)
{
int i,j;
double matrix;
matrix=(double
)malloc(nsizeof(double ));
for(i=0;i<n;i++)
{
matrix[i]=(double
)malloc(n
sizeof(double));
}
return matrix;
}

0

Inicjujesz n-1 elementów, a zwalniasz n.
Po co zmienna j wewnątrz matrix_alloc?

0

minor=matrix_alloc(n-1); Alokujesz pamięć na n-1 elementów
for(y=0;y<n;y++) działasz na niej, jakby miała n elementów
matrix_free(minor, n); i zwalniasz n elementów

0

racja, zmienna j jest pozostalością po innych probach.
wywołuję teraz "matrix_free(minor, n-1);", ale niestety wciaz "program przestal dzialac"

0

No, to teraz użyj debuggera.

0

Przeczytaj jeszcze raz moją odpowiedź.

0

double det(double ** matrix, int n)
{
double** minor;
double sum=0.0;
double sign=1.0;
int i;
int x,y,a=0,b=0;
if(n==1) return matrix[0][0];
if(n==2) return (matrix[0][0]*matrix[1][1])-(matrix[0][1]*matrix[1][0]);
minor=matrix_alloc(n-1);
for(i=0;i<n;i++)
{

     //kopiowanie macierzy do minor
	 for(x=1;x<n-1;x++)
     {
     	b=0;
     	for(y=0;y<n-1;y++)
     	{
     		if(y==i) continue;
     		minor[a][b]=matrix[x][y];
			b++; 	
		}
		a++;
	 }
     //koniec kopiowania.
     
    sum+=sign*matrix[0][i]*det(minor,n-1);puts("test3");
     sign = -sign;

}
matrix_free(minor, n-1);
return sum;
}

zmienilem tez tak ze dziala na n-1 elementow, ale wciaz jest to samo. a debugger jest dla mnie czyms nowym nawet nie wiem jak to dziala ;/

0

Czekaj, czekaj, czekaj.
W jaki sposób wygodniej było Ci to przerobić, aby działało na n-1 elementach, zamiast po prostu alokować n elementów? :|

a debugger jest dla mnie czyms nowym nawet nie wiem jak to dziala ;/

Więc dzisiaj jest Twój szczęśliwy dzień.
Masz calutki internet wzdłuż i wszerz informacji o debuggerach.

0

tak jakos wyszlo :D
w kazdym razie robiac n-1 czy n, wciaz wyrzuca mi ten sam błąd.

0

Moja rada jest zawsze ta sama. Dziel rzeczy na mniejsze funkcje.

void matrix_copyMinor(const double**m, int size, int removeRow, int removeColumn, double **dest);

Popatrz ja to wtedy lepiej wygląda:

double det(double ** matrix, int n)
{
    if(n==1)
        return matrix[0][0];
    if(n==2)
        return (matrix[0][0]*matrix[1][1])-(matrix[0][1]*matrix[1][0]);

    assert(n>2);

    double sum=0.0;
    double sign=1.0;
    int i;
    double** minor = matrix_alloc(n-1);
    for(i=0;i<n;i++) {
         matrix_copyMinor(m, size, 0, i, minor);
         sum+= sign * matrix[0][i] * det(minor, size-1);
         sign = -sign;
    }
    matrix_free(minor, n-1);

    return sum;
}

Z tego co widzę to błąd masz właśnie w kodzie, który powinien być w matrix_copyMinor.
for(x=1;x<n-1;x++) jest źle bo efektywnie wycinasz pierwszy i ostatni wiersz.
for(y=0;y<n-1;y++) też jest źle bo wycinasz ostatni i ity wiersz i na dodatek, w wyniku pod itą kolumną nie ma sensownej wartości (jest śmieć).

Te dwie pętle for, podziel na dwie części! Na to przed wyciętym wierszem/kolumną i na to po wyciętym wierszu/kolumnie

1 użytkowników online, w tym zalogowanych: 0, gości: 1