【问题标题】:Newton algorithm - couln't calculate Hessian牛顿算法 - 无法计算 Hessian
【发布时间】:2014-05-13 16:43:01
【问题描述】:

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

【问题讨论】:

  • hessian 函数未定义用于双输入(您将其传递给函数)。

标签: matlab newtons-method hessian-matrix


【解决方案1】:
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) 时,您将传递两个双参数 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)

【讨论】:

  • 也许像syms x一样简单
  • @user3633449 我更新了我的答案——不确定它是否正确,但它可能会让您对如何正确使用这些功能有所了解。
  • @jedwards 说真的我真的不明白 matlab 是如何工作的。我将 f 定义为 x.^2 - 2.1*x.^4 + (x.^6)/3 + x*y - 4*y.^2 + 4*y.^4 所以我得到一个关于 undefined x 的错误和 y - 好的。所以我输入了 x = 0 和 y = 1,然后调用了你上面写的函数。结果: ??? “double”类型的输入参数的未定义函数或方法“hessian”。如果我没有定义变量,而是输入了 syms x y 我得到了:??? 'sym 类型的输入参数的未定义函数或方法'hessian'
猜你喜欢
  • 2015-01-18
  • 2012-06-24
  • 2020-03-31
  • 2019-11-11
  • 1970-01-01
  • 1970-01-01
  • 2010-12-21
  • 2021-10-28
  • 2016-07-21
相关资源
最近更新 更多