18. Composition of transformations
Every prior lesson in this module studied a single transformation. This closing lesson studies what happens when two are chained together, and confirms directly a claim §16.2 and §18.2 both leaned on without proof: composing linear transformations is matrix multiplication.
Composition is linear
For T_1:U\to V and T_2:V\to W, the composition T_2\circ T_1:U\to W is (T_2\circ T_1)(\vec u)=T_2(T_1(\vec u)) — apply T_1 first, then T_2, read right-to-left exactly like ordinary function composition. If T_1 and T_2 are both linear, so is T_2\circ T_1:
(T_2\circ T_1)(\vec u+\vec v)=T_2(T_1(\vec u+\vec v))=T_2(T_1(\vec u)+T_1(\vec v))=T_2(T_1(\vec u))+T_2(T_1(\vec v))
using T_1's linearity in the middle step and T_2's in the last — homogeneity follows identically. Composing linear maps never leaves the world of linear maps.
The standard matrix of a composition
If A_1 is T_1's standard matrix and A_2 is T_2's, then A_2A_1 is (T_2\circ T_1)'s standard matrix:
(T_2\circ T_1)(\vec x)=T_2(T_1(\vec x))=T_2(A_1\vec x)=A_2(A_1\vec x)=(A_2A_1)\vec x
using §18.1's T(\vec x)=A\vec x twice and §16.2's associativity of matrix multiplication once. This is precisely why matrix multiplication is defined the way it is — the row-times-column rule from §16.2 isn't an arbitrary convention, it's forced by requiring matrix multiplication to correctly represent function composition.
Order matters, and matches function order exactly: A_2A_1 means "T_1 first, then T_2" — the matrix closest to the vector acts first, same as T_2(T_1(\vec x)) reads T_1 innermost. §16.2's noncommutativity, AB\neq BA in general, is now visibly the statement that doing two things in a different order gives a different result — exactly what §18.2 demonstrated with rotate-then-shear versus shear-then-rotate.
Associativity, and identity
Composition is associative, (T_3\circ T_2)\circ T_1=T_3\circ(T_2\circ T_1), matching §16.2's (A_3A_2)A_1=A_3(A_2A_1) directly — both sides just mean "apply all three, in this order," and parenthesization never changes that. The identity transformation I(\vec v)=\vec v composes with anything to leave it unchanged, T\circ I=I\circ T=T, matching §16.2's identity matrix.
Inverses compose in reverse, matching §16.3's (AB)^{-1}=B^{-1}A^{-1}: if T_1,T_2 are both isomorphisms (§18.4), so is T_2\circ T_1, and
(T_2\circ T_1)^{-1}=T_1^{-1}\circ T_2^{-1}
— to undo "T_1 then T_2," undo T_2 first, then T_1, exactly the "undress in reverse order" intuition from §16.3.
Doing it in Python
import numpy as np
A1 = np.array([[1, 1], [0, 1]]) # T1: shear
A2 = np.array([[2, 0], [0, 3]]) # T2: scale
v = np.array([1, 1])
# Composition two ways: matrix product, or applying functions in sequence
combined = A2 @ A1
via_functions = A2 @ (A1 @ v)
via_matrix = combined @ v
print("combined matrix A2 @ A1 =")
for row in combined.tolist():
print(row)
print("\nT2(T1(v)) =", list(via_functions))
print("(A2 A1) v =", list(via_matrix))
print("match:", np.array_equal(via_functions, via_matrix))
combined matrix A2 @ A1 =
[2, 2]
[0, 3]
T2(T1(v)) = [4, 3]
(A2 A1) v = [4, 3]
match: True
Confirming inverses reverse order for a composition of isomorphisms:
import numpy as np
A1 = np.array([[1., 1.], [0., 1.]])
A2 = np.array([[2., 0.], [0., 3.]])
combined_inv = np.linalg.inv(A2 @ A1)
reversed_inv = np.linalg.inv(A1) @ np.linalg.inv(A2)
print("(A2 A1)^-1 =")
for row in combined_inv.tolist():
print([round(v, 4) for v in row])
print("A1^-1 A2^-1 =")
for row in reversed_inv.tolist():
print([round(v, 4) for v in row])
print("match:", bool(np.allclose(combined_inv, reversed_inv)))
(A2 A1)^-1 =
[0.5, -0.3333]
[0.0, 0.3333]
A1^-1 A2^-1 =
[0.5, -0.3333]
[0.0, 0.3333]
match: True
Worked example
T_1(x,y)=(x+y,\,y) and T_2(x,y)=(2x,\,x-y). Find the standard matrix of T_2\circ T_1 and use it to compute (T_2\circ T_1)(3,1).
A_1=\begin{pmatrix}1&1\\0&1\end{pmatrix}, A_2=\begin{pmatrix}2&0\\1&-1\end{pmatrix} (columns from each T_i(\vec e_1),T_i(\vec e_2), §18.1).
A_2A_1=\begin{pmatrix}2&0\\1&-1\end{pmatrix}\begin{pmatrix}1&1\\0&1\end{pmatrix}=\begin{pmatrix}2&2\\1&0\end{pmatrix}
(T_2\circ T_1)(3,1)=\begin{pmatrix}2&2\\1&0\end{pmatrix}\begin{pmatrix}3\\1\end{pmatrix}=\begin{pmatrix}8\\3\end{pmatrix}
\boxed{(T_2\circ T_1)(3,1)=(8,3)}
Sanity check, applying the functions directly instead: T_1(3,1)=(3+1,1)=(4,1); T_2(4,1)=(2(4),\,4-1)=(8,3) ✓ — matches the matrix computation exactly, confirming A_2A_1 really does represent "T_1 then T_2" and not the other order.
Your turn
1. For the worked example's T_1,T_2, compute T_1\circ T_2 instead (the other order) applied to (3,1), and confirm it differs from (8,3).
2. If A_1 represents a 90° rotation and A_2 represents a 45° rotation, what single transformation does A_1A_2 represent?
3. True or false: if T_1 and T_2 are both isomorphisms, then T_2\circ T_1 is automatically an isomorphism too.
Solutions
1. T_2(3,1)=(2(3),\,3-1)=(6,2). T_1(6,2)=(6+2,\,2)=(8,2). So (T_1\circ T_2)(3,1)=(8,2)\neq(8,3)=(T_2\circ T_1)(3,1) — confirming order genuinely changes the result, matching §16.2's noncommutativity made concrete.
2. A 135° rotation. By §18.2's composition rule for rotations, R_{\theta_1}R_{\theta_2}=R_{\theta_1+\theta_2}: A_1A_2=R_{90°}R_{45°}=R_{135°} — rotating by 45° then by 90° is the same as one rotation by their sum. (Rotations are one of the few cases where the composition genuinely is commutative — R_{90°}R_{45°}=R_{45°}R_{90°}=R_{135°} either way — though this is special to rotations, not linear maps in general.)
3. True. Both are bijective (§18.4), and a composition of bijections is a bijection (composing two invertible functions gives an invertible function, with inverse T_1^{-1}\circ T_2^{-1} as derived above) — and composition of linear maps is linear, shown at the top of this lesson. Bijective and linear is exactly the definition of an isomorphism.
Check yourself in code
For T_1(x,y)=(x,\,x+y) and T_2(x,y)=(y,\,x), find the standard matrix of T_2\circ T_1 and apply it to (2,5).
Print exactly this:
A2 @ A1 =
[1, 1]
[1, 0]
result = [7, 2]
import numpy as np
A1 = np.array([[1, 0], [1, 1]])
A2 = np.array([[0, 1], [1, 0]])
combined = A2 @ A1
print("A2 @ A1 =")
for row in combined.tolist():
print(row)
# apply combined to (2, 5) and print "result = ..."
import numpy as np
A1 = np.array([[1, 0], [1, 1]])
A2 = np.array([[0, 1], [1, 0]])
combined = A2 @ A1
print("A2 @ A1 =")
for row in combined.tolist():
print(row)
v = np.array([2, 5])
print("result =", list(combined @ v))
Composing linear transformations is linear, and its standard matrix is the product of the individual standard matrices, applied in the same right-to-left order as function composition — the exact reason matrix multiplication was defined the way §16.2 defined it. Order matters (A_2A_1\neq A_1A_2 in general), and inverses reverse it, (T_2\circ T_1)^{-1}=T_1^{-1}\circ T_2^{-1}.
This closes Module 18. Every transformation studied here has been described in a fixed, standard basis. Module 19 asks the natural next question: is there a better basis — one in which a transformation's matrix becomes as simple as possible? The answer starts with eigenvalues and eigenvectors.