Back

Sparse Matrix in Data Structures: Overview, its Types & Examples

13 Dec 2024
7 min read

A sparse matrix contains most of the elements that are zero. These matrices arise in various real-world applications, particularly with large datasets. Sparse matrices are commonly used in areas like machine learning, data science, and graph theory, where data sets contain many zero values, making them ideal for compression and efficient storage. In this article, we will explore sparse matrices in data structures with examples.

What is a Sparse Matrix in Data Structure?

A sparse matrix in which most of its elements are zero. It is characterized by a small number of non-zero elements compared to the total number of elements (mxn). In other words, a sparse matrix has a significant proportion of zero values, often exceeding half of the total elements.

Given m and n, a sparse matrix of size mxn can be defined as follows:

  • m: The number of rows
  • n: The number of columns 

For example, consider the following 4x4 matrix:

0 0 0 1
0 0 0 0
2 0 0 0
0 0 0 3

Why Sparse Matrix is Used?

Sparse matrices are extremely useful because they allow efficient storage and computational performance. Instead of storing all elements, including the zeros, sparse matrix representations store only the non-zero elements, which reduces memory consumption and speeds up computations. This is vital in applications such as machine learning, where large datasets often contain numerous zero-values such as text data. By utilizing sparse matrices, we can work with these datasets without loading large amounts of redundant data.

Storing and processing these datasets using sparse matrix representations helps reduce computational cost and memory usage, making it possible to train models more efficiently.

Types of Sparse Matrices in Data Structures

Here are the types of sparse matrices in data structure:

1. Lower Triangular Sparse Matrix

The diagonal element of a matrix is zero, and all other elements are positive. For a lower triangular matrix, Ai,j = 0 for i < j.

custom img

Representation of Lower Triangular Matrix A[5,5]

custom img

2. Upper Triangular Sparse Matrix

In an upper triangular matrix, the elements below the main diagonal are zero. For Ai,j = 0 where i > j.

custom img

Representation of Upper Triangular Sparse Matrix A[5,5]

custom img

3. Tri-Diagonal Sparse Matrix

A matrix where non-zero elements can appear only on the diagonal, or immediately above or below the diagonal. In a tri-diagonal matrix, Ai,j = 0 where |i - j| > 1.

custom img

Representation of Tri-Diagonal Sparse Matrix A[5,5]

custom img

Representation of Sparse Matrix

The Sparse Matrix can be represented using two methods:

  • Sparse Matrix Using Array
  • Sparse Matrix Using Linked List

1. Sparse Matrix Using Array

#include<stdio.h>

int main()
{
	// Assume 4x5 sparse matrix
	int sparseMatrix[4][5] =
	{
		{0 , 0 , 3 , 0 , 4 },
		{0 , 0 , 5 , 7 , 0 },
		{0 , 0 , 0 , 0 , 0 },
		{0 , 2 , 6 , 0 , 0 }
	};

	int size = 0;
	for (int i = 0; i < 4; i++)
		for (int j = 0; j < 5; j++)
			if (sparseMatrix[i][j] != 0)
				size++;

	int compactMatrix[3][size];

	// Making of new matrix
	int k = 0;
	for (int i = 0; i < 4; i++)
		for (int j = 0; j < 5; j++)
			if (sparseMatrix[i][j] != 0)
			{
				compactMatrix[0][k] = i;
				compactMatrix[1][k] = j;
				compactMatrix[2][k] = sparseMatrix[i][j];
				k++;
			}

	for (int i=0; i<3; i++)
	{
		for (int j=0; j<size; j++)
			printf("%d ", compactMatrix[i][j]);

		printf("\n");
	}
	return 0;
} 

Output

0 0 1 1 3 3 
2 4 2 3 1 2 
3 4 5 7 2 6

2. Sparse Matrix Using Linked List

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

// Node to represent sparse matrix
struct Node {
    int value;
    int row_position;
    int column_position;
    struct Node *next;
};

