Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Big Idea

Pivoting reorders rows (and sometimes columns) to avoid division by zero and minimize round-off error. Partial pivoting, swapping rows to use the largest pivot, is essential for numerical stability.

The Problem

Gaussian elimination fails if a pivot element akk(k)=0a_{kk}^{(k)} = 0. Even when not zero, small pivots cause problems: division by small numbers amplifies errors and the algorithm becomes unstable.

Partial Pivoting

At each step kk, find the largest element in the current column (below the diagonal) and swap rows before eliminating.

Algorithm 1 (Gaussian Elimination with Partial Pivoting)

Input: ARn×n\mathcal{A} \in \mathbb{R}^{n \times n}, bRn\mathbf{b} \in \mathbb{R}^n

Output: Upper triangular U\mathcal{U}, modified b~\tilde{\mathbf{b}}, permutation record

  1. for k=1,2,,n1k = 1, 2, \ldots, n-1:

  2. \qquad Find p=argmaxikaikp = \arg\max_{i \geq k} |a_{ik}|

  3. \qquad Swap rows kk and pp in A\mathcal{A} and b\mathbf{b}

  4. \qquad for i=k+1,,ni = k+1, \ldots, n:

  5. \qquad\qquad likaik/akkl_{ik} \gets a_{ik} / a_{kk}

  6. \qquad\qquad for j=k+1,,nj = k+1, \ldots, n:

  7. \qquad\qquad\qquad aijaijlikakja_{ij} \gets a_{ij} - l_{ik} \cdot a_{kj}

  8. \qquad\qquad bibilikbkb_i \gets b_i - l_{ik} \cdot b_k

PA = LU Decomposition

With pivoting, the factorization becomes:

PA=LU\mathcal{P}\mathcal{A} = \mathcal{L}\mathcal{U}

where P\mathcal{P} is a permutation matrix that records the row swaps.

To solve Ax=b\mathcal{A}\mathbf{x} = \mathbf{b}:

  1. Apply permutation: Pb\mathcal{P}\mathbf{b}

  2. Forward solve: Ly=Pb\mathcal{L}\mathbf{y} = \mathcal{P}\mathbf{b}

  3. Back solve: Ux=y\mathcal{U}\mathbf{x} = \mathbf{y}

Example 1 (Why Pivoting Matters)

Consider in 3-digit arithmetic:

(0.0001111)(x1x2)=(12)\begin{pmatrix} 0.0001 & 1 \\ 1 & 1 \end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \end{pmatrix} = \begin{pmatrix} 1 \\ 2 \end{pmatrix}

Without pivoting: the multiplier is l21=1/0.0001=10000l_{21} = 1/0.0001 = 10000. The elimination produces a22(1)=1100001=9999a_{22}^{(1)} = 1 - 10000 \cdot 1 = -9999, but in 3-digit arithmetic this is rounded to -10000, and the subsequent back substitution gives x21.000x_2 \approx 1.000 and x10.000x_1 \approx 0.000. The true solution is x11.0001x_1 \approx 1.0001, x20.9999x_2 \approx 0.9999.

With pivoting: swap the rows first:

(110.00011)(x1x2)=(21)\begin{pmatrix} 1 & 1 \\ 0.0001 & 1 \end{pmatrix} \begin{pmatrix} x_1 \\ x_2 \end{pmatrix} = \begin{pmatrix} 2 \\ 1 \end{pmatrix}

Now the multiplier is l21=0.0001l_{21} = 0.0001, which is safe. The result is accurate even in limited precision.

Types of Pivoting

StrategyDescriptionCost
Partial pivotingSwap rows to get largest pivot in columnO(n2)\mathcal{O}(n^2) comparisons
Complete pivotingSwap both rows and columnsO(n3)\mathcal{O}(n^3) comparisons
Scaled pivotingAccount for row scaling before choosing pivotO(n2)\mathcal{O}(n^2)

Partial pivoting is the standard choice: the overhead is O(n2)\mathcal{O}(n^2) comparisons, negligible compared to O(n3)\mathcal{O}(n^3) elimination, and it is sufficient for nearly all practical problems.

Remark 1 (Pivoting in Practice)

All standard libraries (NumPy, SciPy, LAPACK) use partial pivoting by default. When you call scipy.linalg.solve(A, b) or scipy.linalg.lu(A), partial pivoting is applied automatically.

See Also

Stability of Gaussian Elimination: growth factors for random matrices and the structure of LU factors with partial pivoting.