1

我正在尝试在 Matlab 中编写牛顿算法的实现。

当我使用公式调用我的函数时:

result = NewtonMethod(x(1).^2 - 2.1*x(1).^4 + (x(1).^6)/3 + x(1)*x(2) - 4*x(2).^2 + 4*x(2).^4, [0 0], 0.1, 10)

我收到一条错误消息:

??? Undefined function or method 'hessian' for input arguments of type 'double'.

Error in ==> NewtonMethod at 13
    H = hessian(f, x0);

我不知道出了什么问题。也许更熟悉Matlab的人可以帮助我。

下面是我的代码:

function xnext = NewtonMethod(f, x0, eps, maxSteps)

% x0        -   starting point (2 – dimensional  vector)
% H         -   matrix of second derivatives (Hessian)
% eps       -   required  tolerance of calculations
% maxSteps  -   length of step

x = x0;

for n=1:maxSteps

    % determine the hessian H at the starting point x0,
    H = hessian(f, x0);

    % determine the gradient of the goal function gradf at the point x,
    gradF = gradient(f, x);

    % determine next point
    xnext = x - inv(H) * x * gradF;

    if abs(xnext - x) < eps
        return                  %found
    else
        x = xnext;              %update
    end
end

这是我第一次接触 Matlab。

更新:

现在我有一个错误:

??? Error using ==> mupadmex
Error in MuPAD command: Index exceeds matrix dimensions.

Error in ==> sym.sym>sym.subsref at 1381
            B = mupadmex('symobj::subsref',A.s,inds{:});

我输入:

syms x
result = NewtonMethod(x(1).^2 - 2.1*x(1).^4 + (x(1).^6)/3 + x(1)*x(2) - 4*x(2).^2 + 4*x(2).^4, [0 0], 0.1, 10)
4

1 回答 1

3
x(1).^2 - 2.1*x(1).^4 + (x(1).^6)/3 + x(1)*x(2) - 4*x(2).^2 + 4*x(2).^4

NewtonMethod在调用函数之前减少为双精度,因此当您的代码到达时hessian(f, x0),您将向它传递两个双精度参数,这不是受支持的语法

查看有关正确指定符号函数的注释,并将其传递到NewtonMethod.


好久没做数值优化了,看看下面的:

function xn = NewtonMethod(f, x0, eps, maxSteps)

% x0        -   starting point (2 – dimensional  vector)
% H         -   matrix of second derivatives (Hessian)
% eps       -   required  tolerance of calculations
% maxSteps  -   length of step

syms x y

H = hessian(f);
gradF = gradient(f);

xi = x0;

for i=1:maxSteps

    % evaluate f at xi
    zi = subs(f, [x,y], xi);

    % determine the hessian H at the starting point x0,
    hi = subs(H, [x,y], xi);

    % determine the gradient of the goal function gradf at the point x,
    gi = subs(gradF, [x,y], xi);

    % determine next point
    ss = 0.5;  % step size
    xn = xi - ss.* (inv(hi) * gi);

    % evaluate f at xn
    zn = subs(f, [x,y], xn);

    % some debugging spam
    zd = zn - zi;                          % the change in the value of the
    si = sprintf('[%6.3f, %6.3f]', xi);    %   function from xi -> xn
    sn = sprintf('[%6.3f, %6.3f]', xn);
    printf('Step %3d: %s=%9.4f -> %s=%9.4f  :  zd=%9.4f\n', i, si, zi, sn, zn, zd);

    % stopping condition
    if abs(xi - xn) < eps
        return               %found
    else
        xi = xn;             %update
    end
end

并调用

result = NewtonMethod(f, [0; 1], 0.001, 100)
于 2014-05-13T16:48:04.803 回答