[Optimization] fmincon not respecting nonlinear constraints

6 views (last 30 days)
Hi,
Apologies if this is posted in the wrong section of the forum.
I am trying to perform nonlinear optimization using fmincon. However, it is behaving in a way that I cannot explain. In short, it terminates optimization and tells me that constraints were satisfied when clearly they are not.
I think posting all the code will only obfuscate the problem, so I will just post the bare minimum:
objfun:
function fval = objfun_up(~)
fval = 0;
There is no objective for this example, it is just a "find" problem. However, the behaviour occurs even in other cases where I am using an objective function.
confun:
function [c, ceq] = confun2(P)
load vars
P = reshape(P,[m m]);
H = B*D + (Im-B)*P;
piH = statdist(H);
c = lambda*A - n*(60/tau)*piH;
ceq = [];
The maths is irrelevant. In short, the nonlinear constraint function takes the program variable vector P, does some nonlinear stuff to it and outputs c. In this example, I only have inequality constraints.
You will notice that c depends on n. All the constants are stored in vars and are read in correctly. I have checked everything many times and there are no obvious or stupid mistakes.
Here is the call to fmincon:
options = optimset('Algorithm','active-set');
lb = zeros(1,m^2);
ub = ones(1,m^2);
[P,~,exitflag] = fmincon(@objfun,D(:),[],[],[],[],lb,ub,@confun,options);
P = reshape(P,[m m]);
Again, just ignore the maths. But I think the important parts to note are: I have very simple upper and lower bounds (0 < p < 1) and there are no other linear equality or inequality constraints. Everything depends on c = confun(P).
So as I said, c depends very much on n. Now here is what happens when I run the optimization with increasing values of n.
1. Starting at n = 3, the behaviour is as expected:
No feasible solution found. fmincon stopped because the predicted change in the objective function is less than the default value of the function tolerance but constraints were not satisfied to within the default value of the constraint tolerance.
OK, great. n is low so c = lambda*A - n*(60/tau)*piH (ignoring the maths) is almost certainly greater than zero.
Sanity checks:
confun(P) = 3.7983 3.9712 4.4778 1.2078 4.8830 7.1656 0.7788 5.3027 -1.8769 0.2918
any(confun(P) > 0) = 1
exitflag = -2
Everything as expected. You can see that only one of the values of c is less than zero, so the constraints have obviously not been met.
2. Now, when I get to n = 10, the weirdness starts happening:
Local minimum found that satisfies the constraints.
Optimization completed because the objective function is non-decreasing in feasible directions, to within the default value of the function tolerance, and constraints were satisfied to within the default value of the constraint tolerance.
OK, great. Seems like I found a solution. Checking:
exitflag = 1
but:
confun(P) = 0.4947 -0.0496 0.3744 -1.2497 0.4694 1.1195 -2.3594 0.6577 -6.6541 -4.8028
any(confun(P) > 0) = 1
So it tells me that my constraints are satisfied, when clearly we can see that they are not. Half of the values of c are greater than zero.
3. I then forcibly run the optimization for higher values of n. Eventually I get to n = 18.
Optimization completed because the objective function is non-decreasing in feasible directions, to within the default value of the function tolerance, and constraints were satisfied to within the default value of the constraint tolerance.
Checking:
confun(P) = -4.8472 -6.6988 -5.6686 -5.4916 -4.7158 -0.1210 -7.1805 -1.6490 -12.6144 -11.0132
any(confun(P) > 0) = 0
exitflag = 1
So eventually I find a solution, manually. I know that one has to exist because it is a pretty trivial constraint that is eventually met with large enough n. But what is going on with fmincon? Why does it falsely evaluate the constraints as being satisfied? Am I doing something wrong or is this a bug?
Thank in advance,
  1 Comment
Frank
Frank on 29 Apr 2023
Unfortunately fmincon is not open source, I guess you would have to write your own constrained optimization code.

Sign in to comment.

Answers (2)

Matt J
Matt J on 12 Oct 2017
any(confun(P) > 0) is the wrong test. You have to look at any(confun(P) > TolCon).

Matt J
Matt J on 29 Apr 2023
The maths is irrelevant. In short, the nonlinear constraint function takes the program variable vector P, does some nonlinear stuff to it and outputs c. In this example, I only have inequality constraints.
The math is not irrelevant. fmincon assumes the non-linear constraint function to have very specific mathematical properties like differentiability and non-stochasticity. We cannot see whether those properties hold for this problem because the mathematics are hidden inside some 3rd party function statdist. Below is a simple example to show how this behavior can be observed if the nonlinear constraint functions contain randomization operations.
opts=optimoptions('fmincon','Algorithm','active-set','Display','none');
[x,fval,exitflag]=fmincon(@(x)x,2,[],[],[],[],0,1,@confun,opts)
x = 1
fval = 1
exitflag = 1
confun(x)
ans = 0.2196
function [c,ceq]=confun(x)
ceq=[];
c=rand-0.5;
end

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!