Compute the Inverse of a Matrix in C

CCBeginner
Practice Now

Introduction

In this lab, we will learn how to compute the inverse of a square matrix in C programming. The lab covers the following steps: reading a square matrix from user input, using the adjoint and determinant method to compute the inverse matrix, and printing the resulting inverse matrix. The goal is to provide a practical understanding of matrix operations and their implementation in C, which are fundamental concepts in linear algebra and have various applications in fields such as data analysis, image processing, and scientific computing.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL c(("`C`")) -.-> c/UserInteractionGroup(["`User Interaction`"]) c(("`C`")) -.-> c/ControlFlowGroup(["`Control Flow`"]) c(("`C`")) -.-> c/CompoundTypesGroup(["`Compound Types`"]) c(("`C`")) -.-> c/FunctionsGroup(["`Functions`"]) c/UserInteractionGroup -.-> c/output("`Output`") c/ControlFlowGroup -.-> c/for_loop("`For Loop`") c/CompoundTypesGroup -.-> c/arrays("`Arrays`") c/FunctionsGroup -.-> c/math_functions("`Math Functions`") subgraph Lab Skills c/output -.-> lab-435161{{"`Compute the Inverse of a Matrix in C`"}} c/for_loop -.-> lab-435161{{"`Compute the Inverse of a Matrix in C`"}} c/arrays -.-> lab-435161{{"`Compute the Inverse of a Matrix in C`"}} c/math_functions -.-> lab-435161{{"`Compute the Inverse of a Matrix in C`"}} end

Read a Square Matrix

In this step, we will learn how to read a square matrix in C programming. A square matrix is a matrix with an equal number of rows and columns.

First, let's create a C program to read a square matrix from user input:

#include <stdio.h>
#define MAX_SIZE 10

void readMatrix(int matrix[MAX_SIZE][MAX_SIZE], int size) {
    printf("Enter the elements of the %dx%d matrix:\n", size, size);
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            printf("Enter element [%d][%d]: ", i, j);
            scanf("%d", &matrix[i][j]);
        }
    }
}

int main() {
    int matrix[MAX_SIZE][MAX_SIZE];
    int size;

    printf("Enter the size of the square matrix (max %d): ", MAX_SIZE);
    scanf("%d", &size);

    if (size <= 0 || size > MAX_SIZE) {
        printf("Invalid matrix size!\n");
        return 1;
    }

    readMatrix(matrix, size);

    // Print the matrix to verify input
    printf("\nEntered Matrix:\n");
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }

    return 0;
}

Example output:

Enter the size of the square matrix (max 10): 3
Enter the elements of the 3x3 matrix:
Enter element [0][0]: 1
Enter element [0][1]: 2
Enter element [0][2]: 3
Enter element [1][0]: 4
Enter element [1][1]: 5
Enter element [1][2]: 6
Enter element [2][0]: 7
Enter element [2][1]: 8
Enter element [2][2]: 9

Entered Matrix:
1 2 3
4 5 6
7 8 9

Let's break down the code:

  1. We define a maximum matrix size of 10 using #define MAX_SIZE 10.
  2. The readMatrix() function takes a 2D array and its size as parameters.
  3. We use nested loops to read matrix elements from user input.
  4. In main(), we first get the matrix size from the user.
  5. We validate the matrix size to ensure it's within the allowed range.
  6. After reading the matrix, we print it to verify the input.

Now, let's save and compile the program:

cd ~/project
nano matrix_input.c
## Copy the above code into the file
gcc matrix_input.c -o matrix_input
./matrix_input

Use Adjoint and Determinant Method

In this step, we will implement the matrix inversion method using the adjoint and determinant approach. We'll extend the previous matrix input program to calculate the matrix inverse.

First, let's add functions to calculate the determinant and adjoint of a matrix:

#include <stdio.h>
#define MAX_SIZE 10

