Determinant Calculation in C
Determinant Calculation in C

Determinant Calculation in C

Learn how to calculate the determinant of a matrix in C using multiple methods, including the recursive Laplace expansion, LU decomposition, and matrix manipulation. Understand the underlying algorithms and their implementation.

Introduction:

The determinant of a matrix is a scalar value that can be computed from its elements and encapsulates important properties of the matrix. This guide covers multiple methods to calculate the determinant of a matrix in C.

Method 1: Laplace Expansion (Recursive)

Algorithm:

Python
Step 1: Start
Step 2: Input: A square matrix A and its size n.

Step 3: Process:

        (i) If n is 1, return the single element.
        (ii) Initialize det to 0.

        (iii) For each element in the first row:
              (a) Create a submatrix by excluding the current row and 
                  column.
              (b) Recursively calculate the determinant of the submatrix.
              (c) Add the product of the element, its cofactor, and the 
                  determinant of the submatrix to det.

Step 4: Output: Return det.
Step 5: Exit

Pseudocode:

LESS
function determinant_laplace(A, n):
    if n == 1:
        return A[0][0]
    
    det = 0
    for each element A[0][j] in the first row:
        submatrix = get_submatrix(A, 0, j, n)
        det += (-1)^j * A[0][j] * determinant_laplace(submatrix, n-1)
    
    return det

C Implementation:

C
#include <stdio.h>
#include <stdlib.h>

void get_submatrix(int **matrix, int **submatrix, int row, int col, int n) {
    int subi = 0;
    for (int i = 1; i < n; i++) {
        int subj = 0;
        for (int j = 0; j < n; j++) {
            if (j == col) continue;
            submatrix[subi][subj] = matrix[i][j];
            subj++;
        }
        subi++;
    }
}

int determinant_laplace(int **matrix, int n) {
    if (n == 1) return matrix[0][0];

    int det = 0;
    for (int col = 0; col < n; col++) {
        int **submatrix = (int **)malloc((n - 1) * sizeof(int *));
        for (int i = 0; i < n - 1; i++) {
            submatrix[i] = (int *)malloc((n - 1) * sizeof(int));
        }

        get_submatrix(matrix, submatrix, 0, col, n);
        det += (col % 2 == 0 ? 1 : -1) * matrix[0][col] * determinant_laplace(submatrix, n - 1);

        for (int i = 0; i < n - 1; i++) {
            free(submatrix[i]);
        }
        free(submatrix);
    }

    return det;
}

int main() {
    int n = 3;
    int **matrix = (int **)malloc(n * sizeof(int *));
    for (int i = 0; i < n; i++) {
        matrix[i] = (int *)malloc(n * sizeof(int));
    }

    matrix[0][0] = 1; matrix[0][1] = 2; matrix[0][2] = 3;
    matrix[1][0] = 4; matrix[1][1] = 5; matrix[1][2] = 6;
    matrix[2][0] = 7; matrix[2][1] = 8; matrix[2][2] = 9;

    printf("Determinant (Laplace Expansion): %d\n", determinant_laplace(matrix, n));

    for (int i = 0; i < n; i++) {
        free(matrix[i]);
    }
    free(matrix);

    return 0;
}

Step-by-Step Explanation:

  • Function get_submatrix:
    • Removes the specified row and column from the matrix to create a submatrix.

  • Function determinant_laplace:
    • Handles the base case for 1×1 matrices.
    • Iterates over the first row, calculating the determinant recursively for submatrices.
    • Uses the cofactor expansion to sum the determinants of submatrices.

Method 2: LU Decomposition

Algorithm:

C
Step 1: Start
Step 2: Input: A square matrix A and its size n.

Step 3: Process:
        (i) Perform LU decomposition on A to get matrices L and U.
        (ii) Calculate the determinant as the product of the diagonal 
             elements of U.

Step 4: Output: Return the determinant.
Step 5: Exit

Pseudocode:

C
function determinant_lu(A, n):
    L, U = lu_decomposition(A, n)
    det = product of diagonal elements of U
    return det

C Implementation:

C
#include <stdio.h>
#include <stdlib.h>
#include <math.h>

