EVERYTHING AIAI engineering, made visual
0/23 complete
LESSON 17 · MATHEMATICS × AI · BUILD

The machine,
run backwards.

Ax = b asks which input x the transformation A turns into b. Two lines cross once; columns mix to hit a target; and when they cannot, least squares finds the closest reachable point.

100 MIN · 8 CHAPTERSPREREQ · LESSONS 01–03
FIG. 17 / ONE SYSTEM, TWO PICTURES
X = (2, 1) same answer, both views col 1 col 2 mix
LESSON 17TYPE · BUILD~100 MINPREREQ · LESSONS 01–03ORIGINAL LESSON ↗
THE 60-SECOND VERSIONThen show me both pictures ↓
01 / ROW PICTURE, COLUMN PICTURE

One equation, two questions.

The row picture asks where the lines (or planes) of the equations meet. The column picture asks how much of each column of A to mix to build b. The first is where constraints agree; the second is what the machine can reach.

x₁·col₁ + x₂·col₂ = b
02 / ELIMINATION → LU

Factor once, solve many.

Row operations turn A into an upper-triangular U; the multipliers used along the way are exactly the lower-triangular L, so A = LU. Pay O(n³) once, then every new right-hand side costs only two triangular solves, O(n²).

A = LU · A = LLᵀ (symmetric positive definite)
03 / NO EXACT SOLUTION

Tall systems get the closest point.

With more data points than parameters, b is usually outside the column space, so no x is exact. Minimize the squared error instead: the normal equations AᵀA x = Aᵀb give the line that balances every residual — this is linear regression.

minimize ‖Ax − b‖² → AᵀA x = Aᵀb
MENTAL MODEL IN ONE SENTENCE

Ax = b asks which input x the machine A turns into b: square and well-behaved gives one answer found by elimination, tall and noisy gives no exact answer so least squares takes the closest, and the condition number tells you how many digits of whichever answer to believe.

By the end you will be able to solve small systems by elimination with partial pivoting, explain why LU and Cholesky amortize the work, read an overdetermined problem as a projection, derive the normal equations, use κ to predict digit loss, and run a Jacobi sweep on a system too big to factor.

TWO WAYS TO READ Ax = b

One equation.
Two pictures.

A linear system is a pile of straight-line constraints, and it is also a recipe for building a target out of columns. Both readings describe the same x, and each one answers a different question.

A linear system collects m equations in n unknowns. In matrix form it collapses into one line: Ax = b. The matrix A holds the known coefficients, b holds the known outputs, and x is the vector of unknowns we want. Every equation is linear — no squares, no products of unknowns, no curves.

The row picture reads A one row at a time: each equation is a line in 2D (a plane in 3D, a hyperplane beyond that), and the solution is the point where all of them meet. The column picture reads A one column at a time: each column is a vector, and Ax is a mixture of those columns with x saying how much of each to use. The solution is the mix that lands exactly on b.

2x + y = 5 A = [[2, 1], [1, −1]], b = [5, 1] x − y = 1 row picture: the lines y = 5 − 2x and y = x − 1 cross at (2, 1) column picture: x₁·[2, 1] + x₂·[1, −1] = [5, 1] with x = (2, 1): 2·[2, 1] + 1·[1, −1] = [4+1, 2−1] = [5, 1] ✓

One system, two pictures

Move the six coefficients. In the row picture the solution is where the two lines cross; in the column picture it is how much of each column to mix to land exactly on b.

A = [[2, 1], [1, -1]] b = [5, 1] det A = 2·-1 − 1·1 = -3 row picture: lines meet once at (2, 1) column picture: 2·[2, 1] + 1·[1, -1] = [5, 1] ✓

The row picture is two constraints; the column picture is one target built from two ingredients. Same equation, different question.

Worked check: the same answer from both pictures

The row picture solves two equations by substitution. The column picture solves the same problem by bookkeeping on vectors. Watch them land on the same point.

Row picture y = 5 − 2x and y = x − 1 5 − 2x = x − 1 → 6 = 3x → x = 2 y = 2 − 1 = 1 solution (2, 1) Column picture A = [[2, 1], [1, −1]] columns: col1 = [2, 1], col2 = [1, −1] 2·col1 + 1·col2 = [4, 2] + [1, −1] = [5, 1] = b ✓ Sanity check: det A = 2·(−1) − 1·1 = −3 ≠ 0 a non-zero determinant means the columns point in genuinely different directions — exactly one mixture reaches b

