2015-11-20 6 views
0

Я пытаюсь написать небольшую программу с использованием MATLAB, в которой я пытаюсь отличить функцию, которую я создал внутри другой функции, но я продолжаю получать ошибки.Дифференциация с использованием MATLAB

Мои файлы:

newton.m:

function [ y, iter ] = newton(f, fp, x0) 

    iter = 0; 
    xprev = x0; 
    x = xprev - f(xprev)/fp(xprev); 

    iter = iter + 1; 

    while abs(x-xprev) > eps*abs(x) 
     xprev = x; 
     x = x - f(x)/fp(x); 
     iter = iter + 1; 
     y = x; 
    end 
end 

фм:

function y = f(x) 
    y = tan(x) - 2*x; 
end 

fp.m:

function y = fp(f) 
    y = diff(f); 
end 

Я бегу следующее:

[y, iter] = newton(@f, @fp, 1.4) 

и получение:

Error using /
Matrix dimensions must agree.

Error in newton (line 6) x = xprev - f(xprev)/fp(xprev);

Когда я проверяю значение y в fp.m я получаю [].

+0

Функция 'diff' возвращает разность между элементами в векторе. См. diff>. Вы должны получить как минимум два значения при вызове 'fp' –

ответ

1

Вы пытаетесь использовать diff для дифференциации функции. Готовый diff выполняет разностную операцию между парами элементов. Вы не хотите этого. Вместо этого сделайте свои f и fp действительными функциями. Сначала создайте символическое определение вашей функции f, то дифференцировать это символическое представление с использованием символической версии diff (который вы можете просто позвонить с самого diff), а затем создать функцию MATLAB с matlabFunction из этого:

%// Define symbolic variable 
syms x; 

%// Define function symbolically 
y = tan(x) - 2*x; 

%// Define function handles (numerical) to the original and derivative 
f = matlabFunction(y); 
fp = matlabFunction(diff(y)); 

%// Now call Newton's Method 
[y, iter] = newton(f, fp, 1.4); 

Обратите внимание, что f и fp уже являются функциональными ручками. Это то, что возвращает matlabFunction, поэтому нет необходимости создавать дескриптор через @ в качестве входов в функцию метода Newton's больше.

Запуск этой модификации в код, я получаю это для корня с начальным предположением на x = 1.4 и количество итераций, которое потребовалось:

>> format long g 
>> y 

y = 

      1.16556118520721 

>> iter 

iter = 

    8 

Если Символическая Математика Toolbox отсутствует .. .

Если у вас нет набора символов Symbolic Mathematics Toolbox, то то, что я предложил, не будет работать. Таким образом, у вас нет выбора, кроме как использовать дискретную аппроксимацию производной, чтобы заставить ее работать. Тем не менее, мы все еще можем работать с кодом, который я написал выше, но fp придется определять по-разному.

Если вы помните, определение производной таково, что:

Чтобы получить эту работу в дискретном случае, вы делаете Δx очень маленький ... что-то вроде 1e-10, например.

Таким образом, вы могли бы сделать это вместо того, чтобы с анонимными функциями:

%// Define function 
f = @(x) tan(x) - 2*x; 

%// Define derivative 
h = 1e-10; 
fp = @(x) (f(x + h) - f(x))/h; 

%// Now call Newton's Method 
[y, iter] = newton(f, fp, 1.4); 

С этим, я получаю:

>> format long g; 
>> y 

y = 

      1.16556118520721 

>> iter 

iter = 

    8 

Я бы сказал, что это чертовски близко!

+0

Спасибо за ответ! По-моему, я что-то упускаю. Нужно ли мне создавать символическое определение моей функции f в окнах команд или как новый файл «m»? – Buzi

+0

@Buzi Нет, вам не нужно создавать новый файл M для исходной функции и ее производной. Вы создаете свои дескрипторы функций непосредственно в коде. Просто возьмите код, который я написал выше, поместите его в новый файл M и запустите его. Я получил его, чтобы запустить, и вот как я получил свой ответ. BTW, когда вы это заработаете, если вам не нужна дополнительная помощь, подумайте о том, чтобы принять мой ответ, чтобы сообщить сообществу SO, что вам не нужна дополнительная помощь. Удачи! – rayryeng

+0

Должен ли я вызвать новый файл M с определенным именем? И обязательно, я помету ваш ответ как полезный :) – Buzi

 Смежные вопросы

  • Нет связанных вопросов^_^