Basis and Rank
If linear independence tells you which vectors are not redundant, basis and rank tell you the right number of them. A basis is the smallest toolkit that still builds everything; rank counts how many independent directions a matrix actually has. Together they’re the backbone of PCA, compression, and “how many dimensions does my data really need?”
A real-life example: describing any location in a city
To pin down any point in a city you need exactly two directions — say “blocks East” and “blocks North.” One direction isn’t enough (you can only reach a line); a third (“blocks Northeast”) is redundant. Those two directions are a basis for the city plane, and the number 2 is its dimension. Swap to “blocks along Main St” and “blocks along 1st Ave” and you have a different basis for the same plane — the coordinates change, the place doesn’t.
Generating set, span, and basis
- The span of a set is every vector you can build as a linear combination of them: .
- If , then is a generating set of .
- A basis is a minimal generating set — equivalently, a maximal linearly independent set. Remove any vector and it no longer spans; add any vector and it’s no longer independent.
Every vector in has a unique representation in a given basis. The canonical (standard) basis of is
but there are infinitely many others — and all bases of a space have the same number of vectors. That number is the dimension, .
A basis is a coordinate system
Here’s the key mental model: choosing a basis is choosing a coordinate system. The same point has different coordinates in different bases, but it’s the same point in the same plane. Watch a fixed black point keep its identity while an alternate (amber) basis rotates — its coordinates in that basis change continuously, yet always lands on the same spot:
When the two amber vectors line up (collinear), the little warning fires: they no longer span the plane, so they’re not a basis — exactly the independence condition from the previous page.
Rank: how many independent directions?
The rank of a matrix , written , is the number of linearly independent columns — which (remarkably) always equals the number of linearly independent rows. Compute it by row-reducing and counting pivots.
flowchart TD A["Matrix A (m × n)"] --> R["Row-reduce, count pivots"] R --> K["rk(A) = number of pivots"] K --> P1["rk(A) = n → columns independent, A invertible (if square)"] K --> P2["rk(A) = min(m, n) → FULL RANK"] K --> P3["rk(A) < min(m, n) → RANK DEFICIENT (redundancy)"]
Key properties that show up constantly:
- — column rank = row rank.
- A square is invertible .
- is solvable .
- The null space of has dimension .
- Full rank means ; anything less is rank deficient.
Finding a basis of a subspace
To get a basis of a subspace spanned by some vectors:
- Write the spanning vectors as columns of a matrix .
- Row-reduce to row-echelon form.
- The original vectors sitting in pivot columns form a basis.
Same elimination, third job: earlier it solved systems and tested independence; now it extracts a basis.
NumPy: rank, dimension, and low-rank structure
import numpy as np
# Three vectors in R^3, but the third is the sum of the first two
A = np.column_stack([[1, 0, 1],
[0, 1, 1],
[1, 1, 2]]).astype(float)
rank = np.linalg.matrix_rank(A)
print("rank:", rank) # 2 -> only 2 independent directions
print("null space dimension:", A.shape[1] - rank) # 3 - 2 = 1
# Real ML flavor: a "data matrix" that secretly lives in 1 dimension
x = np.linspace(0, 1, 50)
data = np.column_stack([x, 2 * x, -x]) # every column is a multiple of x
print("data shape:", data.shape, "-> rank:", np.linalg.matrix_rank(data))import numpy as np
# Three vectors in R^3, but the third is the sum of the first two
A = np.column_stack([[1, 0, 1],
[0, 1, 1],
[1, 1, 2]]).astype(float)
rank = np.linalg.matrix_rank(A)
print("rank:", rank) # 2 -> only 2 independent directions
print("null space dimension:", A.shape[1] - rank) # 3 - 2 = 1
# Real ML flavor: a "data matrix" that secretly lives in 1 dimension
x = np.linspace(0, 1, 50)
data = np.column_stack([x, 2 * x, -x]) # every column is a multiple of x
print("data shape:", data.shape, "-> rank:", np.linalg.matrix_rank(data))rank: 2
null space dimension: 1
data shape: (50, 3) -> rank: 1rank: 2
null space dimension: 1
data shape: (50, 3) -> rank: 1That last line is the whole idea behind compression: a table that looks 3-dimensional is really rank 1 — one direction explains all of it.
Why this matters for ML
- PCA finds an orthonormal basis ordered by variance and keeps the top few vectors — a basis change plus a rank reduction.
- Low-rank approximation compresses images and recommendation matrices: store a rank- stand-in instead of the full grid.
- Effective dimensionality:
matrix_rankmatrix_rankon your data tells you how many features are truly independent — often far fewer than the column count.
🧪 Try It Yourself
Exercise 1 – Compute the rank
Exercise 2 – Dimension of the null space
Exercise 3 – Detect hidden low-rank structure
Recap
- Span = all linear combinations; a generating set spans the whole space.
- A basis is a minimal generating set = a maximal independent set; every vector has a unique representation in it, and choosing one is choosing a coordinate system.
- All bases share the same size — the dimension of the space.
- Rank = number of independent columns (= rows) = number of pivots; it decides invertibility, solvability, and null-space size.
- Low rank means hidden redundancy — the mathematical basis of compression and PCA.
Next: functions that respect all this structure — every one of them secretly a matrix — Linear Mappings.
If this helped you, consider buying me a coffee ☕
Buy me a coffeeWas this page helpful?
Let us know how we did