Numeric check of the answer in the original equations: 2·2 + 1 = 5 ✓ and 2 − 1 = 1 ✓. The row picture and the column picture are not two methods; they are two readings of the same matrix-vector product.

ONE ANSWER, NONE, OR INFINITELY MANY

Rank decides
how many answers exist.

Before solving anything, ask whether the columns of A point in enough independent directions to reach b. The rank is the count of those directions, and it separates the three possible outcomes.

The rank of A is the number of linearly independent rows — which equals the number of independent columns. It is computed by running elimination and counting the pivots. Rank is what survives the row operations; it measures how many genuine directions the system can move in.

For a square n × n system, rank n means the columns are independent, the determinant is non-zero, and exactly one x reaches any b. Rank less than n means the columns are dependent: some direction of b may be unreachable, and any reachable point is reachable in infinitely many ways. The system is singular.

one solutionrank 2 · det ≠ 0no solutionrank 1 · inconsistentinfinitely manyrank 1 · consistent
For a square system the determinant decides whether the columns are independent. When det = 0 the lines are parallel or identical, and only the right-hand side decides between “none” and “infinitely many”.
What elimination findsRankSolutionsPicture in 2D
n pivots, no contradictionn (full)exactly onelines cross at a point
a pivot row [0 … 0 | non-zero]< nnone — inconsistentparallel lines
a zero row [0 … 0 | 0]< ninfinitely manythe same line twice
Worked check: three systems, three outcomes, one elimination habit

Run elimination on each system and read the last row. The same 2 × 2 coefficient matrix can produce any of the three outcomes depending only on the right-hand side.

A1 = [[2, 1], [1, −1]], b = [5, 1] det = 2·(−1) − 1·1 = −3 ≠ 0, rank 2 one solution: x = (2, 1) check: 2·2+1 = 5 ✓, 2−1 = 1 ✓ A2 = [[1, 2], [2, 4]], b = [3, 6] R2 ← R2 − 2·R1: [0, 0 | 0] rank 1, consistent → infinitely many: x₂ = t (free), x₁ = 3 − 2t check t = 0: (3, 0) → 3 ✓, 6 ✓ t = 1: (1, 1) → 3 ✓, 6 ✓ A3 = [[1, 2], [2, 4]], b = [3, 7] R2 ← R2 − 2·R1: [0, 0 | 1] 0 = 1 is impossible → no solution, no matter what x is

Overdetermined systems (m > n, more equations than unknowns) are the normal case in machine learning: the fourth data point rarely lands on the line through the first three. Generic data puts b outside the column space, and that is precisely when least squares takes over.

GAUSSIAN ELIMINATION & PARTIAL PIVOTING

Make it triangular.
Then solve from the bottom up.

Elimination is the workhorse: two legal row moves turn any square system into an upper-triangular one whose last equation has a single unknown. Pivoting is what keeps the arithmetic honest.

Two operations leave the solution set untouched: swap two rows, and subtract a multiple of one row from another. Gaussian elimination uses them to zero out every entry below the diagonal, column by column. What remains is an upper-triangular system, and back substitution solves it from the last equation upward — one unknown at a time.

The multiplier that clears entry (i, k) is m = A[i][k] / A[k][k]. The divisor A[k][k] is the pivot. If it is zero the algorithm stops; if it is tiny, every rounding error already present in that row is multiplied by a huge number. Partial pivoting fixes both problems by swapping the row with the largest absolute entry in the pivot column into position first. The cost is O(n³) either way — about a billion multiply–subtracts for a 1000 × 1000 system.

Gaussian elimination, one operation at a time

Step through row operations until the matrix is upper triangular, then watch back substitution fill in the solution. The toggle turns partial pivoting on and off.

A = [2, 1, 1], [4, 3, 3], [2, 3, 1] b = [8, 20, 12] Start: write the augmented matrix [A | b]. pivot: none row updates so far: 0 (a full solve costs ≈ n³/3 multiply–subtract pairs — when it completes)

Try the tiny-pivot system with pivoting off: dividing by 0.001 makes the multiplier 1000 and every later digit pays for it. Pivoting swaps first and keeps every multiplier at or below 1.