// Function to get cofactor of matrix
void getCofactor(int matrix[MAX_SIZE][MAX_SIZE], int temp[MAX_SIZE][MAX_SIZE],
                 int p, int q, int n) {
    int i = 0, j = 0;

    for (int row = 0; row < n; row++) {
        for (int col = 0; col < n; col++) {
            if (row != p && col != q) {
                temp[i][j++] = matrix[row][col];

                if (j == n - 1) {
                    j = 0;
                    i++;
                }
            }
        }
    }
}

// Recursive function to calculate determinant
int determinant(int matrix[MAX_SIZE][MAX_SIZE], int n) {
    if (n == 1)
        return matrix[0][0];

    int det = 0;
    int sign = 1;
    int temp[MAX_SIZE][MAX_SIZE];

    for (int f = 0; f < n; f++) {
        getCofactor(matrix, temp, 0, f, n);
        det += sign * matrix[0][f] * determinant(temp, n - 1);
        sign = -sign;
    }

    return det;
}

// Function to calculate adjoint matrix
void adjoint(int matrix[MAX_SIZE][MAX_SIZE], int adj[MAX_SIZE][MAX_SIZE], int n) {
    if (n == 1) {
        adj[0][0] = 1;
        return;
    }

    int sign = 1;
    int temp[MAX_SIZE][MAX_SIZE];

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            getCofactor(matrix, temp, i, j, n);

            sign = ((i + j) % 2 == 0) ? 1 : -1;

            adj[j][i] = sign * determinant(temp, n - 1);
        }
    }
}

// Function to calculate inverse matrix
int inverse(int matrix[MAX_SIZE][MAX_SIZE], float inverse[MAX_SIZE][MAX_SIZE], int n) {
    int det = determinant(matrix, n);

    if (det == 0) {
        printf("Inverse does not exist (determinant is zero).\n");
        return 0;
    }

    int adj[MAX_SIZE][MAX_SIZE];
    adjoint(matrix, adj, n);

    for (int i = 0; i < n; i++) {
        for (int j = 0; j < n; j++) {
            inverse[i][j] = (float)adj[i][j] / det;
        }
    }

    return 1;
}

// Previous readMatrix function from the first step
void readMatrix(int matrix[MAX_SIZE][MAX_SIZE], int size) {
    printf("Enter the elements of the %dx%d matrix:\n", size, size);
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            printf("Enter element [%d][%d]: ", i, j);
            scanf("%d", &matrix[i][j]);
        }
    }
}

int main() {
    int matrix[MAX_SIZE][MAX_SIZE];
    float inv[MAX_SIZE][MAX_SIZE];
    int size;

    printf("Enter the size of the square matrix (max %d): ", MAX_SIZE);
    scanf("%d", &size);

    if (size <= 0 || size > MAX_SIZE) {
        printf("Invalid matrix size!\n");
        return 1;
    }

    readMatrix(matrix, size);

    // Calculate and print inverse matrix
    if (inverse(matrix, inv, size)) {
        printf("\nInverse Matrix:\n");
        for (int i = 0; i < size; i++) {
            for (int j = 0; j < size; j++) {
                printf("%.2f ", inv[i][j]);
            }
            printf("\n");
        }
    }

    return 0;
}

Example output:

Enter the size of the square matrix (max 10): 3
Enter the elements of the 3x3 matrix:
Enter element [0][0]: 1
Enter element [0][1]: 2
Enter element [0][2]: 3
Enter element [1][0]: 0
Enter element [1][1]: 1
Enter element [1][2]: 4
Enter element [2][0]: 1
Enter element [2][1]: 0
Enter element [2][2]: 1

Inverse Matrix:
-2.00 1.00 1.00
2.00 -1.00 -1.00
0.00 1.00 0.00

Let's compile and run the program:

cd ~/project
gcc matrix_inverse.c -o matrix_inverse
./matrix_inverse

Key points about the matrix inversion method:

  1. We use the adjoint method to calculate the matrix inverse.
  2. The determinant is calculated recursively.
  3. The inverse is calculated by dividing the adjoint matrix by the determinant.
  4. If the determinant is zero, the matrix is not invertible.

Print the Inverse Matrix

In this step, we will enhance our matrix inversion program to provide more detailed and formatted output of the inverse matrix. We'll create a function to print the matrix with improved readability and add error handling.

