It is because you have not invoked the options SpecifyObjectiveGradient=true and SpecifyConstraintGradient=true in your call to fmincon. Your calculation of firstorderopt is based on analytical gradient calculations, while fmincon is using finite difference approximations. We see much better agreement when these options are activated:
options = optimoptions('fmincon','Algorithm','sqp','Display','none',...
'SpecifyObjectiveGradient',true,'SpecifyConstraintGradient',true);
[xstar,fstar,exitflag,output,lambda,grad,hessian] = ...
fmincon(@class24_fun,[2; 4],[],[],[],[],[],[],@class24_con,options);
[fstar,grad_fstar] = class24_fun(xstar);
[gstar,hstar,grad_gstar,grad_hstar] = class24_con(xstar);
grad_L = grad_fstar + grad_gstar*lambda.ineqnonlin;
myFOOM = norm(grad_L,inf)
tmwFOOM=output.firstorderopt
There are some residual differences in the two calculations, which I think can be attributed to floating point discrepancies:
function [f, grad_f] = class24_fun(x)
f = x(1)^4 + x(2)^2 - x(1)^2 * x(2);
grad_f = [4*x(1)^3 - 2*x(1)*x(2);
function [g, h, grad_g, grad_h] = ...
g(1) = 1 - 2 * x(1) * x(2) / 3;
g(2) = (3 * x(1)^2 - 4 * x(2)) / 3 + 1;
grad_g = [-2 * x(2)/3, 2 * x(1);
Best Answer