Worked example: the lesson's 3×3, every row operation, plus the tiny-pivot rescue
Augmented [A | b]: | 2 1 1 | 8 | | 4 3 3 | 20 | | 2 3 1 | 12 | column 1: multiplier for R2 is 4/2 = 2, for R3 is 2/2 = 1 R2 ← R2 − 2·R1 = [4−4, 3−2, 3−2 | 20−16] = [0, 1, 1 | 4] R3 ← R3 − 1·R1 = [2−2, 3−1, 1−1 | 12−8] = [0, 2, 0 | 4] column 2: multiplier for R3 is 2/1 = 2 R3 ← R3 − 2·R2 = [0, 2−2, 0−2 | 4−8] = [0, 0, −2 | −4] upper triangular: | 2 1 1 | 8 | | 0 1 1 | 4 | | 0 0 −2 | −4 | back substitution, bottom up: −2x₃ = −4 → x₃ = 2 x₂ + 2 = 4 → x₂ = 2 2x₁ + 2 + 2 = 8 → x₁ = 2 check: 2·2+2+2 = 8 ✓ 4·2+3·2+3·2 = 20 ✓ 2·2+3·2+2 = 12 ✓

Why pivoting matters — a second worked example. Take A = [[0.0001, 1], [1, 1]] and b = [1, 2]. The exact solution is x₁ = 1/0.9999 ≈ 1.0001 and x₂ ≈ 0.9999. Simulate three-significant-digit arithmetic (a teaching model, not float64):

No pivot: m = 1 / 0.0001 = 10,000 R2 ← R2 − 10,000·R1 = [0, 1 − 10,000 | 2 − 10,000] = [0, −9,999 | −9,998] → [0, −1.00e4 | −1.00e4] x₂ = 1.00 x₁ = (1 − 1.00) / 0.0001 = 0 ✗ true value is 1.0001 With partial pivoting (swap the rows first): [ 1 1 | 2 ] [ 0.0001 1 | 1 ] m = 0.0001 R2 ← R2 − 0.0001·R1 = [0, 0.9999 | 0.9998] → [0, 1.00 | 1.00] x₂ = 1.00 x₁ = (2 − 1.00) / 1 = 1.00 ✓ correct to three digits

The update R2 − m·R1 multiplies whatever rounding error lives in R1 by m. Keeping m ≤ 1 — which is exactly what swapping in the largest pivot achieves — stops that amplification. In exact arithmetic the two orders agree perfectly; in finite arithmetic they can differ in every digit.

Quick check

In the unpivoted 2×2 example, the multiplier was 10,000. What actually went wrong?

LU & CHOLESKY · FACTOR ONCE, SOLVE MANY

Elimination, bottled
for reuse.

Elimination secretly factors A into two triangular matrices. Once those exist, every new right-hand side costs O(n²) instead of O(n³) — and symmetric positive definite matrices get a half-price version.

During elimination, the multipliers you compute are not throwaway scrap. Collect them below the diagonal, put 1s on the diagonal, and you have a lower-triangular matrix L. The eliminated result is an upper-triangular matrix U, and together they satisfy A = LU. With row swaps the identity becomes PA = LU, where P records the permutation.

Solving with the factors splits one hard problem into two easy ones. Write Ax = b as LUx = b, then let y = Ux: first solve Ly = b top-down (forward substitution), then Ux = y bottom-up (back substitution). Each triangular solve is O(n²), so the O(n³) factorization is paid once and reused by every future b.

When A is symmetric (A = Aᵀ) and positive definite (every eigenvalue > 0), it has a matrix square root: A = LLᵀ, the Cholesky decomposition. It needs only the lower triangle, costs about n³/3 operations instead of 2n³/3, and fails loudly — a negative number under the square root — if the matrix was not positive definite after all. Covariance matrices, Gaussian-process kernel matrices, and the ridge matrix XᵀX + λI are all symmetric positive definite.

Factor once: LU vs Cholesky

Edit the symmetric matrix. Both panels factor the same A — LU keeps both triangles, Cholesky needs only the lower one and half the work.

