Violation Nonlinear Constraints Fmincon Interior-Point Matlab
I Am Trying to Impose Two Nonlinear Constraints with Fmincon (Interior-Point) in Matlab: Sqrt(W*S*W')
I am trying to impose two nonlinear constraints with fmincon (interior-point) in Matlab:
sqrt(w*S*w') <= sigmaTgt/sqrt(260)
sqrt(w*S*w') >= sigmaTgt/sqrt(260)-0.02/sqrt(260)
I tried the following:
function [c,ceq] = in_nonlconstr(w, S)
c(1) = sqrt(w*S*w') - tgtVolAnn/sqrt(260);
c(2) = - sqrt(w*S*w') + ( tgtVolAnn/sqrt(260) - 0.02/sqrt(260) );
ceq = [];
end
but after the optimization I keep getting that sqrt(w*S*w') satisfies c(1) but not c(2), despite an exitflag of 1 and the solver having converged.
Am I writing it correctly or is there smth wrong with my solver?
Message from output.message:
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 optimality tolerance, and constraints are satisfied to within the default value of the constraint tolerance.
Stopping criteria details:
Optimization completed: The relative first-order optimality measure, 9.821943e-07, is less than options.OptimalityTolerance = 1.000000e-06, and the relative maximum constraint violation, 0.000000e+00, is less than options.ConstraintTolerance = 1.000000e-06.
Optimization Metric Options relative first-order optimality = 9.82e-07 OptimalityTolerance = 1e-06 (default) relative max(constraint violation) = 0.00e+00 ConstraintTolerance = 1e-06 (default)
1 Answer
Give this a shot:
options = optimset('OptimalityTolerance', 1e-20, 'ConstraintTolerance', 1e-20);
% this may need to be instead started with the function name, depends on your MATLAB version
options = optimset('fmincon','OptimalityTolerance', 1e-20, 'ConstraintTolerance', 1e-20);
fmincon(....., options) % i.e. what you already are passing to fmincon but adding additional tolerances
Let me know if that solves your problem. If not my variable names are probably wrong, I'd need you to run options=optimset('fmincon') and post the variable names inside options to set the tolerances. The other option you have is to change your algorithm - MATHWORKS says sqp is usually better than the method you're using:
options = optimset('fmincon','Algorithm','sqp','TolConSQP',1e-20) % other choices are 'active-set' or 'trust-region-reflective' and don't have the `TolConSQP` tolerance parameter, which you may not need at all anyhow
You of course can use a lower tolerance if it works for your application - it seems 1e-20 is the largest for any of the algorithms. See here for documentation: