# Context

There are a handful of ways to compress a matrix, $\mathbf{M}$, but Compressed Row Storage (CRS) is fairly popular due to its fast access. Similarly, there exists Compressed Column Storage (CCS), which is equivalent to the CRS of the transpose of the original matrix, i.e. $CRS(\mathbf{M}^\text{T}) = CCS(\mathbf{M})$.

Notably - for CRS - should the original matrix contain a row which is empty, and one wish to maintain the original's dimensions when de-compressing one must pad empty rows: similar for columns if using CCS. This is especially useful if one wants to access the compressed matrix as if it were not compressed.

An example of a dense matrix $\mathbf{M}$ and its transpose $\mathbf{M}^\text{T}$ undergoing CRS is given below:

Thus if one wanted to find $\mathbf{M}[i][j]$:

start = row_pointers[i]   // where row i starts
end = row_pointers[i + 1] // where row i ends
non_empty_columns = column_indexes[start:end] // non-zero column indexes of row i
if j in non_empty_columns:
return values[start:end][non_empty_columns.index(j)]


# Question

It is clear that the CRS of $\mathbf{M}$ and $\mathbf{M}^\text{T}$ are visually distinct. However, is there a mapping, that given only the CRS of $\mathbf{M}$, would return the search of $\mathbf{M}^\text{T}$.

For example, if I wanted all non empty columns of row 1, I could use the above method with just the parameter i:

start = row_pointers[i]   // where row i starts
end = row_pointers[i + 1] // where row i ends
non_empty_columns = column_indexes[start:end] // non-zero column


but what if I wanted also all non-empty rows for column 1 (e.g. searching for all non-empty columns in the transpose)?

Is there a mapping that would efficiently allow me to find those?

• What do you mean by this mapping? Do you want to compute the transpose of $M$ in CRS? Without it you cannot really reconstruct a column from CRS without actually going through all nonzeros. Jan 17, 2017 at 18:12
• On a side note, I'm not quite sure how useful this "padding" of empty rows is. It seems to me that it just adds more overhead when traversing nonzeros of the matrix (e.g., for matrix-vector multiplications). Jan 17, 2017 at 18:12
• @AlgebraicPavel, suppose the matrix is a directed adjacency matrix, then there can be a cause where row i (corresponding to vertex i) is empty (no successors), but another row, k, may have an entry at column i (predecessor of i). In such as case, CRS would remove the row - although the column value would be preserved. This would change the dimensions of the row-pointer array, and thus one must keep note elsewhere that row i is not included. Padding, for the compression of sparse graphs, just makes book keeping a bit easier - although inflating the size - linearly - in regard to the Vertex Set. Jan 18, 2017 at 5:54
• @AlgebraicPavel no I do not want to transpose of M in the CRS, that is an expensive operation. Rather - again adapting an adjacency matrix view - I want the span of non-empty column incidences of a row. The CRS of the transpose gives the non-empty row incidences of a column. Thus given only the CRS of the original matrix, can one efficiently find the non-empty row incidences of a column without looping through? similar to the straightforward operation of finding non-empty column incidences of a row given above. Jan 18, 2017 at 5:57