A =
A = L @ U (Doolittle, no pivoting) L = [[1, 0, 0], [3, 1, 0], [-4, 5, 1]] U = [[4, 12, -16], [0, 1, 5], [0, 0, 9]] steps — each multiplier is stored in L: l21 = 12 / 4 = 3 (row 2 − 3·row 1) l31 = -16 / 4 = -4 (row 3 − -4·row 1) l32 = 5 / 37 = 5 (row 3 − 5·row 2) check: max |A − L·U| = 0 cost: O(2n³/3) ≈ 666,666,667 multiply–subtracts at n = 1,000
A = L @ Lᵀ (Cholesky) L = [[2, 0, 0], [6, 1, 0], [-8, 5, 3]] steps — the square roots are why SPD is required: l11 = √(4 − Σ squares) = √4 = 2 l21 = (12 − Σ products) / 2 = 6 l22 = √(37 − Σ squares) = √1 = 1 l31 = (-16 − Σ products) / 2 = -8 l32 = (-43 − Σ products) / 1 = 5 l33 = √(98 − Σ squares) = √9 = 3 check: max |A − L·Lᵀ| = 0 cost: O(n³/3) ≈ 333,333,333 multiply–subtracts at n = 1,000

Half the storage, half the arithmetic: Cholesky exploits the symmetry that LU ignores. The price is the requirement: symmetric, and every eigenvalue positive.

Derivation: read L off the multipliers, and Cholesky twice by hand
From the lesson's elimination, the multipliers were 2 (R2), 1 (R3, first pass) and 2 (R3, second pass): A = L @ U | 2 1 1 | | 1 0 0 | | 2 1 1 | | 4 3 3 | = | 2 1 0 | @ | 0 1 1 | | 2 3 1 | | 1 2 1 | | 0 0 −2 | check row 2: 2·[2,1,1] + 1·[0,1,1] = [4,3,3] ✓ check row 3: 1·[2,1,1] + 2·[0,1,1] + 1·[0,0,−2] = [2,3,1] ✓ Cholesky of A = [[4, 2], [2, 5]]: want L = [[l₁₁, 0], [l₂₁, l₂₂]] with L Lᵀ = A l₁₁² = 4 → l₁₁ = 2 l₂₁ · l₁₁ = 2 → l₂₁ = 1 l₂₁² + l₂₂² = 5 → l₂₂ = √(5 − 1) = 2 L = [[2, 0], [1, 2]]; L Lᵀ = [[4, 2], [2, 1+4]] = [[4, 2], [2, 5]] ✓ A 3×3 check, A = [[4, 12, −16], [12, 37, −43], [−16, −43, 98]]: l₁₁ = √4 = 2 l₂₁ = 12/2 = 6 l₃₁ = −16/2 = −8 l₂₂ = √(37 − 6²) = √1 = 1 l₃₂ = (−43 − (−8)(6)) / 1 = 5 l₃₃ = √(98 − (−8)² − 5²) = √9 = 3 L = [[2, 0, 0], [6, 1, 0], [−8, 5, 3]] check row 3 of L Lᵀ: [−8·2, −8·6 + 5·1, 64 + 25 + 9] = [−16, −43, 98] ✓ log det A = 2·Σ log l_ii = 2·ln(2·1·3) = 2·ln 6 ≈ 3.5835 direct check: det A = 36, and ln 36 ≈ 3.5835 ✓ (the square roots are exactly why positive definiteness is required)

Gaussian processes use both facts: the predictive mean needs Kα = y, solved once from the Cholesky factor, and the marginal likelihood needs log det K, which the diagonal of L gives for free. Ridge regression does the same trick for (XᵀX + λI)w = Xᵀy.

Quick check

Ridge regression solves (XᵀX + λI)w = Xᵀy with Cholesky rather than LU. What makes Cholesky legal here?

WHEN Ax = b HAS NO EXACT SOLUTION

Miss by as little
as possible.

Every regression problem is overdetermined: more data points than parameters, so b sits outside the column space. Least squares finds the closest reachable point — and the answer is a familiar formula.

When A has m rows and n columns with m > n, the system is overdetermined. There is no x that satisfies every equation, but there is a best x: minimize the squared error ‖Ax − b‖², the sum of squared residuals. A residual is what one equation is still off by: rᵢ = (Ax)ᵢ − bᵢ.

Geometrically, Ax can only reach points in the column space of A. The closest such point to b is its perpendicular projection, and the leftover residual is perpendicular to the column space. That perpendicularity, written in coordinates, is the pair of equations AᵀA x = Aᵀb — the normal equations. For a data matrix with one column of 1s (the intercept) and one column per feature, this is the closed-form solution to linear regression.

Least squares, drawn

Pull the four points up and down. The line minimizes the summed area of the orange squares — the squared residuals — and the fit always solves the normal equations.