void lu_decomposition(double **matrix, double **L, double **U, int n) {
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            if (j < i)
                L[j][i] = 0;
            else {
                L[j][i] = matrix[j][i];
                for (int k = 0; k < i; k++) {
                    L[j][i] = L[j][i] - L[j][k] * U[k][i];
                }
            }
        }
        for (int j = 0; j < n; j++) {
            if (j < i)
                U[i][j] = 0;
            else if (j == i)
                U[i][j] = 1;
            else {
                U[i][j] = matrix[i][j] / L[i][i];
                for (int k = 0; k < i; k++) {
                    U[i][j] = U[i][j] - ((L[i][k] * U[k][j]) / L[i][i]);
                }
            }
        }
    }
}

double determinant_lu(double **matrix, int n) {
    double **L = (double **)malloc(n * sizeof(double *));
    double **U = (double **)malloc(n * sizeof(double *));
    for (int i = 0; i < n; i++) {
        L[i] = (double *)malloc(n * sizeof(double));
        U[i] = (double *)malloc(n * sizeof(double));
    }

    lu_decomposition(matrix, L, U, n);

    double det = 1;
    for (int i = 0; i < n; i++) {
        det *= L[i][i];
    }

    for (int i = 0; i < n; i++) {
        free(L[i]);
        free(U[i]);
    }
    free(L);
    free(U);

    return det;
}

int main() {
    int n = 3;
    double **matrix = (double **)malloc(n * sizeof(double *));
    for (int i = 0; i < n; i++) {
        matrix[i] = (double *)malloc(n * sizeof(double));
    }

    matrix[0][0] = 1; matrix[0][1] = 2; matrix[0][2] = 3;
    matrix[1][0] = 4; matrix[1][1] = 5; matrix[1][2] = 6;
    matrix[2][0] = 7; matrix[2][1] = 8; matrix[2][2] = 9;

    printf("Determinant (LU Decomposition): %f\n", determinant_lu(matrix, n));

    for (int i = 0; i < n; i++) {
        free(matrix[i]);
    }
    free(matrix);

    return 0;
}

Step-by-Step Explanation:

  • LU Decomposition:
    • Decomposes matrix A into lower triangular matrix L and upper triangular matrix U.

  • Determinant Calculation:
    • The determinant of A is the product of the diagonal elements of L.

Summary

The determinant of a matrix is a fundamental concept in linear algebra with applications in various mathematical and engineering fields. In C programming, we can calculate the determinant using different methods, each suitable for different scenarios. Here, we explored two primary methods: Laplace expansion (recursive) and LU decomposition.

Method 1: Laplace Expansion (Recursive)

  • Purpose: Calculate the determinant of a matrix using cofactor expansion.
  • Complexity: O(n!), where n is the size of the matrix. This makes it inefficient for large matrices due to its exponential time complexity.
  • Steps:
    • Base case: If the matrix is 1×1, return the single element.
    • For each element in the first row, create a submatrix by excluding the current row and column.
    • Recursively calculate the determinant of the submatrix.
    • Sum the products of each element, its cofactor, and the determinant of the submatrix.
  • Use Case: Educational purposes and small matrices due to its simplicity and ease of understanding.

Method 2: LU Decomposition

  • Purpose: Efficiently calculate the determinant by decomposing the matrix into lower (L) and upper (U) triangular matrices.
  • Complexity: O(n^3), making it more suitable for larger matrices compared to Laplace expansion.
  • Steps:
    • Decompose the matrix A into lower (L) and upper (U) triangular matrices using LU decomposition.
    • Calculate the determinant as the product of the diagonal elements of the lower triangular matrix L.
  • Use Case: Practical applications requiring efficient computation, especially for larger matrices.

Each method has its own advantages and is suitable for different scenarios:

  1. Laplace Expansion:
    • Pros: Simple to understand and implement; useful for educational purposes.
    • Cons: Inefficient for large matrices due to exponential time complexity.
  2. LU Decomposition:
    • Pros: Efficient for larger matrices with polynomial time complexity.
    • Cons: More complex to implement than Laplace expansion.

For practical applications involving large matrices, LU decomposition is recommended due to its efficiency. Laplace expansion, while not suitable for large matrices, serves as a valuable educational tool for understanding the concept of determinants and cofactor expansion.


Discover more from lounge coder

Subscribe to get the latest posts sent to your email.

Leave a Reply

Your email address will not be published. Required fields are marked *

Discover more from lounge coder

Subscribe now to keep reading and get access to the full archive.

Continue reading