Problem with the MaxFunctionEvaluations limit in fmincon options

I am using fmincon 1.0.9 (great tool!) with Scilab 2026.1.0 and I have noticed a minor problem. The MaxFunctionEvaluations option does not seem to work. Consider for example such a code:

opt = optimoptions("fmincon") ;
opt.MaxFunctionEvaluations = 80 ; 
opt.MaxIterations = 70 ;     
...

And in this run we can see that fmincon is stopped when MaxIterations = 70, although it should have been stopped 8 iterations before when the function was evaluated 80 times:

 Iter  Func-count  Function value   Feasibility   Step Length     Step Norm   First-order
                                                                               optimality
   60          78   -4.479239e-03    2.0260e-02    1.1262e-01    1.1049e+00    4.2933e-07
   61          79   -4.480577e-03    2.6660e-02    1.0000e+00    2.3026e+00    1.0336e-07
   62          80   -4.480941e-03    3.8018e-02    7.6680e-01    3.1317e+00    2.2585e-07
   63          87   -4.480941e-03    3.6414e-02    4.2745e-02    1.8983e+01    2.1303e-07
   64          88   -4.481343e-03    8.1311e-03    1.0000e+00    9.8214e-01    1.4422e-07
   65          90   -4.480977e-03    4.1020e-11    1.0000e+00    2.2829e+00    1.3258e-07
   66          91   -4.481778e-03    7.8694e-03    1.0000e+00    9.0123e-01    1.5371e-07
   67          92   -4.481977e-03    3.3721e-03    1.0000e+00    7.1226e-01    9.2874e-08
   68          93   -4.482168e-03    1.4315e-02    8.9239e-01    1.5808e+00    1.2420e-07
   69          95   -4.468018e-03    2.1033e-06    1.0000e+00    8.8025e+00    2.6441e-06
   70          96   -4.481633e-03    1.3874e-01    1.0000e+00    5.1207e+00    4.9743e-07

Termination message: Maximum number of iterations exceeded

And if I comment the line opt.MaxIterations = 70 ;, it does not stop either.

Hello,

Thanks for using fmicon. You’re right, this parameter is not taken into account, I will fix this ASAP.

S.

1 Like

Thanks @mottelet

MaxFunctionEvaluations is in my opinion indeed more interesting as it is related to the computing time of the function, which is typically what we would like to limit.

Hello,

In the meantime, you can control this in an OutputFcn callback, like in this small example:

function [f, g, H]=rosenfgh(x)
    f = 100*(x(2) - x(1)^2)^2 + (1-x(1))^2;
    if argn(1) > 1 // g required
        g = [-400*(x(2)-x(1)^2)*x(1)-2*(1-x(1));
            200*(x(2)-x(1)^2)];
        if argn(1) > 2// H required
            H = [1200*x(1)^2-400*x(2)+2, -400*x(1);
                -400*x(1), 200];  
        end
    end
end

function stop = callback(x,optimValues,state)
    stop = optimValues.funccount >= 10;
endfunction

opt=optimoptions("fmincon");
opt.SpecifyObjectiveGradient = %t;
opt.Display = "iter";
opt.HessianFcn = "objective";
opt.OutputFcn=callback;

problem = struct();
problem.objective = rosenfgh;
problem.x0 = [0;0];
problem.options = opt;

x=fmincon(problem)
 Iter  Func-count  Function value   Feasibility   Step Length     Step Norm   First-order
                                                                               optimality
    0           1    1.000000e+00    0.0000e+00    0.0000e+00    0.0000e+00    2.0000e+00
    1           8    9.531250e-01    0.0000e+00    2.5000e-01    1.0000e+00    1.2500e+01
    2           9    4.832057e-01    0.0000e+00    1.0000e+00    9.0278e-02    1.0117e+00
    3          15    4.570883e-01    0.0000e+00    5.0000e-01    4.2939e-01    9.5274e+00

Termination message:  Stopping optimization at current point as requested by user
1 Like

Hello,

I have updated the package (1.1 is the new version). You can just remove the current version then after restarting Scilab :

atomsSystemUpdate
atomsInstall fmincon
atomsLoad fmincon

Now the the MaxFunctionEvaluations option value is taken into account, but as a side effect the
number of objective function calls is now precisely counted. It was greatly underestimated, particularly when the gradient is not provided by the user (finite differences are used, hence many objective function calls are done).

S.

1 Like

Thanks S. @mottelet !

It now works. And indeed, on the same problem I have now Func-count=266 instead of 157 (in my case, I am using both function and constraint gradients).

Constraints finite difference gradients do not contribute to this counter.

S.