Алгоритм Ньютона - не может вычислять гессиан
Я пытаюсь написать реализацию алгоритма Ньютона в 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
Это мой первый контакт с Матлабом.
Обновить:
Теперь у меня есть ошибка:
??? 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 ответ
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)