12. Rank-Nullity Theorem

📖 Reading · 10 min
💡 Every code box below is live — edit it and hit Run.

§17.4 introduced two numbers attached to any m\times n matrix A: the rank (pivot count, =\dim\operatorname{Col}(A)=\dim\operatorname{Row}(A)) and the nullity (\dim\operatorname{Null}(A), the number of free variables). This closing lesson of Module 17 states the single equation relating them — simple to write down, and surprisingly powerful to apply.

The theorem

\operatorname{rank}(A)+\operatorname{nullity}(A)=n

where n is the number of columns of A (the dimension of the space A's inputs live in). The proof is really just §17.4's construction, restated: RREF has exactly n columns, each one either a pivot column (contributing to rank) or a free column (contributing a basis vector to the null space, per §17.4's free-variable construction) — and every column is exactly one of the two, never both, never neither. Counting columns two ways gives the theorem directly.

What it's really saying

Rank measures how much of the output space A's columns actually reach; nullity measures how much of the input space collapses to \vec0. The theorem says these two effects exactly account for every input dimension: each of the n input dimensions either survives into something new in the output (pivot, counted in rank) or gets crushed (free variable, counted in nullity) — there's no third option and no double-counting.

A useful reformation for square matrices: for n\times n A,

A\text{ invertible}\iff\operatorname{rank}(A)=n\iff\operatorname{nullity}(A)=0

which packages §16.3's "full rank," §17.1's "independent columns," and §17.0's "trivial null space" invertibility characterizations into one line, and is exactly why "0 is not an eigenvalue of A" will join that same list in §19.0 — an eigenvalue of 0 means A\vec v=\vec0 for some \vec v\neq0, i.e. a nontrivial null space.

Consequences worth having on hand

  • A tall matrix (m>n) can have trivial null space (nullity 0, rank n — every input survives), but its column space can never be all of \mathbb{R}^m: rank \le n<m leaves output dimensions unreached. This is exactly the situation §20.5's least squares deals with — a system with more equations than unknowns, generally inconsistent for exactly this reason.
  • A wide matrix (m<n) can never have trivial null space: rank \le m<n forces nullity =n-\operatorname{rank}\ge n-m>0 by the theorem directly — more unknowns than equations always leaves at least one free variable. (This matches §16.1's "more unknowns than equations can't pin down a unique solution," now derived as a corollary rather than argued separately.)
  • Rank is bounded by both dimensions: \operatorname{rank}(A)\le\min(m,n), since there can be at most one pivot per row and at most one per column.

Doing it in Python

import sympy as sp

A = sp.Matrix([
    [1, 2, 1, 0],
    [2, 4, 0, 1],
    [1, 2, -1, 1],
])

rank = A.rank()
nullity = A.cols - rank
print(f"A is {A.rows}x{A.cols}")
print(f"rank = {rank}, nullity = {nullity}")
print(f"rank + nullity = {rank + nullity}  (should equal cols = {A.cols})")

ns = A.nullspace()
print(f"\nnullspace has {len(ns)} basis vector(s), matching nullity: {len(ns) == nullity}")
A is 3x4
rank = 2, nullity = 2
rank + nullity = 4  (should equal cols = 4)

nullspace has 2 basis vector(s), matching nullity: True

Confirming the tall/wide consequences directly:

import numpy as np

wide = np.array([[1., 2., 3.], [4., 5., 6.]])       # 2x3: more unknowns than equations
tall = np.array([[1., 2.], [3., 4.], [5., 7.]])      # 3x2: more equations than unknowns

print("wide (2x3): rank =", np.linalg.matrix_rank(wide),
      " nullity =", 3 - np.linalg.matrix_rank(wide), " (always > 0 here)")
print("tall (3x2): rank =", np.linalg.matrix_rank(tall),
      " nullity =", 2 - np.linalg.matrix_rank(tall), " (can be 0)")
wide (2x3): rank = 2  nullity = 1  (always > 0 here)
tall (3x2): rank = 2  nullity = 0  (can be 0)

Worked example

Verify rank-nullity for A=\begin{pmatrix}1&2&3&4\\2&4&6&9\end{pmatrix}.

Row-reduce: R_2\leftarrow R_2-2R_1 gives \begin{pmatrix}1&2&3&4\\0&0&0&1\end{pmatrix}, already RREF after R_1\leftarrow R_1-4R_2: \begin{pmatrix}1&2&3&0\\0&0&0&1\end{pmatrix}. Pivots: columns 1,4. \operatorname{rank}(A)=2.

n=4 columns, so nullity =4-2=2. Free variables: columns 2,3. x_1+2x_2+3x_3=0 and x_4=0, so x_1=-2x_2-3x_3. Basis for \operatorname{Null}(A): set (x_2,x_3)=(1,0) then (0,1): \{(-2,1,0,0),\,(-3,0,1,0)\} — two vectors, matching nullity =2.

\boxed{\operatorname{rank}(A)+\operatorname{nullity}(A)=2+2=4=n}\ \checkmark

Sanity check. A(-2,1,0,0)^T=(1(-2)+2(1),\,2(-2)+4(1))=(0,0) ✓, and A(-3,0,1,0)^T=(1(-3)+3(1),\,2(-3)+6(1))=(0,0) ✓ — both null space basis vectors genuinely map to zero, confirming the free-variable construction was done correctly and that the count matches the theorem's prediction exactly.

Your turn

1. A 5\times7 matrix has rank 4. What is its nullity?

2. Can a 3\times5 matrix have nullity 1? Explain using rank-nullity and the rank bound \operatorname{rank}(A)\le\min(m,n).

3. True or false: rank-nullity implies that a square invertible matrix has nullity 0.

Solutions

1. \operatorname{nullity}=n-\operatorname{rank}=7-4=3.

2. No. Rank-nullity requires \operatorname{rank}(A)=n-\operatorname{nullity}=5-1=4. But \operatorname{rank}(A)\le\min(3,5)=3 for a 3\times5 matrix — 4>3 is impossible. So nullity 1 cannot occur; the smallest possible nullity for a 3\times5 matrix is 5-3=2 (when rank is at its maximum possible value, 3).

3. True. An invertible n\times n matrix has rank n (full rank, §16.3), so by rank-nullity, nullity =n-n=0 — matching §17.0/§17.4's direct observation that \operatorname{Null}(A)=\{\vec0\} for an invertible matrix, now derived as an immediate corollary instead.

Check yourself in code

For A=\begin{pmatrix}1&2&0&3\\0&1&1&1\\1&3&1&4\end{pmatrix}, compute rank, nullity, and confirm rank + nullity equals the column count.

Print exactly this:

rank = 2
nullity = 2
rank + nullity == cols: True
import sympy as sp

A = sp.Matrix([[1, 2, 0, 3], [0, 1, 1, 1], [1, 3, 1, 4]])
rank = A.rank()
print("rank =", rank)
# print nullity (cols - rank) and whether rank + nullity == cols
import sympy as sp

A = sp.Matrix([[1, 2, 0, 3], [0, 1, 1, 1], [1, 3, 1, 4]])
rank = A.rank()
nullity = A.cols - rank
print("rank =", rank)
print("nullity =", nullity)
print("rank + nullity == cols:", rank + nullity == A.cols)

Rank-nullity says \operatorname{rank}(A)+\operatorname{nullity}(A)=n always — every input column is either a pivot (surviving into the output, counted by rank) or free (collapsing into the null space, counted by nullity), with no overlap and no gaps. It packages invertibility into one line for square matrices, and explains directly why wide matrices always have a nontrivial null space while tall ones need not.

This closes Module 17. Vector spaces, span, basis, dimension, and the three fundamental subspaces are the vocabulary; Module 18 puts that vocabulary to work describing functions between vector spaces — linear transformations — of which matrix-vector multiplication has been a working example all along.