Last active
May 14, 2024 08:01
-
-
Save rdisipio/98bfdf0d8b259427f72d487042477a0f to your computer and use it in GitHub Desktop.
Sparse Matrix CSR to CSC conversion
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def csr_to_csc(m, n, Ax, Aj, Ap): | |
nnz = len(Ax) | |
Bx = [0 for _ in range(nnz)] | |
Bi = [0 for _ in range(nnz)] | |
Bp = [0 for _ in range(m+1)] | |
# Count elements in each column: | |
cnt = [0 for _ in range(n)] | |
for k in range(nnz): | |
col = Aj[k] | |
cnt[col] += 1 | |
# Cumulative sum to set the column pointer of matrix B | |
for i in range(1, n+1): | |
Bp[i] = Bp[i-1] + cnt[i-1] | |
for row in range(m): | |
for j in range(Ap[row], Ap[row+1]): | |
col = Aj[j] | |
dest = Bp[col] | |
Bi[dest] = row; | |
Bx[dest] = Ax[j]; | |
Bp[col] += 1 | |
# now shift Bp | |
Bp = [0] + Bp | |
Bp.pop(-1) | |
return Bx, Bi, Bp | |
def nonzero(X): | |
return sum([1 for x in X if x != 0]) | |
def dense_to_csr(A): | |
Ax = [] | |
Aj = [] | |
Ap = [0] | |
m = len(A) | |
n = len(A[0]) | |
for i in range(m): | |
Ap.append(Ap[-1] + nonzero(A[i])) | |
for j in range(n): | |
if A[i][j] == 0: continue | |
Ax.append(A[i][j]) | |
Aj.append(j) | |
return m, n, Ax, Aj, Ap | |
A = [[0,0,3,0], [0,2,0,1], [0,0,0,2], [1,0,0,0]] | |
if __name__ == '__main__': | |
m, n, Ax, Aj, Ap = dense_to_csr(A) | |
print("Ax:", Ax) | |
print("Aj:", Aj) | |
print("Ap:", Ap) | |
Bx, Bi, Bp = csr_to_csc(m, n, Ax, Aj, Ap) | |
print("Bx:", Bx) | |
print("Bi:", Bi) | |
print("Bp:", Bp) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
I'm not really sure if m or n are representing rows vs columns, but is is clear to me that Bp should be of size ncols+1 (and not nrows+1). But then I feel like cnt should have the same size (-1) if I'm understanding the algorithm correctly.