MATLAB Answers

How fmincon shifts x0 when it does not strictly satisfy the upper and lower bounds?

64 views (last 30 days)
When you get the following message in running fmincon:
Your initial point x0 is not between bounds lb and ub; FMINCON
shifted x0 to strictly satisfy the bounds.
How the x0 is shifted? Is it a reproducible shift? Can the shifted x0 be recorded?

  2 Comments

babak naghizadehsafa
babak naghizadehsafa on 17 Apr 2019
I am copying part of my code here. The x0 that is fed to fmincon are either between zero or one (including 0 and 1)
lb_scaled = zeros(1,length(lb));
ub_scaled = ones(1,length(ub));
options = optimoptions('fmincon','DiffMinChange',0.0001,'Display','Iter');
[par_fit_speg1_scaled,residue_speg1,exitflag_speg1,output_speg1] ...
= fmincon(fun_speg1,par_0_scaled_speg1,...
[],[],[],[],lb_scaled,ub_scaled,[],options);
fclose('all');
%Model evaluations
[epsilon_speg1,time_speg1] = FEBio_run_swelling_HM(...
par_fit_speg1_scaled(1),par_fit_speg1_scaled(2),par_fit_speg1_scaled(3),par_fit_speg1_scaled(4),...
par_fit_speg1_scaled(5),par_fit_speg1_scaled(6),a0,e,p_speg1,lb,ub,time_resample,step_size);

Sign in to comment.

Accepted Answer

Alan Weiss
Alan Weiss on 18 Apr 2019
I believe that if you get this message, then you have made an error. You gave a start point that is infeasible with respect to the bounds, and this is a mistake. fmincon does the best it can to try to continue despite the error. If I got that message, I would examine my code carefully and eliminate the cause of the error, rather than trying to figure out exactly how fmincon works around my error.
Alan Weiss
MATLAB mathematical toolbox documentation

  2 Comments

Catalytic
Catalytic on 18 Apr 2019
You gave a start point that is infeasible with respect to the bounds, and this is a mistake.
That's news to me. Why is it assumed that the initial point supplied by the user will be feasible with respect to bounds, but not any of the other constraints?
Walter Roberson
Walter Roberson on 18 Apr 2019
The documentation for x0 indicates,
Initial point, specified as a real vector or real array. Solvers use the number of elements in, and size of, x0 to determine the number and size of variables that fun accepts.
  • 'interior-point' algorithm — If the HonorBounds option is true (default), fmincon resets x0 components that are on or outside bounds lb or ub to values strictly between the bounds.
  • 'trust-region-reflective' algorithm — fmincon resets infeasible x0 components to be feasible with respect to bounds or linear equalities.
  • 'sqp', 'sqp-legacy', or 'active-set' algorithm — fmincon resets x0 components that are outside bounds to the values of the corresponding bounds.
As "strictly between the bounds" and "to be feasible with respect to bounds" is not documented in further detail, I would tend to assume that it might change between releases.

Sign in to comment.

More Answers (2)

Matt J
Matt J on 17 Apr 2019
Edited: Matt J on 17 Apr 2019
I don't know precisely how the shifting algorithm works, but I think it's safe to assume that it is independent of the objective function. Therefore, if you just replace your objective function with a constant,
myObjective=@(x) 0
and run fmincon with that, the minimization should terminate in one iteration at the shifted x0, and you can then inspect it.

  3 Comments

Walter Roberson
Walter Roberson on 17 Apr 2019
Even though the objective is constant, fmincon will attempt to optimize the constraints, so other values can get moved as well. Values that are not constrained can get moved arbitrarily far as the algorithms flail around trying combinations of circumstances and just happening to do well with a greatly moved parameter, just because the changes to the other constrained parameters reduced the constraint violation slightly.
Matt J
Matt J on 17 Apr 2019
OK, well maybe if you replace the objective with a constant and discard the other (non-bound) constraints...?
Matt J
Matt J on 17 Apr 2019
In case it's of interest, the following experiment seems to support my hypothesis that the "shifted x0" for the interior point method is independent of both the objective function and the non-bound constraints.
All of the optimizations below terminate in zero iterations at the same point, c. If the shifted x0 had varied with the addition of the more complicated constraints, the 2nd and 3rd call to fmincon below should have taken more than zero iterations and/or terminated at some point other than c.
x0=[0;0;0];
fun0=@(x) 0;
lb=[0.1;0.1;0.1];
ub=[1;1;1];
opts=optimoptions('fmincon','Algorithm','interior-point');
c=fmincon(fun0,x0, [],[],[],[], lb,ub,[],opts); %the shifted x0 for simple bounds?
%% Now construct a problem with more complicated additional constraints, but whose
% solution is c.
fun=@(x) norm(x-c)^2;
A=-[1,1,1]; b=A*c;
Aeq=[1,1,-1]; beq=Aeq*c;
nonlcon=@(x) deal( norm(x).^2-2*norm(c).^2 , norm(x).^2-norm(c).^2 );
[x0,fval0,exitflag0,stats0]=fmincon(fun0,x0, A,b,Aeq,beq, lb,ub,nonlcon,opts);
x0,stats
[x1,fval,exitflag,stats]=fmincon(fun,x0, A,b,Aeq,beq, lb,ub,nonlcon,opts)
x1,stats

Sign in to comment.


Walter Roberson
Walter Roberson on 17 Apr 2019
For activeSet, sqp, and sqpLegacy:
Any x0 value that is less than the lower bound for that entry, is replaced with the lower bound for that entry.
Any x0 value that is greater than the lower bound for that entry, is replaced with the upper bound for that entry.
The calculation is effectively
min( max(x0, lower_bounds), upper_bounds )
though not implemented that way.
For Trust Region Reflective, the helper routine startx() is called, which attempts to place the point in the center of the section... but it has to figure out what a sensible "center" in the case where bounds are finite. Some funky things are done with comparing abs() of the finite bounds to 1, and I do not follow those at the moment. The x0 is replaced by the finite bound adjusted by 1/2 of the absolute value of the finite bound but always at least 1/2 in the case where the bound was near 0; the point is adjusted on the infinite side of the finite bound. If both bounds are infinite, 1 is used.
In the case of Interior Point, shiftInitPtToInterior() is called. Unfortunately that is a .p so I cannot see how it calculates the new points.

  0 Comments

Sign in to comment.

Sign in to answer this question.