Let's modify our previous program to include a dedicated matrix printing function:

#include <stdio.h>
#include <stdlib.h>
#define MAX_SIZE 10
#define PRECISION 4

// Previous functions (determinant, adjoint, inverse) remain the same as in the previous step

// New function to print matrix with formatted output
void printMatrix(float matrix[MAX_SIZE][MAX_SIZE], int size, const char* title) {
    printf("%s:\n", title);
    printf("Matrix Dimensions: %dx%d\n", size, size);
    printf("------------------------------\n");

    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            // Use scientific notation for very small or large numbers
            if (abs(matrix[i][j]) < 0.0001 || abs(matrix[i][j]) > 1000) {
                printf("%10.4e ", matrix[i][j]);
            } else {
                printf("%10.4f ", matrix[i][j]);
            }
        }
        printf("\n");
    }
    printf("------------------------------\n");
}

// Previous readMatrix function
void readMatrix(int matrix[MAX_SIZE][MAX_SIZE], int size) {
    printf("Enter the elements of the %dx%d matrix:\n", size, size);
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            printf("Enter element [%d][%d]: ", i, j);
            scanf("%d", &matrix[i][j]);
        }
    }
}

int main() {
    int matrix[MAX_SIZE][MAX_SIZE];
    float inv[MAX_SIZE][MAX_SIZE];
    int size;

    printf("Matrix Inverse Calculator\n");
    printf("========================\n");

    printf("Enter the size of the square matrix (max %d): ", MAX_SIZE);
    scanf("%d", &size);

    if (size <= 0 || size > MAX_SIZE) {
        printf("Error: Invalid matrix size!\n");
        return 1;
    }

    // Read original matrix
    readMatrix(matrix, size);

    // Print original matrix
    int originalMatrix[MAX_SIZE][MAX_SIZE];
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            originalMatrix[i][j] = matrix[i][j];
        }
    }

    // Convert original matrix to float for printing
    float originalMatrixFloat[MAX_SIZE][MAX_SIZE];
    for (int i = 0; i < size; i++) {
        for (int j = 0; j < size; j++) {
            originalMatrixFloat[i][j] = originalMatrix[i][j];
        }
    }

    printMatrix(originalMatrixFloat, size, "Original Matrix");

    // Calculate and print inverse matrix
    if (inverse(matrix, inv, size)) {
        printMatrix(inv, size, "Inverse Matrix");
    } else {
        printf("Error: Matrix is not invertible!\n");
        return 1;
    }

    return 0;
}

Example output:

Matrix Inverse Calculator
========================
Enter the size of the square matrix (max 10): 3
Enter the elements of the 3x3 matrix:
Enter element [0][0]: 4
Enter element [0][1]: 7
Enter element [0][2]: 2
Enter element [1][0]: 2
Enter element [1][1]: 6
Enter element [1][2]: 9
Enter element [2][0]: 3
Enter element [2][1]: 1
Enter element [2][2]: 8

Original Matrix:
------------------------------
         4         7         2
         2         6         9
         3         1         8
------------------------------

Inverse Matrix:
------------------------------
    -0.4286     0.2857     0.1429
     0.1429    -0.2857     0.1429
     0.1429     0.1429    -0.1429
------------------------------

Let's compile and run the program:

cd ~/project
gcc matrix_inverse_print.c -o matrix_inverse_print
./matrix_inverse_print

Key improvements in this step:

  1. Added a dedicated printMatrix() function
  2. Improved matrix output formatting
  3. Added error handling for matrix inversion
  4. Display matrix dimensions
  5. Use scientific notation for very small or large numbers

Summary

In this lab, we first learned how to read a square matrix from user input in C programming. We created a function called readMatrix() that takes a 2D array and its size as parameters, and used nested loops to read the matrix elements. We then validated the matrix size to ensure it's within the allowed range, and printed the entered matrix to verify the input.

Next, we will learn how to compute the inverse of a matrix using the adjoint and determinant method, and how to print the inverse matrix.

Other C Tutorials you may like