5.3: Pivoting
In our description of the Gaussian elimination algorithm so far, you may have noticed a problem. During the row reduction process, we have to multiply rows by a factor of \(A'_{mn}/A'_{nn}\) (where \(\mathbf{A}'\) denotes the current matrix). If \(A'_{nn}\) happens to be zero, the factor blows up, and the algorithm fails.
To bypass this difficulty, we add an extra step to the row reduction procedure. As we step forward through row numbers \(n = 0, 1, \cdots, N-1\), we do the following for each \(n\):
- Pivoting : search through the matrix elements on and below the diagonal element at \((n,n)\), and find the row \(n'\) with the largest value of \(|A'_{n'n}|\). Then, swap row \(n\) and row \(n'\).
- Continue with the rest of the algorithm, eliminating the \(A'_{mn}\) elements below the diagonal.
You should be able to convince yourself that (i) pivoting does not alter the solution, and (ii) it does not alter the runtime scaling of the row reduction phase, which remains \(O(N^3)\).
Apart from preventing the algorithm from failing unnecessarily, pivoting improves its numerical stability. If \(A'_{nn}\) is non-zero but very small in magnitude, dividing by it will produce a very large result, which brings about a loss of floating-point numerical precision. Hence, it is advantageous to swap rows around to ensure that the magnitude of \(A'_{nn}\) is as large as possible.
When trying to pivot, it might happen that all the values of \(|A'_{n'n}|\), on and below the diagonal, are zero (or close enough to zero within our floating-point tolerance). If this happens, it indicates that our original \(\mathbf{A}\) matrix is singular, i.e., it has no inverse. Hence, the pivoting procedure has the additional benefit of helping us catch the cases where there is no valid solution to the system of equations; in such cases, the Gaussian elimination algorithm should abort.
5.3.1 Example
Let's work through an example of Gaussian elimination with pivoting, using the problem in the previous section:
\[\left[\begin{array}{ccc|cc} 1 & 2 & 3 & 3 & 6 \\ 3 & 2 & 2 & 4 & 8 \\ 2 & 6 & 2 & 4 & 2 \end{array}\right].\]
The row reduction phase goes as follows:
-
(\(n=0\)): Pivot, swapping row \(0\) and row \(1\):
\[\left[\begin{array}{ccc|cc} 3 & 2 & 2 & 4 & 8 \\ 1 & 2 & 3 & 3 & 6 \\ 2 & 6 & 2 & 4 & 2 \end{array}\right].\] -
(\(n=0\)): Eliminate the element at \((1,0)\):
\[\left[\begin{array}{ccc|cc} 3 & 2 & 2 & 4 & 8 \\ 0 & 4/3 & 7/3 & 5/3 & 10/3 \\ 2 & 6 & 2 & 4 & 2 \end{array}\right].\] -
(\(n=0\)): Eliminate the element at \((2,0)\):
\[\left[\begin{array}{ccc|cc} 3 & 2 & 2 & 4 & 8 \\ 0 & 4/3 & 7/3 & 5/3 & 10/3 \\ 0 & 14/3 & 2/3 & 4/3 & -10/3 \end{array}\right].\] -
(\(n=1\)): Pivot, swapping row \(1\) and row \(2\):
\[\left[\begin{array}{ccc|cc} 3 & 2 & 2 & 4 & 8 \\ 0 & 14/3 & 2/3 & 4/3 & -10/3 \\0 & 4/3 & 7/3 & 5/3 & 10/3 \end{array}\right].\] -
(\(n=1\)): Eliminate the element at \((2,1)\):
\[\left[\begin{array}{ccc|cc} 3 & 2 & 2 & 4 & 8 \\ 0 & 14/3 & 2/3 & 4/3 & -10/3 \\0 & 0 & 15/7 & 9/7 & 30/7 \end{array}\right].\]
The back-substitution phase then proceeds as usual. You can check that it gives the same results we obtained before.