Sparse Matrix
9 functions for sparse matrices in CSC (Compressed Sparse Column) format. Essential for single-cell RNA-seq count matrices where >90% of values are zero.
sparse_matrix
Create a sparse matrix from dimensions and COO entry records.
sparse_matrix(nrows, ncols, entries) -> SparseMatrix
| Parameter | Type | Description |
|---|---|---|
| entries | List<Record> | Records with row, col, and val fields |
| nrows | int | Number of rows |
| ncols | int | Number of columns |
# 30,000 genes x 10,000 cells, mostly zeros
let entries = [
{row: 0, col: 5, val: 3.0}, # gene 0, cell 5 = 3 counts
{row: 0, col: 12, val: 1.0}, # gene 0, cell 12 = 1 count
{row: 142, col: 5, val: 7.0}, # gene 142, cell 5 = 7 counts
]
let mat = sparse_matrix(30000, 10000, entries)
to_dense / to_sparse
Convert between sparse and dense matrix representations.
to_dense(sparse) -> matrix
to_sparse(matrix) -> sparse
let small_sparse = sparse_matrix(3, 3, [
{row: 0, col: 0, val: 1.0},
{row: 1, col: 2, val: 2.0},
{row: 2, col: 1, val: 3.0}
])
let dense = to_dense(small_sparse)
let sp = to_sparse(dense)
println(nnz(sp)) # 3
Edge case: to_dense on a large scRNA-seq matrix (30k x 10k) allocates ~2.4 GB. Use sparse operations when possible.
nnz
Count of non-zero entries in the sparse matrix.
nnz(sparse) -> int
let mat = sparse_matrix(10, 10, [
{row: 0, col: 0, val: 5.0},
{row: 1, col: 2, val: 3.0},
])
nnz(mat) # 2
# Sparsity ratio
let sparsity = 1.0 - float(nnz(mat)) / float(10 * 10)
println("Sparsity:", round(sparsity * 100, 1), "%") # Sparsity: 98.0%
sparse_get
Get a single value from a sparse matrix by row and column index.
sparse_get(sparse, row, col) -> float
let mat = sparse_matrix(10, 10, [
{row: 0, col: 0, val: 5.0},
{row: 1, col: 2, val: 3.0},
])
sparse_get(mat, 0, 0) # 5.0
sparse_get(mat, 0, 1) # 0.0 (not stored = zero)
normalize_sparse
Normalize columns (cells) to sum to a target value, commonly 10,000 for CPM-like normalization.
normalize_sparse(mat, method) -> SparseMatrix
let raw_counts = sparse_matrix(30000, 10000, entries)
let normalized = normalize_sparse(raw_counts, "log1p_cpm")
sparse_row_sums / sparse_col_sums
Compute row or column sums of a sparse matrix efficiently.
sparse_row_sums(sparse) -> list
sparse_col_sums(sparse) -> list
let mat = sparse_matrix(3, 3, [
{row: 0, col: 0, val: 5.0},
{row: 0, col: 1, val: 3.0},
{row: 1, col: 0, val: 2.0},
])
sparse_row_sums(mat) # [8.0, 2.0, 0.0]
sparse_col_sums(mat) # [7.0, 3.0, 0.0]