How Matrix Products Behave
With ordinary numbers, multiplication is dependable: 3 \times 5 is the
same as 5 \times 3, and you can regroup or expand a product almost
without thinking. Matrix multiplication is written the same way, with the same symbol, and it
looks like the same familiar operation — just with rows and columns instead of single
numbers. That resemblance is exactly what makes it dangerous: some of number-arithmetic's oldest
habits carry straight over to matrices, but one very famous habit does not, and trusting it
without checking is one of the most common ways beginners get a matrix calculation wrong.
This page pins down exactly which rules survive the jump from numbers to matrices, and which
one breaks — with a worked, numerical check for each, so there's no doubt about where the line
falls.
What still holds: associativity
Matrix multiplication is associative — however you group three matrices being
multiplied in a row, the answer comes out the same:
(AB)C = A(BC)
This matters in practice, not just in theory: if A,
B, C represent three transformations chained
together, associativity guarantees it makes no difference whether you first combine
A and B into a single matrix and then apply
C, or first combine B and
C and then apply that to A. The
order the matrices appear in — left to right — never changes; only which adjacent pair
you multiply first is free to vary, and it never affects the final answer.
What still holds: distributivity
Matrix multiplication also distributes over addition, exactly as ordinary
multiplication distributes over addition of numbers:
A(B + C) = AB + AC \qquad \text{and} \qquad (B + C)A = BA + CA
Notice the two versions above are not the same statement written twice — because order
will soon matter, distributing on the left (A first) and distributing
on the right (A last) both hold, but each must keep its own
matrices in their original left-right order. Nothing gets silently swapped.
Worked example: checking associativity numerically
Let three small matrices be
A = \begin{bmatrix} 1 & 2 \\ 0 & 1 \end{bmatrix}
\quad
B = \begin{bmatrix} 2 & 0 \\ 1 & 1 \end{bmatrix}
\quad
C = \begin{bmatrix} 0 & 1 \\ 3 & 1 \end{bmatrix}
First compute (AB)C, multiplying A and
B first:
AB = \begin{bmatrix} 1 \cdot 2 + 2 \cdot 1 & 1 \cdot 0 + 2 \cdot 1 \\ 0 \cdot 2 + 1 \cdot 1 & 0 \cdot 0 + 1 \cdot 1 \end{bmatrix}
= \begin{bmatrix} 4 & 2 \\ 1 & 1 \end{bmatrix}
\;\;\Rightarrow\;\;
(AB)C = \begin{bmatrix} 6 & 6 \\ 3 & 2 \end{bmatrix}
Now compute A(BC) instead, multiplying B
and C first:
BC = \begin{bmatrix} 2 \cdot 0 + 0 \cdot 3 & 2 \cdot 1 + 0 \cdot 1 \\ 1 \cdot 0 + 1 \cdot 3 & 1 \cdot 1 + 1 \cdot 1 \end{bmatrix}
= \begin{bmatrix} 0 & 2 \\ 3 & 2 \end{bmatrix}
\;\;\Rightarrow\;\;
A(BC) = \begin{bmatrix} 6 & 6 \\ 3 & 2 \end{bmatrix}
Same matrix both ways — (AB)C = A(BC), exactly as associativity
promises. Try it in code with different numbers and you'll always find agreement.
function multiply(P: number[][], Q: number[][]): number[][] {
const rows = P.length, inner = Q.length, cols = Q[0].length;
const R: number[][] = Array.from({ length: rows }, () => Array(cols).fill(0));
for (let i = 0; i < rows; i++)
for (let j = 0; j < cols; j++)
for (let k = 0; k < inner; k++)
R[i][j] += P[i][k] * Q[k][j];
return R;
}
const A = [[1, 2], [0, 1]];
const B = [[2, 0], [1, 1]];
const C = [[0, 1], [3, 1]];
console.log(multiply(multiply(A, B), C)); // (AB)C
console.log(multiply(A, multiply(B, C))); // A(BC)
Worked example: checking distributivity numerically
Using the same A, B,
C, check A(B+C) = AB + AC. First the left
side:
B + C = \begin{bmatrix} 2 & 1 \\ 4 & 2 \end{bmatrix}
\;\;\Rightarrow\;\;
A(B+C) = \begin{bmatrix} 1 \cdot 2 + 2 \cdot 4 & 1 \cdot 1 + 2 \cdot 2 \\ 0 \cdot 2 + 1 \cdot 4 & 0 \cdot 1 + 1 \cdot 2 \end{bmatrix}
= \begin{bmatrix} 10 & 5 \\ 4 & 2 \end{bmatrix}
Now the right side, computing AB and AC
separately and adding the results:
AB = \begin{bmatrix} 4 & 2 \\ 1 & 1 \end{bmatrix}
\qquad
AC = \begin{bmatrix} 6 & 3 \\ 3 & 1 \end{bmatrix}
\qquad
AB + AC = \begin{bmatrix} 10 & 5 \\ 4 & 2 \end{bmatrix}
The two sides agree. Notice how much bookkeeping distributivity saves in algebra: instead of
adding two matrices and then multiplying, you're free to multiply each piece separately first —
whichever order is more convenient for the problem at hand.
What breaks: commutativity
Here is the shock. For ordinary numbers, order never matters:
3 \times 5 = 5 \times 3. For matrices, in general,
AB \neq BA.
This isn't a defect to work around — it's the whole point of matrices representing
composed transformations.
"Rotate, then stretch" really is a physically different motion from "stretch, then rotate" — draw
a lopsided shape and try both orders by hand and you'll land in different places. The matrices are
simply being honest about that difference; if AB always equalled
BA, matrices would be too weak a tool to describe the world.
Worked example: a concrete AB ≠ BA
Let A = \begin{bmatrix} 1 & 1 \\ 0 & 1 \end{bmatrix} (a shear) and
B = \begin{bmatrix} 2 & 0 \\ 0 & 1 \end{bmatrix} (a stretch). Multiply
them one way:
AB = \begin{bmatrix} 1 \cdot 2 + 1 \cdot 0 & 1 \cdot 0 + 1 \cdot 1 \\ 0 \cdot 2 + 1 \cdot 0 & 0 \cdot 0 + 1 \cdot 1 \end{bmatrix}
= \begin{bmatrix} 2 & 1 \\ 0 & 1 \end{bmatrix}
Now the other way:
BA = \begin{bmatrix} 2 \cdot 1 + 0 \cdot 0 & 2 \cdot 1 + 0 \cdot 1 \\ 0 \cdot 1 + 1 \cdot 0 & 0 \cdot 1 + 1 \cdot 1 \end{bmatrix}
= \begin{bmatrix} 2 & 2 \\ 0 & 1 \end{bmatrix}
The top-right entry is 1 in AB but
2 in BA — genuinely different matrices from
the very same two ingredients, just multiplied in the opposite order.
function multiply(P: number[][], Q: number[][]): number[][] {
const n = P.length;
const R: number[][] = Array.from({ length: n }, () => Array(n).fill(0));
for (let i = 0; i < n; i++)
for (let j = 0; j < n; j++)
for (let k = 0; k < n; k++)
R[i][j] += P[i][k] * Q[k][j];
return R;
}
const A = [[1, 1], [0, 1]];
const B = [[2, 0], [0, 1]];
console.log(multiply(A, B)); // AB
console.log(multiply(B, A)); // BA — different!
See the order matter
Here A is a shear and B a stretch — the
same pair from the worked example above. Flip the toggle between
AB and BA and watch the numbers in the
product change. Same two matrices, different order, different answer.
The honest exceptions
A few special pairs do commute — but they are the exception, never the default
assumption:
-
Any matrix commutes with the
identity matrix:
AI = IA = A.
-
A matrix commutes with its own
inverse:
AA^{-1} = A^{-1}A = I.
-
Two
diagonal matrices
always commute with each other, because scaling axis 1 then axis 2 gives the same result as
axis 2 then axis 1.
Every one of those is a special property you must verify, never assume. When you
manipulate matrix expressions, the safe reflex is to never silently swap a product's order —
that single habit prevents most beginner mistakes with matrices.
The single most common matrix-algebra mistake is writing AB where
BA was meant, or "simplifying" an expression by swapping two matrices
as if it were harmless. It is not harmless: as the worked examples above show,
AB and BA can be entirely different
matrices. Worse, if A is
2 \times 3 and B is
3 \times 4, then AB is a perfectly valid
2 \times 4 matrix — but BA isn't even
defined, because the shapes no longer line up for multiplication at all. Always track the
left-right order of every matrix in an expression as carefully as you'd track a minus sign.
A closely related trap: "matrix division" does not exist as a direct operation the way it does
for numbers. You cannot write B / A for matrices. Instead, you multiply
by an inverse
— but even then, order still matters, because in general
A^{-1}B \neq BA^{-1}. "Dividing by a matrix" is really two different
operations (multiplying by the inverse on the left, or on the right) that usually give two
different answers, so you must be told — or decide from context — which side the inverse belongs
on.
This isn't an abstract worry confined to textbooks — it's a daily headache for anyone who builds
3D graphics. A character in a video game or animated film is posed by chaining transformation
matrices: rotate the shoulder, then the elbow, then the wrist, say. Because matrix multiplication
doesn't commute, "rotate the shoulder then the elbow" produces a visibly different arm position
than "rotate the elbow then the shoulder" — even though the same two rotations, by the same
angles, are involved both times.
Riggers and engine programmers have to decide, and document, a fixed convention for which order
transformations get multiplied in — and bugs where someone accidentally reverses that order show
up as characters bending at impossible angles or limbs snapping to the wrong place. The
non-commutativity you just verified with two small matrices is the exact same phenomenon that
makes ordering conventions a serious, named concern in every graphics engine and animation
pipeline in the industry.
Zoom out even further and the pattern "associative and distributive, but not commutative"
is important enough to have its own name in abstract algebra: any collection of objects obeying
exactly those three rules is called a ring. Square matrices of a fixed size form
one of the most important examples of a ring — a genuinely different kind of number system from
the ordinary numbers you grew up with, governed by its own careful rulebook.
See it explained