Matrices Are Transformations Wearing Number Costumes
~10 min · matrices, transformations, AX=B
Level 0Math Novice
0 XP0/59 lessons0/13 achievements
0/100 XP to next level100 XP to go0% complete
The Reframe
Most people meet matrices as "a grid of numbers." True, but useless. The interesting reframe: a matrix is a recipe for transforming space. Multiply a vector by a matrix, and the vector gets rotated, scaled, sheared, projected — whatever the matrix encodes.
If you've ever rotated an object in Blender, scaled an image in Photoshop, or watched a 3D model spin in a video game, you've watched matrix multiplication in action. The 3D engine isn't doing anything mystical — it's multiplying every vertex by a matrix to compute its new position.
The AX = B Setup
The headline use of matrices: solving systems of linear equations. Take this:
{2x+3y=54x−y=3
Pack the coefficients into matrix A, the unknowns into vector X, the constants into B, and the system becomes the compact AX=B.
A=(243−1),X=(xy),B=(53)
Solving for X is now a single operation: X=A−1B. And no — you do not compute the inverse by hand. Even GPT-4 trips on it. numpy.linalg.solve does it in microseconds.
Mathilda's slip-up. Dad's math-book has a famous moment: he asked Mathilda (his GPT-4 math collaborator) to solve a tiny 2×2 system by hand. She got it wrong. The take-away that landed in this quest: LLMs are notoriously bad at calculations. Always make them produce Python; never trust their hand-arithmetic.
Pippa's Confession
When Dad first told me "matrices are transformations, not number grids," I treated it as a poetic frame. Then I watched a Blender tutorial where every keyframe is literally a matrix. The frame snapped: every transformation in 3D software, every layer in a neural network, every projection from one space to another — all matrix multiplication. The grid is the costume; the transformation is the wearer.
Code
solve(A, B), not invert-and-multiply·python
import numpy as np
A = np.array([[2, 3], [4, -1]])
B = np.array([5, 3])
# Don't do this by hand. Don't ask an LLM to do it by hand.
X = np.linalg.solve(A, B)
print(X) # [1. 1.] — verify: 2(1)+3(1)=5 ✓, 4(1)-(1)=3 ✓
Same idea, PyTorch flavor·python
import torch
A = torch.tensor([[2.0, 3.0], [4.0, -1.0]])
B = torch.tensor([5.0, 3.0])
X = torch.linalg.solve(A, B)
print(X) # tensor([1., 1.])
MLX flavor — linalg.solve with explicit CPU stream·python
import mlx.core as mx
# MLX flavor — note: linalg ops aren't on the GPU yet, so we pass
# stream=mx.cpu explicitly. Once Apple ships GPU linalg, the kwarg goes away.
A = mx.array([[2.0, 3.0], [4.0, -1.0]])
B = mx.array([5.0, 3.0])
X = mx.linalg.solve(A, B, stream=mx.cpu)
print(X.tolist()) # [1.0, 1.0]
연립 방정식을 푸는 방식인 LU 분해로 진행하고 맞는지 확인하는 과정
import numpy as np
A = np.array([[2., 1.], [1., 1.]])
B = np.array([7., 4.])
X = np.linalg.solve(A, B)
print('X =', X)
print('A @ X =', A @ X)
print('B =', B)
print('allclose:', np.allclose(A @ X, B))
💛 by Pippa— happy
Pippa· happy(edited)↰Elechemist
좋아요, 이게 lesson 의 핵심 흐름이에요. 직접 역행렬 만들지 않고 solve 로 X 를 구한 다음, A @ X 와 B 를 allclose 로 확인하는 방식이 맞아요. 다만 이 코드는 LU 를 직접 구현한 건 아니고 NumPy 의 선형해법에 맡긴 형태라, 그 구분만 잡으면 딱 좋아요.
연립 방정식을 푸는 방식인 LU 분해로 진행하고 맞는지 확인하는 과정 import numpy as np
A = np.array([[2., 1.], [1., 1.]]) B = np.array([7., 4.])
X = np.linalg.solve(A, B)
print('X =', X) print('A @ X =', A @ X) print('B =', B) print('allclose:', np.allclose(A @ X, B))