points: (1, 3) (2, 5) (3, 6) (4, 8) AᵀA = [[4, 10], [10, 30]] Aᵀb = [22, 63] normal equations give: c = 1.5, m = 1.6 fit: y = 1.5 + 1.6x residuals (fit − y): [0.1, -0.3, 0.3, -0.1] SSE = 0.2 Aᵀr = [Σr, Σxr] = [0, 0] ← zero means done

Those two zeros are the normal equations in disguise: at the best line, the residual vector is perpendicular to every column of A.

Derivation: the normal equations from calculus, and the 4-point fit checked
  1. Expand: ‖Ax − b‖² = (Ax − b)ᵀ(Ax − b) = xᵀAᵀAx − 2xᵀAᵀb + bᵀb.
  2. Differentiate with respect to the vector x — the vector versions of d(x²)/dx = 2x and d(cx)/dx = c — giving gradient 2AᵀAx − 2Aᵀb.
  3. Set the gradient to zero: AᵀA x = Aᵀb. The second derivative 2AᵀA is positive semi-definite, so the error surface is a convex bowl and this critical point is the minimum.
fit y = c + m·x through (1, 3), (2, 5), (3, 6), (4, 8) A = [[1, 1], b = [3, 5, 6, 8] [1, 2], [1, 3], [1, 4]] AᵀA = [[4, 10], Aᵀb = [22, 63] [10, 30]] det = 4·30 − 10·10 = 20 c = (22·30 − 10·63) / 20 = 30/20 = 1.5 m = (4·63 − 10·22) / 20 = 32/20 = 1.6 fit: y = 1.5 + 1.6x predictions: 3.1, 4.7, 6.3, 7.9 residuals (fit − y): 0.1, −0.3, 0.3, −0.1 Aᵀr = [Σr, Σx·r] = [0, 0] ✓ perpendicular to both columns SSE = 0.1² + 0.3² + 0.3² + 0.1² = 0.2 the reference notebook prints y = 1.5 + 1.7x; testing m = 1.7 gives Aᵀr = [1.0, 3.0] and SSE = 0.5, so 1.6 is the true minimum. (Both this page and the lab compute 1.6 from the normal equations.)

The normal equations are the shortest path to the answer, but they have a numerical price: κ(AᵀA) = κ(A)², so forming AᵀA squares the condition number and can turn a mildly hard problem into an impossible one. Libraries fit with QR or SVD on A itself when features are nearly collinear. For a handful of well-scaled features — the textbook case — the normal equations are perfect.

Quick check

At the least-squares solution, what is true about the residual vector r = Ax − b?

HOW MANY DIGITS CAN YOU TRUST?

A solver “worked”.
That does not mean it was right.

The condition number measures how loudly a small error in the input echoes in the answer. It turns “the computer said so” into a specific number of trustworthy digits.

The condition number of A is κ(A) = ‖A‖ · ‖A⁻¹‖ = σmax / σmin, the ratio of the largest to the smallest singular value. It is the worst-case amplification factor for relative error: disturb b by a relative 1% and x can move by up to κ%. A matrix with κ near 1 behaves like a rotation — safe. A matrix with κ near 10¹⁶ effectively destroys its smallest direction: in float64, whose relative precision is about 10⁻¹⁶, the answer carries no information at all.

The rule of thumb is one decimal digit per power of ten: with κ ≈ 10ᵏ you lose about k of the ~15 significant digits float64 stores, leaving 15 − k. Ill-conditioning in machine learning usually means nearly collinear features: two columns that say almost the same thing make σmin tiny. Regularization is the standard fix, because adding λI lifts σmin without inflating σmax.

Ill-conditioning, felt

The two rows of A are nearly identical, so the two lines nearly coincide. Nudge b a hair and watch the intersection shoot off the chart; add λ and it comes back.

A = [[1, 1], [1, 1 + 1e−8]] κ(A) = σmax/σmin ≈ 4.00e8 float64 keeps ~15 digits → ~9 survive δ = 0: x = (1, 0) δ = 1e−8: x = (0, 1) |Δx₂| = 1.0e0 λ = 1e−6: x = (0.5, 0.5) residual ‖Ax − b‖ = 3.60e−7

κ is the worst-case amplification of a relative error in b. Each power of ten in κ costs about one decimal digit of the answer.

Derivation: why the relative error can grow by κ, with numbers

Perturb the right-hand side and see how the solution responds.

