Sparse Matrix Representations | Set 3 ( CSR )

If most of the elements in the matrix are zero then the matrix is called a sparse matrix. It is wasteful to store the zero elements in the matrix since they do not affect the results of our computation. This is why we implement these matrices in more efficient representations than the standard 2D Array. Using more efficient representations we can cut down space and time complexities of operations significantly.

We have discussed at 4 different representations in following articles :

  1. Sparse Matrix Representation | Set 1
  2. Sparse Matrix Representation | Set 2 .

In this article, we will discuss another representation of the Sparse Matrix which is commonly referred as the Yale Format.

The CSR (Compressed Sparse Row) or the Yale Format is similar to the Array Representation (discussed in Set 1) of Sparse Matrix. We represent a matric M (m * n), by three 1-D arrays or vectors called as A, IA, JA. Let NNZ denote the number of non-zero elements in M and note that 0-based indexing is used.

To find the no of non-zero elements in say row i, we perform IA[i+1] – IA[i]. Notice how this representation is different to the array based implementation where the second vector stores the row indices of non-zero elements.

The following examples show how these matrixes are represented.

Examples:

Input : 0  0  0  0
        5  8  0  0
        0  0  3  0
        0  6  0  0

Solution: When the matrix is read row by 
          row, the A vector is [ 5 8 3 6]
          The JA vector stores column indices
          of elements in A hence, JA = [ 0 1 2 
           1]. IA[0] = 0. IA[1] = IA[0] + no  
          of non-zero elements in row 0 
          i.e 0 + 0 = 0.
          Similarly,
          IA[2] = IA[1] + 2 = 2
          IA[3] = IA[2] + 1 = 3  
          IA[4] = IA[3]+1 = 4
          Therefore IA = [0 0 2 3 4]
          The trick is remember that IA[i]
          stores NNZ upto and not-including 
          i row.

Input : 10  20  0  0  0  0
         0  30  0  4  0  0
         0   0 50 60 70  0
         0   0  0  0  0 80

Output :  A = [10 20 30 4 50 60 70 80],
         IA = [0 2 4 7 8]
         JA = [0  1 1 3 2 3 4 5]

Algorithm

SPARSIFY (MATRIX)
Step 1: Set M to number of rows in MATRIX
Step 2: Set N to number of columns in MATRIX
Step 3: I = 0, NNZ = 0. Declare A, JA, and IA. 
        Set IA[0] to 0
Step 4: for I = 0 ... N-1
Step 5: for J = 0 ... N-1
Step 5: If MATRIX [I][J] is not zero
           Add MATRIX[I][J] to A
           Add J to JA
           NNZ = NNZ + 1
        [End of IF]
Step 6: Add NNZ to IA
        [ End of J loop ]
        [ End of I loop ]
Step 7: Print vectors A, IA, JA
Step 8: END
filter_none

edit
close

play_arrow

link
brightness_4
code

// CPP program to find sparse matrix rep-
// resentation using CSR
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;
  
typedef std::vector<int> vi;
  
typedef vector<vector<int> > matrix;
  
// Utility Function to print a Matrix
void printMatrix(const matrix& M)
{
    int m = M.size();
    int n = M[0].size();
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < n; j++) 
            cout << M[i][j] << " ";        
        cout << endl;
    }
}
  
// Utility Function to print A, IA, JA vectors
// with some decoration.
void printVector(const vi& V, char* msg)
{
  
    cout << msg << "[ ";
    for_each(V.begin(), V.end(), [](int a) {
        cout << a << " ";
    });
    cout << "]" << endl;
}
  
// Generate the three vectors A, IA, JA 
void sparesify(const matrix& M)
{
    int m = M.size();
    int n = M[0].size(), i, j;
    vi A;
    vi IA = { 0 }; // IA matrix has N+1 rows
    vi JA;
    int NNZ = 0;
  
    for (i = 0; i < m; i++) {
        for (j = 0; j < n; j++) {
            if (M[i][j] != 0) {
                A.push_back(M[i][j]);
                JA.push_back(j);
  
                // Count Number of Non Zero 
                // Elements in row i
                NNZ++;
            }
        }
        IA.push_back(NNZ);
    }
  
    printMatrix(M);
    printVector(A, (char*)"A = ");
    printVector(IA, (char*)"IA = ");
    printVector(JA, (char*)"JA = ");
}
  
// Driver code
int main()
{
    matrix M = {
        { 0, 0, 0, 0, 1 },
        { 5, 8, 0, 0, 0 },
        { 0, 0, 3, 0, 0 },
        { 0, 6, 0, 0, 1 },
    };
  
    sparesify(M);
  
    return 0;
}
chevron_right

Output:

0 0 0 0 1 
5 8 0 0 0 
0 0 3 0 0 
0 6 0 0 1 
A = [ 1 5 8 3 6 1 ]
IA = [ 0 1 3 4 6 ]
JA = [ 4 0 1 2 1 4 ]

Notes

References
https://en.wikipedia.org/wiki/Sparse_matrix




Intern at GeeksForGeeks

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.




Article Tags :
Practice Tags :