2015-02-11 4 views
0

Я не понимаю, почему я получаю это сообщение об ошибке. Я применил решение Гаусса-Ньютона для решения системы линейных уравнений.Gauss-Newton Solver: неправильное назначение с прямоугольной пустой матрицей

Он продолжает говорить, что неправильное назначение с прямоугольной пустой матрицей на линии "for i=1:m"

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 
     sum1 = sum1 + A(i,j)*x(j); 
     for j=i+1:n 
      sum2 = sum2 + A(i,j)*x(j); 
     end 
    end 
    x(i) = (-sum1-sum2+b(i))./A(i,j);  
end 
if abs(norm(x) - norm(x0)) < TOL 
    break 
end 
x0 = x; 
l = l + 1; 
end 
+0

Я написали ответ. Я также решил вашу другую проблему с вашим решателем Якоби. Если вы не возражаете, взгляните на мой ответ и примите его, если я помогу вам ... это тоже! – rayryeng

+1

Спасибо! Я не знал, как принять ответ, но я вижу это сейчас. Спасибо за помощь по обоим моим кодам! – user3681755

+0

Нет проблем :) Я действительно сделал небольшую ошибку с моим кодом. Я поменял две переменные внутри двух циклов 'for' внутри этого большего цикла' for', используя 'i'. Взглянуть! Он не меняет ответа, хотя ... но он сходится быстрее. – rayryeng

ответ

0

Три вещи неправильно с вашим кодом.

  1. Ваши for инструкций цикла неверны. В частности, вы забыли поместить end ключевое слово в конце первого for цикла внутри цикла i (т.е. for j = 1 : i-1)
  2. Вам нужно вычислить значения Гаусса-Ньютон с использованием током решения от j = 1, 2 до i-1. Первый цикл for должен использовать x, а второй цикл for от j = i+1 до n должен использовать x0.
  3. При решении для каждого значения 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 дает нам встроенный.