Warm tip: This article is reproduced from stackoverflow.com, please click
c pointers recursion

determinant program not working correctly

发布于 2020-04-03 23:37:08

i wrote a program to find the determinant of a n by n matrix using recursion(laplace theorem) .

they are three functions

1)determinant() to find the determinant of n*n matrix

2)create() to dynamically allocate a n*n array

3)copy() to create n-1*n-1 minor of n*n array

#include<stdio.h>
#include<stdlib.h>
#include<math.h>
int determinant(int **a,int size,int noentry);// find determinant using recursion
int copy(int **b,int **a,int size,int noentry);//copy elements to minor
int **create(int size); // dynamically allocate a two dimensional array
 int main()
{
 int **a,size,i,j,y;
 printf("enter the order of the determinant \n");
 scanf("%d",&size);
 a=create(size);
 printf("enter your elements \n");
 for(i=0;i<size;i++)
{
    for(j=0;j<size;j++)
    {
        scanf("%d",&a[i][j]);
    }
 }
y=determinant(a,size,0);
printf("the determinant is %d \n",y);
 return 0;
}
int  determinant(int **a,int size,int noentry)
{
int i;
static int det=0;
if(size<=2)
    return a[0][0]*a[1][1]-a[0][1]*a[1][0];
else
{
    for(i=0;i<size;i++)
    {

        int **b;
        b=create(size-1);
        copy(b,a,size-1,i);
        det= det+pow(-1,i)*a[0][i]*determinant(b,size-1,i);
    }
    return det;
 }
}
int copy(int **b,int **a,int size,int noentry)
{
 int i,j,k;
 for(i=1;i<=size;i++)
{
    k=0;
    for(j=0;j<=size;j++)
    {
        if(j==noentry)
            continue;
        else
        {
            b[i-1][k]=a[i][j];
            k++;
        }
    }
}
return size;
}
int **create(int size)
{
 int **b;
 if(size<=0)
 {
    printf("the size cannot be negative/null \n");
    return NULL;
}
int i;
printf("entered the create function \n");
b=(int **)malloc(sizeof(int *)*size);
for(i=0;i<size;i++)
    b[i]=(int *)malloc(size*sizeof(int));
return b;
}

the program is working correctly for 3 by 3 matrix but no for 4 by 4 matrix i can't spot the error.

Questioner
kapil
Viewed
54
Serge Ballesta 2015-12-04 21:33

First, you never free allocated bloc which is bad. You should create a destroy method to free a previously allocated matrix and call it once per create call.

Next, you pass an unused noentry parameter to determinant. It should just be: int determinant(int **a,int size);

But the cause of your error is that in determinant method, det variable is static. As you recurse in determinant, each new invocation should have its own det copy instead or sharing the same one.

TL/DR: just remove the static qualifier for det variable in determinant function.

Last advice: debugging would be easier if you allocated your matrices... matrix wise!

int **create(int size)
{
    int i;
    int **b;
    if(size<=0)
    {
        printf("the size cannot be negative/null \n");
        return NULL;
    }
    printf("entered the create function \n");
    b=(int **)malloc(sizeof(int *)*size);
    b[0]=(int *)malloc(size * size*sizeof(int));
    for(i=1;i<size;i++)
        b[i]=b[0] + i * size;
    return b;
}
void destroy(int **a) {
    free(a[0]);
    free(a);
}

That way the whole matrix uses contiguous memory to allow to see its content easily in a debugger by watching at size² integers starting at a[0]. And as a side effect, the destroy function is damned simple.

Just to be exhaustive, the fixed determinant function becomes:

int  determinant(int **a,int size)
{
    int i;
    int det=0;
    int m1 = 1;
    if(size<=2)
        return a[0][0]*a[1][1]-a[0][1]*a[1][0];
    else
    {
        for(i=0;i<size;i++)
        {

            int **b;
            b=create(size-1);
            copy(b,a,size-1,i);
            det= det+m1*a[0][i]*determinant(b,size-1);
            destroy(b);
            m1 = - m1;
        }
        return det;
    }
}