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