7.2. Gauss-Seidel method#
In the previous section on the Jacobi method we saw that the solution to the linear system of equations \(A \vec{x} = \vec{x}\) can be calculated by estimating the solution \(\vec{x}\) and calculate an improved estimation \(\vec{x}^{(k+1)}\) using values from the current estimation \(\vec{x}^{(k)}\). We continue to calculate the improved estimates until the largest absolute value in the {prf:ref}residual
so when calculating \(x_i\), we have already calculated the next values of \(x_1, x_2, \ldots, x_{i-1}\). We can improve the speed of which the Jacobi method converges by using these new values to calculate \(x_i^{(k+1)}\). This gives us the Gauss-Seidel method named after German mathematicians Carl Gauss and Philipp von Seidel.
(The Gauss-Seidel method)
The Gauss-Seidel method for solving a system of linear equations of the form \(A \vec{x} = \vec{b}\) is
7.2.1. The iteration matrix for the Gauss-Seidel method#
The iteration matrix for the Gauss-Seidel method can be found by rearranging \((L+D+U)\vec{x}=\vec{b}\)
So the matrix equation for the Gauss-Seidel method is
and the iteration matrix is
Calculate the solution to the system of linear equations from Example 7.1 (shown below) using the Gauss-Seidel method with an accuracy tolerance of \(tol = 10^{-4}\)
Solution (click to show)
The Gauss-Seidel method for this system is
Using starting values of \(\vec{x} = \vec{0}\). Calculating the first iteration
Calculate the residual
Since \(\max(| \vec{r}^{(1)} |) = 4.875 > 10^{-4}\) we continue iterating. Calculating the second iteration
Calculate the residual
Since \(\max(\| \vec{r}^{(2)} \|) = 0.421875 > 10^{-4}\) we continue iterating. The Gauss-Seidel method was iterated until \(\|\vec{r}\| < 10^{-4}\) and a selection of the iteration values are given in the table below. Note that the Gauss-Seidel method took 20 iterations to achieve convergence to \(tol=10^{-4}\) whereas the Jacobi method took 49 iterations to achieve the same accuracy.
\(k\) |
\(x_{1}\) |
\(x_{2}\) |
\(x_{3}\) |
\(\max( \| \vec{r} \|)\) |
---|---|---|---|---|
0 |
0.000000 |
0.000000 |
0.000000 |
14.000000 |
1 |
-0.500000 |
-1.625000 |
3.093750 |
4.88e+00 |
2 |
0.718750 |
-1.765625 |
3.058594 |
4.22e-01 |
3 |
0.824219 |
-1.853516 |
3.036621 |
2.64e-01 |
4 |
0.890137 |
-1.908447 |
3.022888 |
1.65e-01 |
5 |
0.931335 |
-1.942780 |
3.014305 |
1.03e-01 |
\(\vdots\) |
\(\vdots\) |
\(\vdots\) |
\(\vdots\) |
|
19 |
0.999905 |
-1.999921 |
3.000020 |
1.43e-04 |
20 |
0.999940 |
-1.999950 |
3.000012 |
8.93e-05 |
7.2.2. Code#
The code below defines the function gauss_seidel()
which solves a linear system of equations of the for \(A \vec{x} = \vec{b}\) using the Gauss-Seidel method.
def gauss_seidel(A, b, tol=1e-6):
n = len(b)
x = np.zeros(n)
maxiter = 100
for k in range(maxiter):
for i in range(n):
sum_ = 0
for j in range(n):
if i != j:
sum_ += A[i,j] * x[j]
x[i] = (b[i] - sum_) / A[i,i]
r = b - np.dot(A, x)
if max(abs(r)) < tol:
break
return x
function x = gauss_seidel(A, b, tol)
n = length(b);
x = zeros(n, 1);
maxiter = 100;
for k = 1 : 100
for i = 1 : n
sum_ = 0;
for j = 1 : n
if j ~= i
sum_ = sum_ + A(i,j) * x(j);
end
end
x(i) = (b(i) - sum_) / A(i,i);
end
r = b - A * x;
if max(abs(r)) < tol
break
end
end
end