Matrices
A matrix is a rectangular grid of numbers. That sounds humble, but it is the single most important object in machine learning, and the reason is that it has two faces. A matrix can be data — a spreadsheet, an image, a batch of feature vectors — and it can be an action: a rotation, a projection, a neural network layer.
The book says this outright at the top of §2.2: matrices “can be used to compactly represent systems of linear equations, but they also represent linear functions”. Learning to switch between those two readings, and to know which one a given page means, is the skill this section buys you.
What you’ll learn
Section titled “What you’ll learn”- What a matrix is, precisely, and why can be treated as .
- Why multiplication is not element-wise, and what it is instead.
- The one idea that makes matrix multiplication obvious: the columns are the images of the basis vectors.
- Why , and why even their shapes can differ.
- Identity, inverse, transpose, symmetry — and the four look-alike identities that are false.
Intuition: a grayscale image, and a machine that bends the plane
Section titled “Intuition: a grayscale image, and a machine that bends the plane”Open any grayscale photo, zoom in far enough, and you find a grid of brightness values from 0 to 255. A 1080×1920 photo is a matrix with 1080 rows and 1920 columns. Every filter you have used — blur, sharpen, edge-detect — is arithmetic on that grid. Matrix as data.
Now take the tiny matrix and multiply every point of a sheet of graph paper by it. The grid stretches and shears into a new grid — still straight lines, still evenly spaced, but tilted. Matrix as action.
flowchart TD M["a matrix"] M --> D["DATA
rows are observations,
columns are features"] M --> A["ACTION
a linear map that sends
the basis vectors somewhere"] D --> D1["an image, a design matrix,
a batch of embeddings"] A --> A1["rotation, projection,
a neural network layer"] A --> A2["its COLUMNS are exactly
where the basis vectors land"] A2 --> KEY["so multiplication is
composition of actions,
not entry-by-entry arithmetic"]
The right-hand branch is the whole page. Once you believe the columns are the images of the basis vectors, the multiplication rule stops being a formula to memorise and becomes the only rule it could possibly be.
The math
Section titled “The math”Definition
Section titled “Definition”A real-valued matrix has rows and columns:
The entry sits in row , column — row index always first. A matrix is a row vector; an matrix is a column vector. The set of all real matrices is .
The book adds a remark that pays off later: by stacking its columns into one long vector, any
can be represented as a vector in . So
and are “the same” as vector spaces — a claim §2.7 makes
precise via Theorem 2.17 (equal dimension implies isomorphic). It is also exactly what
A.reshape(-1) does, and why a weight matrix can be handed to an optimiser as a flat parameter vector.
Addition and scaling: element by element
Section titled “Addition and scaling: element by element”Two matrices of the same shape add entry-by-entry, and multiplies every entry
by . No surprises, and both are exactly what NumPy’s + and * do.
That is worth flagging, because it sets up the trap: addition is element-wise and multiplication is not. The operator that looks most similar behaves least similarly.
Multiplication: the one that trips everyone
Section titled “Multiplication: the one that trips everyone”To multiply by , each entry of is a dot product of a row of with a column of :
The neighbouring dimensions must match — columns of equals rows of — and the result takes the outer dimensions:
Why that rule, and not some other one?
Section titled “Why that rule, and not some other one?”Because multiplication is composition. Applying and then should be the same as applying the single matrix , and that requirement forces the formula.
Here is the argument in one line. The -th column of any matrix is — the image of the -th basis vector. So the -th column of must be
which is a weighted sum of ‘s columns with weights from ‘s -th column — precisely . The rule is not a convention; it is the only rule under which “multiply the matrices” means “do one thing then the other”.
This also explains the dimension requirement without any memorisation: outputs vectors in , so must accept vectors in , so must have columns.
Order matters, and so does shape
Section titled “Order matters, and so does shape”Obvious once you think of composition: rotating then stretching is not stretching then rotating. But the book makes a sharper point with its Figure 2.5 — even when both products are defined, their shapes can differ. With being and being , is and is . They are not merely unequal; they do not live in the same space.
What does hold:
Associativity is why (A @ B) @ C and A @ (B @ C) agree mathematically — though they can differ
wildly in cost, which is the whole subject of optimising a chain of matrix products.
Identity, inverse, transpose
Section titled “Identity, inverse, transpose”The identity has ones on the diagonal and zeros elsewhere, and . Note the two different sizes: for a non-square the left and right identities are different matrices.
An inverse satisfies
and only square matrices can have one. When it exists is called regular, invertible or nonsingular; when it does not, singular or noninvertible. The book notes the inverse is unique when it exists — so “the” inverse is well defined.
For there is a closed form worth knowing:
valid if and only if . That quantity is the determinant (§4.1), and this is the first place it appears: as the thing that must not be zero.
The transpose has — the columns of written as the rows of . A matrix is symmetric when , which only a square matrix can be.
The four identities that are true, and the two that are not
Section titled “The four identities that are true, and the two that are not”The book gives the one-number sanity check for the false one: the scalar case is . If it fails for numbers it fails for matrices.
And a second false-looking-true claim: the sum of two symmetric matrices is always symmetric, but their product generally is not. The book’s counterexample is worth keeping:
Both factors are symmetric; the product is not. This matters more than it looks: covariance matrices are symmetric and products of them appear constantly, so assuming symmetry survives multiplication is a real bug waiting to happen. (It does survive in the special form , which is always symmetric — the fact §3.8 and Chapter 9 rely on.)
Worked example by hand
Section titled “Worked example by hand”The book’s Example 2.3, computed entry by entry. With
is . Each entry is one dot product:
| entry | row of | column of | arithmetic | value |
|---|---|---|---|---|
Now the other order. is — a different shape entirely:
Spot-checking two entries: the entry is ✓, and the entry is ✓.
And a inverse by the formula. For the determinant is , so
Check: ✓
See it move
Section titled “See it move”The lab below builds the action of a matrix one column at a time. Frames 2 and 3 place the images of and — which are the columns — and everything after them follows by linearity.
The dashed square is the unit square before the map; the amber parallelogram is its image, and its area is the determinant.
Watch the probe frame in particular. It computes and lands on exactly the same point as — because it is the same computation. That is linearity, and it is why knowing two columns tells you the whole map.
And a singular one, where the two columns are multiples of each other:
Both columns point the same way, so the image of the unit square has zero area. Nothing that lands on that line remembers where it came from.
The parallelogram has collapsed to a segment: determinant zero, no inverse. Information has been destroyed, and no matrix can undo that — which is the geometric content of “singular”.
From scratch
Section titled “From scratch”import numpy as np
# ---- the book's Example 2.3 ---------------------------------------------
A = np.array([[1.0, 2.0, 3.0],
[3.0, 2.0, 1.0]]) # 2x3
B = np.array([[0.0, 2.0],
[1.0, -1.0],
[0.0, 1.0]]) # 3x2
print("A @ B =\n", A @ B, " shape", (A @ B).shape)
print("B @ A =\n", B @ A, " shape", (B @ A).shape)
print("same shape?", (A @ B).shape == (B @ A).shape)
# ---- multiplication IS composition -------------------------------------
# The j-th column of A@B equals A applied to the j-th column of B.
for j in range(B.shape[1]):
print(f"col {j}: (A@B)[:,{j}] =", (A @ B)[:, j], " A @ B[:,{}] =".format(j), A @ B[:, j])
# ---- the columns are the images of the basis vectors --------------------
M = np.array([[2.0, 1.0], [0.0, 1.5]])
e1, e2 = np.array([1.0, 0.0]), np.array([0.0, 1.0])
print("\nM @ e1 =", M @ e1, " == first column ", M[:, 0])
print("M @ e2 =", M @ e2, " == second column", M[:, 1])
print("linearity: M @ (e1+e2) == M@e1 + M@e2 :", np.allclose(M @ (e1 + e2), M @ e1 + M @ e2))
# ---- @ versus * ---------------------------------------------------------
P = np.array([[1.0, 2.0], [3.0, 4.0]])
Q = np.array([[5.0, 6.0], [7.0, 8.0]])
print("\nP @ Q (matrix product):\n", P @ Q)
print("P * Q (Hadamard) :\n", P * Q)
# ---- inverse, by formula and by library --------------------------------
A2 = np.array([[4.0, 1.0], [2.0, 2.0]])
det = A2[0, 0] * A2[1, 1] - A2[0, 1] * A2[1, 0]
by_hand = np.array([[A2[1, 1], -A2[0, 1]], [-A2[1, 0], A2[0, 0]]]) / det
print("\ndet =", det)
print("inverse by formula:\n", np.round(by_hand, 6))
print("matches np.linalg.inv:", np.allclose(by_hand, np.linalg.inv(A2)))
print("A @ A^-1 == I:", np.allclose(A2 @ by_hand, np.eye(2)))
# ---- the book's Example 2.4: a 3x3 inverse pair ------------------------
A3 = np.array([[1.0, 2.0, 1.0], [4.0, 4.0, 5.0], [6.0, 7.0, 7.0]])
B3 = np.array([[-7.0, -7.0, 6.0], [2.0, 1.0, -1.0], [4.0, 5.0, -4.0]])
print("\nExample 2.4: A@B == I:", np.allclose(A3 @ B3, np.eye(3)),
" B@A == I:", np.allclose(B3 @ A3, np.eye(3)))
# ---- the identities: which hold and which do not ----------------------
R = np.array([[2.0, 1.0], [1.0, 3.0]])
S = np.array([[1.0, 0.0], [2.0, 1.0]])
print("\n(RS)^T == S^T R^T :", np.allclose((R @ S).T, S.T @ R.T))
print("(RS)^-1 == S^-1 R^-1 :", np.allclose(np.linalg.inv(R @ S),
np.linalg.inv(S) @ np.linalg.inv(R)))
print("(R+S)^-1 == R^-1 + S^-1 :", np.allclose(np.linalg.inv(R + S),
np.linalg.inv(R) + np.linalg.inv(S)))
print("scalar check 1/(2+4) vs 1/2+1/4:", 1 / (2 + 4), "vs", 1 / 2 + 1 / 4)
# ---- symmetry does not survive multiplication -------------------------
X = np.array([[1.0, 0.0], [0.0, 0.0]])
Y = np.array([[1.0, 1.0], [1.0, 1.0]])
XY = X @ Y
print("\nX symmetric:", np.allclose(X, X.T), " Y symmetric:", np.allclose(Y, Y.T))
print("X@Y =\n", XY, "\nX@Y symmetric:", np.allclose(XY, XY.T))
print("but A^T A always is:", np.allclose(A.T @ A, (A.T @ A).T))
# ---- stacking columns: R^{m x n} is R^{mn} ----------------------------
flat = A.reshape(-1, order="F") # column-major, as the book stacks
print("\nA shape", A.shape, "-> flattened", flat.shape, ":", flat)A @ B =
[[2. 3.]
[2. 5.]] shape (2, 2)
B @ A =
[[ 6. 4. 2.]
[-2. 0. 2.]
[ 3. 2. 1.]] shape (3, 3)
same shape? False
col 0: (A@B)[:,0] = [2. 2.] A @ B[:,0] = [2. 2.]
col 1: (A@B)[:,1] = [3. 5.] A @ B[:,1] = [3. 5.]
M @ e1 = [2. 0.] == first column [2. 0.]
M @ e2 = [1. 1.5] == second column [1. 1.5]
linearity: M @ (e1+e2) == M@e1 + M@e2 : True
P @ Q (matrix product):
[[19. 22.]
[43. 50.]]
P * Q (Hadamard) :
[[ 5. 12.]
[21. 32.]]
det = 6.0
inverse by formula:
[[ 0.333333 -0.166667]
[-0.333333 0.666667]]
matches np.linalg.inv: True
A @ A^-1 == I: True
Example 2.4: A@B == I: True B@A == I: True
(RS)^T == S^T R^T : True
(RS)^-1 == S^-1 R^-1 : True
(R+S)^-1 == R^-1 + S^-1 : False
scalar check 1/(2+4) vs 1/2+1/4: 0.16666666666666666 vs 0.75
X symmetric: True Y symmetric: True
X@Y =
[[1. 1.]
[0. 0.]]
X@Y symmetric: False
but A^T A always is: True
A shape (2, 3) -> flattened (6,) : [1. 3. 2. 2. 3. 1.]Three lines to notice. The same shape? False line is the book’s Figure 2.5 point: both products
exist and they are not even comparable. The col 0 lines confirm multiplication is composition,
column by column. And the scalar check, 0.1666… vs 0.75, is a one-second refutation of the
inverse-of-a-sum identity — if it fails for numbers, do not bother testing matrices.
On real data
Section titled “On real data”Reading the plot
Section titled “Reading the plot”The second figure makes a point that is easy to state and easy to forget. Both curves are parallel to
the reference line, so the naive loop and @ are doing the same number of arithmetic
operations. The four-orders-of-magnitude gap is entirely constant factors: a tuned BLAS keeps the
working set in cache, issues vector instructions, and never touches the Python interpreter.
The lesson is not “NumPy is faster”. It is that asymptotic complexity and wall-clock time are different questions, and for matrix work the constants are large enough to decide whether an experiment finishes today. It is also why §2.3 remarks that Gaussian elimination is “impractical” at scale despite being perfectly correct: cubic is cubic, whoever writes the loop.
Pitfalls
Section titled “Pitfalls”Compare
Section titled “Compare”| operation | element-wise? | shape rule | NumPy | commutative? |
|---|---|---|---|---|
| addition | yes | shapes must match exactly | A + B | yes |
| scalar multiplication | yes | any | 2 * A | yes |
| Hadamard product | yes | shapes must match exactly | A * B | yes |
| matrix product | no | inner dims must match | A @ B | no |
| transpose | — | A.T | — | |
| inverse | — | square, nonsingular only | np.linalg.inv(A) | — |
-
Why is matrix multiplication defined by that particular sum-of-products rule rather than element-wise?
Requiring that applying B then A equals applying the single matrix AB forces the formula. The element-wise product exists — it is the Hadamard product — it just does not compose maps.
pch.quizShowAnswer
B — Because it makes multiplication correspond to composing the two linear maps, one after the other — Requiring that applying B then A equals applying the single matrix AB forces the formula. The element-wise product exists — it is the Hadamard product — it just does not compose maps.
-
A is two by three and B is three by two. Both products are defined. What is true?
This is the book's Figure 2.5 point. Non-commutativity is not just about different entries — the two products can live in different spaces entirely.
pch.quizShowAnswer
C — AB is two by two and BA is three by three, so they are not even comparable — This is the book's Figure 2.5 point. Non-commutativity is not just about different entries — the two products can live in different spaces entirely.
-
Two symmetric matrices are multiplied together. Is the result symmetric?
The book's counterexample settles it. The sum of symmetric matrices is symmetric; the product usually is not. A-transpose-A is always symmetric, which is why that form is ubiquitous.
pch.quizShowAnswer
B — Generally not, though the sum always is — The book's counterexample settles it. The sum of symmetric matrices is symmetric; the product usually is not. A-transpose-A is always symmetric, which is why that form is ubiquitous.
-
What does the columns view say about a two by two matrix whose second column is twice its first?
Both basis vectors land on the same line, so every point does. The image of the unit square has zero area, the determinant is zero, and no inverse can exist because the map is not injective.
pch.quizShowAnswer
B — It maps the whole plane onto a single line, so it is singular and destroys information — Both basis vectors land on the same line, so every point does. The image of the unit square has zero area, the determinant is zero, and no inverse can exist because the map is not injective.
🧪 Try It Yourself
Section titled “🧪 Try It Yourself”Exercise 1 – Multiply two matrices
Section titled “Exercise 1 – Multiply two matrices”Exercise 2 – Order matters, and so does shape
Section titled “Exercise 2 – Order matters, and so does shape”Exercise 3 – The columns are the images of the basis vectors
Section titled “Exercise 3 – The columns are the images of the basis vectors”Exercise 4 – The inverse of a sum is not the sum of the inverses
Section titled “Exercise 4 – The inverse of a sum is not the sum of the inverses”Exercise 5 – Symmetry does not survive multiplication
Section titled “Exercise 5 – Symmetry does not survive multiplication”Recall card
Section titled “Recall card”- A matrix has two faces — data to be looked at, and a linear action doing the looking. Which one a page means is usually implicit.
- Stacking the columns turns an m-by-n matrix into a vector of length mn, which is why a weight matrix can be handed to an optimiser as a flat parameter vector.
- Addition is element-wise; multiplication is not. The element-wise product has its own name, the Hadamard product.
- The multiplication rule is forced by composition — requiring that applying B then A equal applying AB leaves no freedom in the formula.
- The columns of a matrix are the images of the basis vectors, so knowing where the basis goes determines the entire map.
- Even when both products are defined their shapes can differ — two-by-three times three-by-two gives two-by-two one way and three-by-three the other.
- The order flips under inverse and transpose — the inverse of a product is the product of inverses reversed, and likewise for the transpose.
- The inverse of a sum is not the sum of the inverses, and the scalar case refutes it in one line.
- A product of symmetric matrices is usually not symmetric, but A-transpose-A always is.
- The two-by-two inverse exists exactly when the determinant is nonzero — the first appearance of the quantity Chapter 4 is about.
- Asymptotic cost and wall-clock cost are different questions: a naive loop and a tuned BLAS both do n-cubed work, four orders of magnitude apart.
Next: the algorithm that actually solves these systems, pivot by pivot — Solving Systems of Linear Equations.
pch.coffeeTagline
pch.coffeeCtapch.feedbackHeading
pch.feedbackSubheading