使用 MATLAB 进行微分

Differentiation using 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  

f.m:

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);

当我检查 fp.m 中 y 的值时,我一直得到 []

您正在尝试使用 diff 来区分函数。开箱即用 diff performs a difference operation between pairs of elements. You don't want this. Instead, make your f and fp as actual function handles. First create the symbolic definition of your function f, then differentiate this symbolic representation using the symbolic version of diff (which you can just call with diff itself), then create a MATLAB function with 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);  

请注意,ffp 已经是函数句柄。这就是 matlabFunction returns,因此不再需要通过 @ 创建句柄作为牛顿法函数的输入。

运行 对你的代码的这个修改,我得到这个作为根的初始猜测 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

我会说这非常接近!