A(x + δx) = b + δb → δx = A⁻¹ δb norms: ‖δx‖ ≤ ‖A⁻¹‖ · ‖δb‖ and ‖b‖ = ‖Ax‖ ≤ ‖A‖ · ‖x‖ divide the first by ‖x‖ and the second by ‖b‖: ‖δx‖ / ‖x‖ ≤ ‖A‖ ‖A⁻¹‖ · (‖δb‖ / ‖b‖) = κ · (relative error in b)

Numeric check. Let κ = 10⁸ and let b be stored with standard float64 rounding, a relative error of about 10⁻¹⁶. Then the solution’s relative error can reach 10⁸ × 10⁻¹⁶ = 10⁻⁸: eight digits lost, leaving about seven good ones.

A = [[2, 0], [0, 1]] κ = 2/1 = 2 lose ~0.3 digits A = [[1, 1], [1, 1 + 1e−15]] κ ≈ 4/1e−15 = 4e15 lose ~15.6 digits det A = 1e−15, and the two rows differ in the 16th digit float64 has ~16 digits: the second piece of information is gone Regularization: A = [[1, 1], [1, 1 + 1e−8]] κ ≈ 4e8 (~8.6 digits lost) ridge solves (AᵀA + λI)x = Aᵀb, and AᵀA + λI swaps σᵢ² for σᵢ² + λ: λ = 0.01 → κ(AᵀA + 0.01I) = (4 + 0.01)/(2.5e−17 + 0.01) ≈ 401 → about 2.6 digits lost instead of 8.6. One small term, six digits saved. (The reference writes the improved ratio as (σmax + λ)/(σmin + λ); adding λI to AᵀA is what ridge actually does, hence the squares.)
Quick check

You compute a solution with a matrix whose condition number is 10¹⁰, in float64 (about 15 digits). Roughly how many digits of the answer are meaningful?

TOO BIG TO FACTOR

Stop factoring.
Start improving a guess.

A million unknowns make O(n³) hopeless, but many huge matrices are sparse: each equation touches only a few unknowns. Iterative methods exploit that by never eliminating anything at all.

Direct methods — elimination, LU, Cholesky — change the matrix until it is triangular. That costs O(n³) time and O(n²) storage, which is fine at n = 1,000 and impossible at n = 50,000,000. Iterative methods instead produce a sequence of guesses x₀, x₁, x₂, … that (hopefully) converges to the solution, using only matrix–vector products Ax. For a sparse A, each product costs O(non-zeros), not O(n²).

The simplest example is the Jacobi method: solve the i-th equation for the i-th unknown, plugging in the previous guesses for everything else. Everything depends on one number — the spectral radius ρ of the iteration matrix, the largest absolute eigenvalue. If ρ < 1 the error shrinks by a factor of ρ each sweep; if ρ ≥ 1 it stalls or explodes. Diagonally dominant matrices (and symmetric positive definite ones) guarantee ρ < 1. Conjugate gradient is the famous upgrade: for SPD systems it finds the exact answer in at most n steps in exact arithmetic, and usually far fewer — with convergence speed set by κ once more.

Jacobi sweeps, watching the error shrink

Instead of factoring A, each sweep solves every equation for its own unknown using the previous guess. Strong diagonal → fast convergence; weak diagonal → divergence.

Jacobi update: x_i ← (b_i − Σ a_ij x_j) / a_ii exact solution x* = (0.1333, 0.4667) current x0 = (0, 0) error ‖x0 − x*‖ = 4.85e−1 iteration matrix = [[0, -0.25], [-0.25, 0]] spectral radius ρ = |off| / 4 = 0.25 each sweep multiplies the error by about 0.25

Jacobi only needs A times a vector — no factorization. That is the door into conjugate gradient and the world of million-unknown systems.

