Gaussian Elimination and Pivoting
The systematic, row-by-row procedure for solving a system of linear equations by hand or by computer — and why blindly following the textbook steps can quietly destroy accuracy unless you reorder rows along the way.
Prerequisites: Matrix Inverses and Linear Systems
Solving a portfolio-optimization system for optimal weights means solving several linear equations simultaneously. Gaussian elimination is the systematic procedure — the same one taught in introductory algebra — for reducing that system, equation by equation, to a form that's trivial to solve by back-substitution. It's mechanical and always works in exact arithmetic, but on a computer, doing the steps in the wrong order can quietly wreck the accuracy of the answer, which is exactly the problem pivoting exists to fix.
An analogy: tidying a messy system by canceling variables
Imagine three equations in three unknowns, and you want to solve them by hand: pick one equation, use it to eliminate the first variable from the other two equations, then use one of the remaining two to eliminate the second variable from the last one — leaving one equation in one unknown, easily solved. Then substitute that answer back up the chain to get the rest. This is exactly Gaussian elimination: a step-by-step reduction from "many unknowns tangled together" to "one unknown, then unwind."
The math, one piece at a time
Given , Gaussian elimination systematically zeroes out entries below the diagonal, column by column, using row operations: subtracting a multiple of one row from another. To eliminate the entry in row using row 1's leading entry (the pivot) , subtract times row 1 from row :
In words: this row operation is designed to make the new exactly zero, while keeping the system's true solution unchanged, because subtracting a scaled copy of one true equation from another true equation produces another true equation. Repeating this for every row below, then moving to the second column and repeating, eventually leaves in upper triangular form — zeros everywhere below the diagonal — from which is found by back-substitution, solving the last (simplest) equation first and working upward.
Pivoting addresses what happens when the pivot (or any pivot along the way) is small relative to the entries it's dividing into. Dividing by a small number amplifies whatever rounding error is already present in the other entries — the same kind of error explosion seen in catastrophic cancellation. Partial pivoting fixes this by, before each elimination step, swapping rows so the largest available entry (in absolute value) in the current column becomes the pivot — mathematically this changes nothing about the solution (swapping equations doesn't change the system), but it keeps every division well-conditioned, controlling the growth of rounding error throughout the whole procedure.
Worked example 1: elimination by hand
Solve . Eliminate the entry below the pivot: , giving row 2 as . Back-substitute: ; then row 1 gives . Check: ✓, ✓.
Worked example 2: why pivoting matters, with real numbers
Solve using only 4 significant digits of precision. Without pivoting, the pivot is : , giving , rounded to 4 digits: , giving , then — actually recoverable here, but with slightly worse-conditioned numbers this same procedure loses several digits of accuracy fast. With partial pivoting, swap rows first so (the larger entry) becomes the pivot: eliminating with a modest multiplier of keeps every computed number well-scaled and avoids the huge multiplier entirely, giving a far more numerically robust path to the same exact answer .
What this means in practice
Gaussian elimination with partial pivoting is what actually runs underneath most solve(A, b) calls in numerical libraries — it's the standard, general-purpose method for solving portfolio optimization systems, calibrating models that reduce to linear systems, and any problem without special structure that would justify a more specialized method. Pivoting isn't an optional refinement; production-grade linear solvers essentially always pivot, because an un-pivoted implementation can fail silently on inputs that look perfectly reasonable.
Gaussian elimination reduces to upper-triangular form through systematic row operations, then solves by back-substitution; partial pivoting — reordering rows so the largest available entry becomes each pivot — doesn't change the mathematical answer but is essential for controlling rounding-error growth, since dividing by a small pivot amplifies whatever error is already present in the matrix.
The classic mistake is implementing Gaussian elimination exactly as taught on paper — always using the entry currently on the diagonal as the pivot, without checking its size — and trusting it to work because it "always works" in exact arithmetic. On a computer with finite precision, a small pivot (even one that's technically nonzero) can amplify existing rounding error into a badly wrong answer, with no error message or warning. Never implement elimination without partial pivoting for production use; a matrix that happens to have small diagonal entries relative to entries below it is not a rare edge case in practice.
Related concepts
Practice in interviews
Further reading
- Golub & Van Loan, Matrix Computations, ch. 3
- Trefethen & Bau, Numerical Linear Algebra, lecture 20