Error in fminunc function
4 vues (au cours des 30 derniers jours)
Afficher commentaires plus anciens
Sylvina Barreto
le 3 Avr 2016
Réponse apportée : Walter Roberson
le 3 Avr 2016
The problem I'm having is that when I call the fminunc function it doesn't solve the problem because it sayd that the gradient is zero and that it needs two elements, but when I just call the gradient it throws the right one. What am I doing wrong? Please help me :)
This is the script
function [f,grad,hess] = exam_sylvi(x)
f = 2*x(1)+3*x(2)^2+exp(2*x(1)^2+x(2)^2);
if nargout > 1
grad = gradient (f,[x(1),x(2)])
end
if nargout > 2
hess = hessian (f,[x(1),x(2)])
end
end
This is the run
EDU>> grad
grad =
4*x1*exp(2*x1^2 + x2^2) + 2
2*x2*exp(2*x1^2 + x2^2)
EDU>> hess
hess =
[ 4*exp(2*x1^2 + x2^2) + 16*x1^2*exp(2*x1^2 + x2^2), 8*x1*x2*exp(2*x1^2 + x2^2)]
[ 8*x1*x2*exp(2*x1^2 + x2^2), 2*exp(2*x1^2 + x2^2) + 4*x2^2*exp(2*x1^2 + x2^2)]
EDU>> [x,fval,exitflag] = fminsearch(@exam_sylvi,[1,0])
x =
-0.3766 -0.0000
fval =
0.5748
exitflag =
1
EDU>> options = optimoptions('fminunc','Display','iter','Algorithm','quasi-newton','HessUpdate','steepdesc','GradObj','on');
EDU>> [x,fval,exitflag,output] = fminunc(@exam_sylvi,[1,0],options)
grad =
0
Error using fminunc (line 339)
User-defined objective gradient does not have the correct number of elements:
the gradient should have 2 elements.
0 commentaires
Réponse acceptée
Walter Roberson
le 3 Avr 2016
Your tests are with symbolic x, but fmincon runs with numeric x. So f = 2*x(1)+3*x(2)^2+exp(2*x(1)^2+x(2)^2) is going to produce a numeric scalar because x(1) and x(2) will have particular numeric values. You then apply the numeric gradient function to that scalar, giving the x(1) and x(2) as the step sizes (which is obviously wrong), but since f is only a scalar the step sizes are irrelevant and the numeric gradient is going to return just the scalar.
What you should probably do is
function [f,grad,hess] = exam_sylvi(x)
syms x1 x2
F = 2*x+3*x2^2+exp(2*x1^2+x2^2);
f = double( subs(F, [x1 x2], x) );
if nargout > 1
grad = double( subs( gradient(F,[x1, x2]), [x1, x2], x) );
end
if nargout > 2
hess = double( subs( hessian(F,[x1, x2]), [x1, x2], x) );
end
end
Except, of course, that would be inefficient and you would be better to pre-calculate those before calling fmincon:
syms x1 x2
F = 2*x+3*x2^2+exp(2*x1^2+x2^2);
fh = matlabFunction(F, 'vars', {x1, x2});
gradh = matlabFunction( gradient(F, [x1, x2]), 'vars', {x1, x2});
hessh = matlabFunction( hessian(F, [x1, x2]), 'vars', {x1, x2});
[x,fval,exitflag,output] = fminunc(@(x) exam_sylvi(x, fh, gradh, hessh), [1,0], options)
Together with
function [f, grad, hess] = exam_slvi(x, fh, gradh, hessh)
f = fh(x);
if nargout > 1
grad = gradh(x);
end
if nargout > 2
hess = hessh(x);
end
end
0 commentaires
Plus de réponses (0)
Voir également
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!