Derivation: the Jacobi iteration matrix, and 15 sweeps to 10⁻⁸
Split A = D + (L + U): diagonal, strict lower, strict upper. A x = b D x + (L + U) x = b D x = b − (L + U) x x = D⁻¹ (b − (L + U) x) the Jacobi step, componentwise: x_i ← ( b_i − Σ_{j≠i} a_ij x_j ) / a_ii Treat the step as a fixed-point map x ← M x + D⁻¹b with M = −D⁻¹(L + U). Its eigenvalues control everything: error after k sweeps is ≤ ρ(M)^k · (initial error). Converges ⟺ ρ(M) < 1. Worked check: A = [[4, 1], [1, 3]], b = [1, 2] M = [[0, −1/4], [−1/3, 0]], eigenvalues ±√(1/12) ≈ ±0.2887 exact solution: x₁ = 1/11 ≈ 0.0909, x₂ = 7/11 ≈ 0.6364 (check: 4/11 + 7/11 = 1 ✓ and 1/11 + 21/11 = 2 ✓) sweep x₁ x₂ 0 0 0 1 0.25 0.6667 (1 − 0)/4, (2 − 0)/3 2 0.0833 0.5833 (1 − 0.6667)/4, (2 − 0.25)/3 3 0.1042 0.6389 ... oscillating toward the answer sweeps to shrink the error below 1e−8: ρ^k ≤ 1e−8 → k ≥ ln(1e−8)/ln(0.2887) = 18.42/1.243 ≈ 14.8 → 15 sweeps conjugate gradient on this same 2×2 SPD system: at most 2 steps.

That comparison is the whole story of large-scale solvers: the best method depends on how fast the error decays, and that rate is controlled by the spectrum — which is κ again, in disguise. Better conditioning means fewer sweeps, which is a third reason regularization helps.

CHECK YOURSELF

Five questions.
Then the terms worth keeping.

Answer before you look. The pivoting and Cholesky questions are the ones that separate “I can call solve” from “I know what solve does”.

0 / 5 answered · 0 correct

01What does it mean geometrically when Ax = b has no exact solution?

02Why is partial pivoting used in Gaussian elimination?

03Why is Cholesky preferred over LU for solving (XᵀX + λI) w = Xᵀy in ridge regression?

04A matrix has condition number κ = 10⁸. Using float64 (about 15 significant digits), how many digits of the solution can you trust?

05What is the main advantage of LU decomposition over Gaussian elimination when solving Ax = b for many different b vectors?

Key terms, demystified

Click a card to swap the lazy description for what it actually means.

Exercises from the lesson

