Skip to content

Instantly share code, notes, and snippets.

@rdisipio
Last active May 14, 2024 08:01
Show Gist options
  • Save rdisipio/98bfdf0d8b259427f72d487042477a0f to your computer and use it in GitHub Desktop.
Save rdisipio/98bfdf0d8b259427f72d487042477a0f to your computer and use it in GitHub Desktop.
Sparse Matrix CSR to CSC conversion
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)
@shakedregev
Copy link

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.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment