Три вещи неправильно с вашим кодом.
- Ваши
for
инструкций цикла неверны. В частности, вы забыли поместить end
ключевое слово в конце первого for
цикла внутри цикла i
(т.е. for j = 1 : i-1
)
- Вам нужно вычислить значения Гаусса-Ньютон с использованием током решения от
j = 1, 2
до i-1
. Первый цикл for
должен использовать x
, а второй цикл for
от j = i+1
до n
должен использовать x0
.
- При решении для каждого значения
x
вам необходимо разделить на правильный диагональный коэффициент.
Как таковой:
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
Пример использования:
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
Это означает, что потребовалось 21 итераций, чтобы добиться решения с допуском 1e-10
. Сравните это со встроенным обратным от Matlab:
x2 = A \ b
x2 =
0.048780487804878
-0.085365853658537
0.792682926829268
Как вы можете видеть, я указал погрешнсть 1e-10
, что означает, что мы гарантированно иметь 10 десятичных разрядов точности. Мы можем точно видеть 10 десятичных знаков точности между тем, что дает нам Гаусс-Ньютон с тем, что MATLAB дает нам встроенный.
Я написали ответ. Я также решил вашу другую проблему с вашим решателем Якоби. Если вы не возражаете, взгляните на мой ответ и примите его, если я помогу вам ... это тоже! – rayryeng
Спасибо! Я не знал, как принять ответ, но я вижу это сейчас. Спасибо за помощь по обоим моим кодам! – user3681755
Нет проблем :) Я действительно сделал небольшую ошибку с моим кодом. Я поменял две переменные внутри двух циклов 'for' внутри этого большего цикла' for', используя 'i'. Взглянуть! Он не меняет ответа, хотя ... но он сходится быстрее. – rayryeng