Search code examples
crecursionmatrixdeterminants

how to compute the determinant of a Matrix in C using recursive functions


Hello I was trying to make a C program that calculate the determinant of a given matrix. I somewhat completed it but I got stuck when I was trying to make a function that finds the sub matrix of a given matrix and a component. I commented as clearly as I could in each part but I believe the main problem with the program is the last method subMatrix.If you could help me fix it or present an alternative solution i would really appreciate it.
PS :I know some part of the code or comments might not be clear ,so feel free to ask me any questions in the comments.

#define MAX 10000
    //here I was trying to make a "matrix" type to be able to return values in the function "subMatrix"
    struct Matrix
    {
        double a[MAX][MAX];
    };


    struct Matrix subMatrix(int n, double m[n][n], int I, int J);
    double determinant(int n, double M[n][n]);


    int main()
    {
        int n, k = 0;
        printf("how many rows does the matrix have"); 
        scanf("%d", &n);
        double Matrix[n][n];
        double temp[n * n];
        printf("enter the numbers in order with an enter after each one");
        //gathering all the data from the user
        for (int i = 0; i < n * n; i++)
        {
            scanf("%d", temp[i]);
        }
        //sorting the data into a matrix
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                Matrix[i][j] = temp[k];
                k++;
            }
        }
        //prints the determinant
        printf("%d",determinant(n,Matrix));

        return 0;
    }
    //this recursive function calculates the determinant 
    double determinant(int n, double M[n][n])
    {
        double det = 0;
        //the functions continues to call its self until n=2
        if (n == 2)
        {
            det = M[0][0] *M[1][1]-M[0][1]*M[1][0];
        }
        else
        {
            for (int i = 0; i < n; i++)
            {
                det += M[0][i] * determinant(n - 1, subMatrix(n, M, 0, i));
            }
        }



        return det;
    }
    //here I tried to make the subMatrix of a given matrix and one of its components
    //by sub matrix I mean the matrix that doesn't include the row and columns that are in line with one of the matrix componants
    struct Matrix subMatrix(int n, double m[n][n], int I, int J)
    {
        int i, a = 0, b = 0;
        int j;
        struct Matrix M[n - 1][n - 1];
        for (i = 0; i < n; i++)
        {
            if (i != I)
            {
                for (j = 0; j < n; j++)
                {
                    if (J != j)
                    {
                        M[a][b] = m[i][j];
                        b++;
                    }
                }
                a++;
            }
        }
        return M;
    }

Solution

  • There are multiple issues with your code,

    1. subMatrix is returning pointer of struct Matrix but expected to be just a struct Matrix
    2. In subMatrixvalue of b is incremented and not reset on new row.
    3. Argument for determinant expects double M[n][n]but passing struct Matrix in recursive call
    4. redundant use of local variable temp[n * n]
    5. wrong behavior on input n=1

    Simple solution to get 2D array back from subMatrix is to pass the reference of 2D array and fill the required value inside the function.

    I tried to simply the clutter as follows,

    void subMatrix(int n, double m[n][n], int I, int J,double M[n-1][n-1])
    {
        int i, a = 0, b = 0;
        int j;
        for (i = 0; i < n; i++)
        {
            if (i == I)
            {
                continue;
            }
    
            b = 0;//in-order to start fresh for new row
            for (j = 0; j < n; j++)
            {
                if (J == j)
                {
                    continue;
                }
                M[a][b] = m[i][j];
                b++;
            }
            a++;
        }
    }
    
    //this recursive function calculates the determinant 
    double  determinant(int n, double M[n][n])
    {
        double det = 0;
        //the functions continues to call its self until n=2
        if(n==1)
        {
            return M[0][0];
        }
        if (n == 2)
        {
            det = M[0][0] *M[1][1]-M[0][1]*M[1][0];
        }
        else
        {
            double subArray[n-1][n-1];
            for (int i = 0; i < n; i++)
            {
                //subMatrix is filling the subArray
                subMatrix(n,M,0,i,subArray);
                det += M[0][i] * ((i&1)?-1:1)*determinant(n - 1,subArray);
            }
        }
        return det;
    }
    
    int main()
    {
        int n, k = 0;
    
        printf("how many rows does the matrix have"); 
        scanf("%d", &n);
    
        double Matrix[n][n];
        printf("enter the numbers in order with an enter after each one");
    
       //Taking user input for 2D array
        for (int i = 0; i < n; i++)
        {
            for (int j = 0; j < n; j++)
            {
                scanf("%lf", &Matrix[i][j]);
            }
        }
    
        printf("%f",determinant(n,Matrix));
        return 0;
    }