牛顿算法 - 无法计算Hessian

时间:2014-05-13 16:43:02

标签: matlab newtons-method hessian-matrix

我正在尝试在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)

1 个答案:

答案 0 :(得分: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函数之前减少为double,因此当代码到达hessian(f, x0)时,您将传递两个双参数which is not a supported syntax

在正确指定符号函数时查看notes,并将其传递到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)