scipy.sparse — sparse matrix formats (CSR, CSC), sparse solvers
WHY sparse at all?
WHY it matters: A dense matrix needs floats TB — impossible. If each row has ~5 nonzeros, , storable in ~120 MB. Same problem, less memory.
The three formats you must know
1. COO — Coordinate (the "scratchpad")
2. CSR — Compressed Sparse Row
3. CSC — Compressed Sparse Column
Deriving CSR from scratch (Feynman-style)
Take
Step 1 — list nonzeros row by row. Why? CSR's ordering convention is "scan each row left→right." Row0: . Row1: . Row2: . Row3: .
So data = [10, 20, 30, 40, 50, 60], indices = [0, 1, 0, 2, 3, 1].
Step 2 — count nonzeros per row. Counts .
Why? indptr is the cumulative sum of these, telling us boundaries.
Step 3 — cumulative sum, starting at 0.
Why this step? Row lives in data[indptr[i]:indptr[i+1]]. Check row 2: data[2:5]=[30,40,50] ✓. The final entry .

Worked example: building & using it in code
import numpy as np
from scipy.sparse import coo_matrix, csr_matrix
from scipy.sparse.linalg import spsolve
# Build in COO (easy), convert to CSR (fast)
rows = [0, 1, 2, 2, 2, 3]
cols = [0, 1, 0, 2, 3, 1]
vals = [10,20,30,40,50,60]
A = coo_matrix((vals, (rows, cols)), shape=(4,4)).tocsr()
print(A.indptr) # [0 1 2 5 6] <- matches our derivation
print(A.indices) # [0 1 0 2 3 1]
print(A.data) # [10 20 30 40 50 60]Why .tocsr()? COO can't do fast arithmetic or solves; CSR can.
Solving
from scipy.sparse import diags
from scipy.sparse.linalg import spsolve, cg
n = 1000
# 1D Poisson: tridiagonal [-1, 2, -1]
A = diags([-1, 2, -1], [-1, 0, 1], shape=(n, n), format='csc')
b = np.ones(n)
x_direct = spsolve(A, b) # sparse LU (uses CSC)
x_iter, info = cg(A, b) # conjugate gradient (SPD only)Why CSC for spsolve? Sparse LU factorization processes columns; passing CSC avoids an internal conversion.
Why cg here? This is symmetric positive definite, so Conjugate Gradient converges fast and never forms a dense factorization.
Common mistakes (steel-manned)
Active recall
Recall Quick self-test (cover the answers)
- What three arrays define CSR? →
data,indices,indptr. - Length of
indptr? → . - Where do row 's nonzeros live? →
data[indptr[i]:indptr[i+1]]. - Which format do direct solvers prefer? → CSC.
- SpMV cost? → .
Recall Feynman: explain to a 12-year-old
Imagine a giant spreadsheet that's almost all empty boxes. Instead of writing down every empty box, you only write the boxes that have a number — plus a little note saying "row 2 starts here, row 3 starts here." That note is indptr: it's like bookmarks telling you where each row's numbers begin, so you can flip straight to any row. Because you skipped all the blanks, the computer reads way less and finishes way faster.
What problem do sparse matrices solve?
What three arrays make up CSR format?
How do you get the nonzeros of row i in CSR?
What is the length and last value of CSR indptr?
How does CSC differ from CSR?
Why build a sparse matrix in COO (or LIL/DOK) then convert?
What is the cost of sparse matrix-vector product y=Ax in CSR?
When should you NOT use a sparse matrix?
Which scipy function does a direct sparse solve and what format does it like?
When is cg (conjugate gradient) valid, and what to use otherwise?
What is fill-in?
In modern scipy.sparse, how do you do matrix multiply vs elementwise multiply?
Connections
- Dense matrices (NumPy ndarray) — the baseline sparse improves on.
- LU decomposition and Cholesky decomposition — what
spsolvedoes under the hood. - Conjugate Gradient method / Krylov subspace methods — iterative
cg,gmres. - Preconditioning — accelerates iterative sparse solvers.
- Finite element method / PDE discretization — main source of sparse systems.
- Graph adjacency matrices — graphs are naturally sparse.
- Big-O complexity — why O(nnz) beats O(n²).
Concept Map
Hinglish (regional understanding)
Intuition Hinglish mein samjho
Dekho, bahut badi matrices — jaise PDE solve karte waqt ya graphs me — mostly zeros hoti hain. Agar tum saare zeros bhi store karoge to memory aur time dono waste honge ( cost). Sparse matrix ka funda simple hai: sirf nonzero values aur unke coordinates store karo. Isse numbers ki jagah sirf numbers bachte hain — kabhi-kabhi 8 TB ki jagah 100 MB!
CSR (Compressed Sparse Row) format me teen arrays hote hain: data (nonzeros, row-by-row left to right), indices (har value ka column number), aur indptr (length , jo batata hai ki har row data me kahan se start hoti hai). indptr actually bookmark jaisa hai — row ke nonzeros milte hain data[indptr[i]:indptr[i+1]] me. Isi liye row access hota hai aur multiply super fast ho jata hai. CSC bilkul ulta hai — column-by-column — aur direct solvers (LU factorization) isko prefer karte hain.
Practical workflow yaad rakhna: matrix COO me build karo (entries dalna easy), phir .tocsr() ya .tocsc() se convert karo. CSR me directly A[i,j]=v karne ki galti mat karna — wo har baar arrays shift karta hai, slow aur warning deta hai. Solve karne ke liye: general matrix ke liye spsolve (CSC do), symmetric positive-definite ke liye cg, aur baaki iterative ke liye gmres/bicgstab. Bas yaad rakho: "COO to collect, CSR to compute, CSC to crack." Ye samajh loge to scientific computing me bade-bade systems easily handle kar paoge.