我正在尝试使用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
f.m:</ p>
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)
得到:
使用/
时出错 矩阵维度必须一致。牛顿错误(第6行) x = xprev - f(xprev)/ fp(xprev);
当我在fp.m中检查y
的值时,我会继续[]
。
答案 0 :(得分:1)
您正尝试使用diff
来区分功能。开箱即用的diff
执行元素对之间的差异操作。你不想要这个。而是将f
和fp
作为实际的函数句柄。首先创建函数f
的符号定义,然后使用diff
的符号版本区分此符号表示(您可以使用diff
本身调用) ,然后使用matlabFunction
创建一个MATLAB函数:
%// 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
返回的内容,因此无需再通过@
创建句柄作为牛顿方法函数的输入。
对你的代码运行这个修改,我得到了这个根,初始猜测是x = 1.4
以及它所花费的迭代次数:
>> format long g
>> y
y =
1.16556118520721
>> iter
iter =
8
如果由于某种原因,你没有符号数学工具箱,那么我建议的东西不会起作用。因此,您无法做出选择,只能使用导数的离散逼近来实现此功能。但是,我们仍然可以使用上面编写的代码,但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
我说它非常接近!