Метод Ньютона в Matlab

Я пытаюсь применить метод Ньютона в Matlab и написал скрипт:

syms f(x)
f(x) = x^2-4
g = diff(f)
x_1=1 %initial point
while f(['x_' num2str(i+1)])<0.001;% tolerance
    for i=1:1000 %it should be stopped when tolerance is reached
       ['x_' num2str(i+1)]=['x_' num2str(i)]-f(['x_' num2str(i)])/g(['x_' num2str(i)])
    end
end

Я получаю эту ошибку:

   Error: An array for multiple LHS assignment cannot contain M_STRING.

Формула метода Ньютона: x_(n+1)= x_n-f(x_n)/df(x_n) до тех пор, пока значение f(x_n) не приблизится к нулю.


person fyec    schedule 25.01.2019    source источник
comment
Пожалуйста, не создавайте динамические переменные. Используйте один массив, чтобы сохранить все итерации   -  person Sardar Usama    schedule 26.01.2019


Ответы (1)


Все основные части присутствуют в настоящем коде. Однако есть некоторые проблемы.

Основная проблема заключается в том, что конкатенация строк создает переменную в рабочей области; Это не. Основным виновником является эта строка, вот эта

['x_' num2str(i+1)]=['x_' num2str(i)]-f(['x_' num2str(i)])/g(['x_' num2str(i)])

['x_' num2str(i+1)] — это строка, а язык MATLAB не поддерживает присваивание символьным массивам (это моя интерпретация An array for multiple LHS assignment cannot contain M_STRING.).

Мой ответ, ответы других могут отличаться, будет

  1. Преобразование символьных функций в дескрипторы через matlabFunction (поскольку метод Netwon почти всегда является числовой реализацией, символьные функции должны быть удалены, как только результат их использования будет завершен)
  2. Замените создание строк двойным массивом для x (намного, намного чище, быстрее и в целом лучший код).
  3. Поместите if-тест с break в for-цикле по сравнению с текущей конструкцией.

Мои предложения, реализованные, будут выглядеть так:

syms f(x)
f(x) = x^2-4;
g = diff(f);

f = matlabFunction(f);
g = matlabFunction(g);

nmax = 1000;
tol = 0.001;% tolerance
x = zeros(1, nmax);
x(1) = 1; %initial point

fk = f(x(1));
for k = 1:nmax
    if (abs(fk) < tol)
        break;
    end

    x(k+1) = x(k) - f(x(k))/g(x(k));
    fk = f(x(k));

end
person TroyHaskin    schedule 26.01.2019