Four problems, all fully worked — two of them correct arithmetic slips in the reference notebook. Try first; the answer is one click away.

  1. Solve [[1, 2, 3], [4, 5, 6], [7, 8, 10]] x = [6, 15, 27] by Gaussian elimination. Verify the answer in each original equation, then read L and U off the multipliers.
    Show one worked answer

    Augmented [A | b]; R2 ← R2 − 4·R1 gives [0, −3, −6 | −9]; R3 ← R3 − 7·R1 gives [0, −6, −11 | −15]; R3 ← R3 − 2·R2 gives [0, 0, 1 | 3]. Back substitution: x₃ = 3; −3x₂ − 18 = −9 so x₂ = −3; x₁ − 6 + 9 = 6 so x₁ = 3. Check: 3 − 6 + 9 = 6 ✓, 12 − 15 + 18 = 15 ✓, 21 − 24 + 30 = 27 ✓. The multipliers 4, 7, 2 become L = [[1, 0, 0], [4, 1, 0], [7, 2, 1]] with U = [[1, 2, 3], [0, −3, −6], [0, 0, 1]], and L @ U reproduces A exactly. Warning: the reference notebook prints x = (1, 1, 1), which satisfies the first two equations but gives 7 + 8 + 10 = 25, not 27, in the third — the printed answer is a typo and x = (3, −3, 3) is the solution.

  2. Fit y = c + m·x through (1, 3), (2, 5), (3, 6), (4, 8) with the normal equations. Verify that the residual vector is perpendicular to both columns of A and compare the squared error with the source's printed slope of 1.7.
    Show one worked answer

    A has rows [1, x], so AᵀA = [[4, 10], [10, 30]] and Aᵀb = [22, 63]. The determinant is 4·30 − 100 = 20, giving c = (22·30 − 10·63)/20 = 30/20 = 1.5 and m = (4·63 − 10·22)/20 = 32/20 = 1.6. The fit is y = 1.5 + 1.6x, with predictions 3.1, 4.7, 6.3, 7.9 and residuals (fit − y) 0.1, −0.3, 0.3, −0.1. Checks: Σr = 0 and Σx·r = 1(0.1) + 2(−0.3) + 3(0.3) + 4(−0.1) = 0, so Aᵀr = 0 — the residual is perpendicular to both columns. SSE = 0.01 + 0.09 + 0.09 + 0.01 = 0.2. The reference prints 1.7, but c = 1.5, m = 1.7 gives Aᵀr = [1.0, 3.0] (not zero) and SSE = 0.5, so 1.6 is the true minimum; the printed value is an arithmetic slip.

  3. Let A = [[1, 1], [1, 1 + 10⁻⁸]] and b = [1, 1 + 10⁻⁸]. Compute κ(A), solve Ax = b, then solve (AᵀA + 0.01·I)x = Aᵀb and explain the difference.
    Show one worked answer

    Two nearly parallel rows mean a tiny determinant: det A = 10⁻⁸ and κ(A) ≈ 4/det = 4 × 10⁸ — about 8.6 digits are lost, leaving roughly 6 or 7 good digits in float64. Writing ε = 10⁻⁸ and δ = 10⁻⁸, the exact solution is x = (1 − δ/ε, δ/ε) = (0, 1): the second component moved by a full unit in response to a 10⁻⁸ change in b. With λ = 0.01: AᵀA ≈ [[2, 2], [2, 2]], so AᵀA + λI = [[2.01, 2], [2, 2.01]], Aᵀb = [2, 2], det = 2.01² − 4 = 0.0401, and x = (0.02/0.0401, 0.02/0.0401) ≈ (0.499, 0.499). The regularized answer accepts a slightly larger residual in exchange for being stable and small. In regression language, λ shrinks the weights toward zero and makes XᵀX + λI safely positive definite.

  4. Solve [[4, 1], [1, 3]] x = [1, 2] with Jacobi sweeps. Find the exact solution, the spectral radius of the iteration matrix, and the number of sweeps needed to shrink the error below 10⁻⁸.
    Show one worked answer

    The exact solution is x₁ = 1/11 ≈ 0.0909 and x₂ = 7/11 ≈ 0.6364 (check: 4/11 + 7/11 = 1 and 1/11 + 21/11 = 2). Splitting A = D + (L + U) gives the iteration matrix M = −D⁻¹(L + U) = [[0, −1/4], [−1/3, 0]], whose eigenvalues are ±√(1/12) ≈ ±0.2887, so ρ ≈ 0.2887. From x₀ = (0, 0): sweep 1 gives (0.25, 0.6667), sweep 2 gives (0.0833, 0.5833), sweep 3 gives (0.1042, 0.6389) — oscillating toward the answer. The error shrinks like ρᵏ, so k ≥ ln(10⁻⁸)/ln(0.2887) ≈ 18.42/1.243 ≈ 14.8: 15 sweeps. Conjugate gradient solves this particular SPD 2 × 2 system in at most 2 steps, which is exactly why it is preferred when n is huge.

Terms this lesson borrows from later lessons (or outside)

You do not need to master these here. Each one gets a proper treatment in its own lesson; the one-line meaning is enough to keep reading. Orange dotted underlines in the prose point back to this list.

  • featureOne input column: a single measured property of each example (age, pixel value, word count). The X in Xw = y is a column of features per sample. (Lesson 01)
  • projectionThe closest point in a subspace to a given vector; the residual left over is perpendicular to that subspace. Least squares is a projection onto the column space. (Lesson 01)
  • eigenvaluesThe numbers λ with Av = λv: directions a matrix only stretches. Positive definiteness means every eigenvalue of a symmetric matrix is positive. (Lesson 03)
  • gradientThe vector of partial derivatives, pointing in the direction of steepest increase. The normal equations come from setting the gradient of the squared error to zero. (Lesson 04)
  • SVDA = UΣVᵀ, valid for any matrix. Singular values are the stretch factors; the condition number is σmax/σmin, and the pseudoinverse is built from the same factors. (Lesson 11)
  • clusteringGrouping data points so that points in a group are closer to each other than to points in other groups; spectral clustering works through the same Laplacian linear systems. (Lesson 21)
KEEP GOING

A picture is a start.
Practice is the rest.

This lesson is a port of an open course. Everything here traces back to it — and the next step is running the code yourself.

Lesson text adapted from AI Engineering from Scratch (Phase 01, Lesson 17) and the Math Foundations Notebook reference build. The row/column picture lab, elimination stepper, LU-vs-Cholesky console, least-squares lab, condition-number lab and Jacobi lab are original to this page, as are the corrected worked answers to exercises 1 and 2 and the exact squared form of the ridge condition number. Every displayed number is computed in your browser from the values shown. All labs run in your browser.