// Function to create a new node
void create_new_node(struct Node** start, int non_zero_element, 
                     int row_index, int column_index ) {
    struct Node *temp, *r;
    temp = *start;

    if (temp == NULL) {
        // Create new node dynamically
        temp = (struct Node *) malloc(sizeof(struct Node));
        temp->value = non_zero_element;
        temp->row_position = row_index;
        temp->column_position = column_index;
        temp->next = NULL;
        *start = temp;
    } else {
        while (temp->next != NULL)
            temp = temp->next;

        // Create new node dynamically
        r = (struct Node *) malloc(sizeof(struct Node));
        r->value = non_zero_element;
        r->row_position = row_index;
        r->column_position = column_index;
        r->next = NULL;
        temp->next = r;
    }
}

// This function prints the sparse matrix in the desired format
void PrintMatrix(struct Node* start) {
    struct Node* temp = start;
    int matrix[4][5] = {0};  // Initialize a 4x5 matrix with all zeros

    // Fill the matrix with non-zero values from the linked list
    while (temp != NULL) {
        matrix[temp->row_position][temp->column_position] = temp->value;
        temp = temp->next;
    }

    // Print the matrix
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 5; j++) {
            printf("%d ", matrix[i][j]);
        }
        printf("\n");
    }
}

// Driver of the program
int main() {
    // Assume 4x5 sparse matrix with given values
    int sparseMatrix[4][5] =
    {
        {0 , 0 , 3 , 0 , 4},
        {0 , 0 , 5 , 7 , 0},
        {0 , 0 , 0 , 0 , 0},
        {0 , 2 , 6 , 0 , 0}
    };

    /* Start with the empty list */
    struct Node* start = NULL;

    // Traverse the matrix and insert non-zero elements into the linked list
    for (int i = 0; i < 4; i++) {
        for (int j = 0; j < 5; j++) {
            // Pass only those values which are non-zero
            if (sparseMatrix[i][j] != 0) {
                create_new_node(&start, sparseMatrix[i][j], i, j);
            }
        }
    }

    // Print the sparse matrix in the requested format
    PrintMatrix(start);

    return 0;
}

Output

0  0  3  0  4
0  0  5  7  0
0  0  0  0  0
0  2  6  0  0

Advantages & Disadvantages of Using Sparse Matrices

Here are the advantages and disadvantages of using sparse matrices in data structure:

Advantages

  • Stores only non-zero elements, reducing memory usage.
  • Operations on sparse matrices are faster because of non-zero elements.
  • Sparse matrices can handle much larger datasets.

Disadvantages

  • Not all problems can be represented as sparse matrices.
  • Sparse matrices may lose information since many elements are zero.
  • Choosing the right algorithms and libraries for sparse matrix operations can be challenging.

Conclusion

In conclusion, a sparse matrix is an essential concept in data structure and machine learning. This allows efficient storage and processing of large datasets with many zero values. By representing only the non-zero elements, we can reduce memory usage and improve computational performance. Understanding how to store and process sparse matrices is crucial for solving problems efficiently in a variety of domains.

Frequently Asked Questions

1. What is the algorithm for sparse matrix multiplication?

The sparse matrix multiplication algorithm involves iterating only over the non-zero elements in the matrices, which significantly reduces the number of operations needed compared to traditional matrix multiplication.

2. Why is a sparse matrix used in machine learning? 

In machine learning, sparse matrices are used because many datasets (e.g., document-term matrices in NLP) contain many zeros. Using sparse matrices for storage and computation helps reduce memory usage and speed up training.

3. How do you implement a sparse matrix in C++? 

You can implement a sparse matrix in C++ by creating a structure to store the row, column, and value of each non-zero element, and storing these structures in a vector. You can then access and process the non-zero elements efficiently.

Read More Articles

Chat with us
Chat with us
Talk to career expert