Mastering Matrix Operations in C: Addition and Multiplication
Matrices are fundamental mathematical objects that find extensive use in various fields, from computer graphics and image processing to scientific computing, statistics, and machine learning. In C programming, understanding how to perform basic matrix operations like addition and multiplication is a crucial skill. This guide, part of our C Language Series, will walk you through representing matrices in C, and implementing both matrix addition and multiplication with clear explanations and practical code examples.
Representing Matrices in C
In C, matrices are typically represented using two-dimensional arrays. A 2D array can be thought of as an array of arrays, where the first index refers to the row and the second index refers to the column.
For instance, a matrix with M rows and N columns can be declared as:
int matrix[M][N];
For our examples, we'll use predefined maximum dimensions for simplicity, or we'll pass dimensions to functions. Let's define some constants:
#define MAX_ROWS 10
#define MAX_COLS 10
Matrix Addition in C
Matrix addition is one of the simplest matrix operations. To add two matrices, they must have the same number of rows and columns. The result is a new matrix where each element is the sum of the corresponding elements from the two input matrices.
If you have two matrices A and B, each of size m x n, their sum C (also m x n) is calculated as:
C[i][j] = A[i][j] + B[i][j]
Where i ranges from 0 to m-1 and j ranges from 0 to n-1.
Algorithm for Matrix Addition
- Check if the dimensions of the two matrices are compatible (same number of rows and columns). If not, addition is not possible.
- Create a new matrix to store the sum, with the same dimensions.
- Use nested loops to iterate through each element (
ifor rows,jfor columns). - For each element
(i, j), addA[i][j]andB[i][j]and store the result inSum[i][j].
C Code Example: Matrix Addition
#include <stdio.h>
// Assuming MAX_ROWS and MAX_COLS are defined or passed dynamically
#define MAX_ROWS 3
#define MAX_COLS 3
// Function to add two matrices
void addMatrices(int A[][MAX_COLS], int B[][MAX_COLS], int Sum[][MAX_COLS], int rows, int cols) {
printf("\nPerforming Matrix Addition...\n");
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
Sum[i][j] = A[i][j] + B[i][j];
}
}
}
// Function to display a matrix
void displayMatrix(int matrix[][MAX_COLS], int rows, int cols, const char* name) {
printf("\n%s Matrix:\n", name);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%4d ", matrix[i][j]);
}
printf("\n");
}
}
int main() {
int mat1[MAX_ROWS][MAX_COLS] = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
int mat2[MAX_ROWS][MAX_COLS] = {
{9, 8, 7},
{6, 5, 4},
{3, 2, 1}
};
int sumMatrix[MAX_ROWS][MAX_COLS];
int rows = 3;
int cols = 3;
displayMatrix(mat1, rows, cols, "Matrix A");
displayMatrix(mat2, rows, cols, "Matrix B");
// Add matrices
addMatrices(mat1, mat2, sumMatrix, rows, cols);
displayMatrix(sumMatrix, rows, cols, "Sum");
return 0;
}
In the addMatrices function, we iterate through each position (i, j) using two nested loops. The element at A[i][j] is added to B[i][j] and the result is stored in the corresponding position of Sum[i][j].
Matrix Multiplication in C
Matrix multiplication is a bit more complex than addition. For two matrices A and B to be multiplied, the number of columns in the first matrix (A) must be equal to the number of rows in the second matrix (B).
- If
Ais anm x nmatrix (mrows,ncolumns) - And
Bis ann x pmatrix (nrows,pcolumns) - Then their product
C = A * Bwill be anm x pmatrix.
Each element C[i][j] of the product matrix is obtained by taking the dot product of the i-th row of A and the j-th column of B. This involves summing the products of corresponding elements.
C[i][j] = Σ (A[i][k] * B[k][j]) for k from 0 to n-1
Algorithm for Matrix Multiplication
- Check if the number of columns in the first matrix equals the number of rows in the second matrix. If not, multiplication is not possible.
- Create a new matrix to store the product. Its dimensions will be (rows of A) x (columns of B). Initialize all elements of this product matrix to 0.
- Use three nested loops:
- The outer loop (
i) iterates through rows ofA(andProduct). - The middle loop (
j) iterates through columns ofB(andProduct). - The innermost loop (
k) iterates through columns ofA(and rows ofB), performing the sum of products.
- The outer loop (
- Inside the innermost loop, update
Product[i][j] += A[i][k] * B[k][j].
C Code Example: Matrix Multiplication
#include <stdio.h>
// Assuming MAX_DIM is a sufficiently large value for rows/cols
#define MAX_DIM 10
// Function to multiply two matrices
// r1, c1: dimensions of matrix A
// r2, c2: dimensions of matrix B
void multiplyMatrices(int A[][MAX_DIM], int B[][MAX_DIM], int Product[][MAX_DIM], int r1, int c1, int r2, int c2) {
// Check compatibility for multiplication
if (c1 != r2) {
printf("\nError: Matrices cannot be multiplied!");
printf(" Number of columns of A (%d) must be equal to number of rows of B (%d).\n", c1, r2);
return;
}
printf("\nPerforming Matrix Multiplication...\n");
// Initialize product matrix with zeros
for (int i = 0; i < r1; i++) {
for (int j = 0; j < c2; j++) {
Product[i][j] = 0;
}
}
// Actual multiplication
for (int i = 0; i < r1; i++) { // Iterate through rows of A
for (int j = 0; j < c2; j++) { // Iterate through columns of B
for (int k = 0; k < c1; k++) { // Iterate through columns of A / rows of B
Product[i][j] += A[i][k] * B[k][j];
}
}
}
}
// Function to display a matrix (re-using from addition example)
void displayMatrix(int matrix[][MAX_DIM], int rows, int cols, const char* name) {
printf("\n%s Matrix (%dx%d):\n", name, rows, cols);
for (int i = 0; i < rows; i++) {
for (int j = 0; j < cols; j++) {
printf("%5d ", matrix[i][j]);
}
printf("\n");
}
}
int main() {
int matA[MAX_DIM][MAX_DIM] = {
{1, 2, 3},
{4, 5, 6}
};
int rA = 2, cA = 3; // Matrix A is 2x3
int matB[MAX_DIM][MAX_DIM] = {
{7, 8},
{9, 1},
{2, 3}
};
int rB = 3, cB = 2; // Matrix B is 3x2
int productMatrix[MAX_DIM][MAX_DIM]; // Result will be 2x2
displayMatrix(matA, rA, cA, "Matrix A");
displayMatrix(matB, rB, cB, "Matrix B");
// Multiply matrices
multiplyMatrices(matA, matB, productMatrix, rA, cA, rB, cB);
// Only display if multiplication was successful
if (cA == rB) {
displayMatrix(productMatrix, rA, cB, "Product");
}
// Example of incompatible matrices for multiplication
printf("\n--- Trying incompatible multiplication ---\n");
int matC[MAX_DIM][MAX_DIM] = {{1,2},{3,4}}; // 2x2
int rC = 2, cC = 2;
int matD[MAX_DIM][MAX_DIM] = {{5},{6},{7}}; // 3x1
int rD = 3, cD = 1;
displayMatrix(matC, rC, cC, "Matrix C");
displayMatrix(matD, rD, cD, "Matrix D");
multiplyMatrices(matC, matD, productMatrix, rC, cC, rD, cD); // This will show an error
return 0;
}
The multiplyMatrices function first checks if the matrices are compatible. If they are, it initializes the Product matrix to all zeros. The three nested loops then perform the core multiplication: the outer two loops determine the position (i, j) in the result matrix, and the innermost loop sums the products of elements from the i-th row of A and j-th column of B.
Important Considerations
- Dimension Checking: Always include checks for matrix compatibility (dimensions) before performing operations. This prevents errors and crashes.
-
Fixed vs. Dynamic Sizing: In these examples, we used fixed-size 2D arrays (
MAX_ROWS,MAX_COLS). For more flexible applications where matrix sizes are determined at runtime, you would typically use dynamic memory allocation with pointers to pointers (int** matrix) or a single pointer to a contiguous block of memory. This is a more advanced topic but essential for real-world scenarios. -
Passing 2D Arrays to Functions: When passing a 2D array to a function in C, you must specify the number of columns for all dimensions except the first. For example,
int matrix[][MAX_COLS]orint matrix[ROWS][MAX_COLS]. If you are using dynamic allocation, you would passint** matrixalong with its dimensions. - Efficiency: For very large matrices, the naive O(n³) multiplication algorithm used here can be slow. More advanced algorithms like Strassen's algorithm or specialized libraries (e.g., BLAS - Basic Linear Algebra Subprograms) offer better performance.
Conclusion
Matrix addition and multiplication are fundamental operations in linear algebra and computing. By using two-dimensional arrays in C, along with careful implementation of nested loops and dimension checks, you can effectively perform these operations. Understanding these basics is a stepping stone to tackling more complex matrix manipulations and diving deeper into fields like computer graphics, scientific simulations, and machine learning.
Practice these examples, experiment with different matrix sizes and values, and consider how you might extend these functions to handle dynamic matrix sizes using pointers.