Three things wrong with your code.
- Your
for
loop statements are mis-aligned. Specifically, you forgot to place an end
keyword at the end of the first for
loop within the i
loop (i.e. for j = 1 : i-1
)
- You need to compute the values for Gauss-Newton using the current solution from
j = 1, 2
up to i-1
. The first for
loop needs to use x
, and the second for
loop from j = i+1
up to n
needs to use x0
.
- You need to divide by the correct diagonal coefficient when you solve for each value of
x
.
As such:
function [x, l] = GS(A, b, x0, TOL)
[m n] = size(A);
l = 1;
x = [0;0;0];
while (true)
for i=1:m
sum1 = 0; sum2 = 0;
for j=1:i-1 %// CHANGE
sum1 = sum1 + A(i,j)*x(j); %// CHANGE
end
for j=i+1:n %// CHANGE
sum2 = sum2 + A(i,j)*x0(j);
end
x(i) = (-sum1-sum2+b(i))./A(i,i); %// CHANGE
end
if abs(norm(x) - norm(x0)) < TOL
break
end
x0 = x;
l = l + 1;
end
Example use:
format long;
A = [6 1 1; 1 5 3; 0 2 4]
b = [1 2 3].';
[x,i] = GS(A, b, [0;0;0], 1e-10)
x =
0.048780487792648
-0.085365853612062
0.792682926806031
i =
21
This means it took 21 iterations to achieve a solution with tolerance 1e-10
. Compare this with MATLAB's built-in inverse:
x2 = A \ b
x2 =
0.048780487804878
-0.085365853658537
0.792682926829268
As you can see, I specified a tolerance of 1e-10
, which means we are guaranteed to have 10 decimal places of accuracy. We can certainly see 10 decimal places of accuracy between what Gauss-Newton gives us with what MATLAB gives us built-in.