Why does MATLAB fmincon ignore non-linear constraints? - matlab

I want to use MATLABs fmincon function to solve a non-linear problem of which I know that it can be solved in a different way very easily but I want to use fmincon (you might not need the following detailed information about the problem but I provided them in case you need):
Function f(x) is a quadratic function with its vertex at point (5|1).
f(x)=0.1(x-5)^2+1 for 0<=x<=5
Function g(x) is a polynom of order 4 with its vertex at Point (c|0).
g(x)=(x-c)^4 for 0<=x<=c
Function h is just a line on the x axis.
h=0 for c<=x<=5
I want to minimize the Area between the function f(x) and the two connected functions g(x) and h, in the interval [0,5]
minimize A=2*(int(f,[0,5])-int(g,[0,c]))=55/3 - (2*c^5)/5
Also I have the constraint that f(x) must always be 1 unit above the functions g(x) and h.
From the graph I know that the variable c must be between 0 and 2 (just a range for the fmincon function).
This is my .m file:
clc
clear
format long;
options = optimoptions(#fmincon, 'Display', 'iter', 'Algorithm', 'interior-point');
fun=#(x)55/3 - (2*(x(1))^5)/5;
lb = [0];
ub = [2];
[x,fval] = fmincon(fun,[0.1],[],[],[],[],lb,ub,#cons_Q6,options)
The constraints file looks like this (I inserted a lot of values for x with an increment of 0.1):
function [c,ceq]=cons_Q6(x)
c=[(0.0-x(1))^4-0.1*(0.0-5)^2
(0.1-x(1))^4-0.1*(0.1-5)^2
(0.2-x(1))^4-0.1*(0.2-5)^2
(0.3-x(1))^4-0.1*(0.3-5)^2
(0.4-x(1))^4-0.1*(0.4-5)^2
(0.5-x(1))^4-0.1*(0.5-5)^2
(0.6-x(1))^4-0.1*(0.6-5)^2
(0.7-x(1))^4-0.1*(0.7-5)^2
(0.8-x(1))^4-0.1*(0.8-5)^2
(0.9-x(1))^4-0.1*(0.9-5)^2
(1.0-x(1))^4-0.1*(1.0-5)^2
(1.1-x(1))^4-0.1*(1.1-5)^2
(1.2-x(1))^4-0.1*(1.2-5)^2
(1.3-x(1))^4-0.1*(1.3-5)^2
(1.4-x(1))^4-0.1*(1.4-5)^2
(1.5-x(1))^4-0.1*(1.5-5)^2
(1.6-x(1))^4-0.1*(1.6-5)^2
(1.7-x(1))^4-0.1*(1.7-5)^2
(1.8-x(1))^4-0.1*(1.8-5)^2
(1.9-x(1))^4-0.1*(1.9-5)^2
(2.0-x(1))^4-0.1*(2.0-5)^2
(2.1-x(1))^4-0.1*(2.1-5)^2
(2.2-x(1))^4-0.1*(2.2-5)^2
(2.3-x(1))^4-0.1*(2.3-5)^2
(2.4-x(1))^4-0.1*(2.4-5)^2
(2.5-x(1))^4-0.1*(2.5-5)^2
(2.6-x(1))^4-0.1*(2.6-5)^2
(2.7-x(1))^4-0.1*(2.7-5)^2
(2.8-x(1))^4-0.1*(2.8-5)^2
(2.9-x(1))^4-0.1*(2.9-5)^2
(3.0-x(1))^4-0.1*(3.0-5)^2
(3.1-x(1))^4-0.1*(3.1-5)^2
(3.2-x(1))^4-0.1*(3.2-5)^2
(3.3-x(1))^4-0.1*(3.3-5)^2
(3.4-x(1))^4-0.1*(3.4-5)^2
(3.5-x(1))^4-0.1*(3.5-5)^2
(3.6-x(1))^4-0.1*(3.6-5)^2
(3.7-x(1))^4-0.1*(3.7-5)^2
(3.8-x(1))^4-0.1*(3.8-5)^2
(3.9-x(1))^4-0.1*(3.9-5)^2
(4.0-x(1))^4-0.1*(4.0-5)^2
(4.1-x(1))^4-0.1*(4.1-5)^2
(4.2-x(1))^4-0.1*(4.2-5)^2
(4.3-x(1))^4-0.1*(4.3-5)^2
(4.4-x(1))^4-0.1*(4.4-5)^2
(4.5-x(1))^4-0.1*(4.5-5)^2
(4.6-x(1))^4-0.1*(4.6-5)^2
(4.7-x(1))^4-0.1*(4.7-5)^2
(4.8-x(1))^4-0.1*(4.8-5)^2
(4.9-x(1))^4-0.1*(4.9-5)^2
(5.0-x(1))^4-0.1*(5.0-5)^2
];
ceq=[];
As you can see, I've set the bounds for the unknown variable so that x(1)=[0,2] and I have set the constraints in the range [0,5] although I would only need them in the range of [0,2] because of the bounds for x(1).
Now, when I solve it like this I get a solution that doesn't fit all the constraints. But when I delete the unneccessary constraints in the range ]2;5]
function [c,ceq]=cons_Q6(x)
c=[(0.0-x(1))^4-0.1*(0.0-5)^2
(0.1-x(1))^4-0.1*(0.1-5)^2
(0.2-x(1))^4-0.1*(0.2-5)^2
(0.3-x(1))^4-0.1*(0.3-5)^2
(0.4-x(1))^4-0.1*(0.4-5)^2
(0.5-x(1))^4-0.1*(0.5-5)^2
(0.6-x(1))^4-0.1*(0.6-5)^2
(0.7-x(1))^4-0.1*(0.7-5)^2
(0.8-x(1))^4-0.1*(0.8-5)^2
(0.9-x(1))^4-0.1*(0.9-5)^2
(1.0-x(1))^4-0.1*(1.0-5)^2
(1.1-x(1))^4-0.1*(1.1-5)^2
(1.2-x(1))^4-0.1*(1.2-5)^2
(1.3-x(1))^4-0.1*(1.3-5)^2
(1.4-x(1))^4-0.1*(1.4-5)^2
(1.5-x(1))^4-0.1*(1.5-5)^2
(1.6-x(1))^4-0.1*(1.6-5)^2
(1.7-x(1))^4-0.1*(1.7-5)^2
(1.8-x(1))^4-0.1*(1.8-5)^2
(1.9-x(1))^4-0.1*(1.9-5)^2
(2.0-x(1))^4-0.1*(2.0-5)^2
];
ceq=[];
then I get the right result. Does anyone know why this happens and why MATLAB does not respect the constraints when I put them up for the whole range [0,5]?

-Your problem is more related to calculus than matlab tool
constraints like
function [c]=cons_Q6(x)
c=[x < 0; x > 0]; are just ignored by fmincon, because they are not logical
Technically you need to know the optimum c before solving
this optimization problem
- Another issue A = int(f,[0,5])-int(g,[0,c]) = 55/6 - c^5/5 instead of
A = 2*(int(f,[0,5])-int(g,[0,c])) = 55/3 - (2*c^5)/5
Factor 2 is used whether for even whether for odd function (like cosine or since).
Even for those kind of function the integration interval is reduced by half
I updated your optimization function and the solution c is as follow
x = [0, c], constraint is g(x)-f(x)-1<= 0--> (x-c)^4 -0.1(x-5)^2 <=0
x = [c, 5], constraint is h(x)-f(x)-1<= 0--> -0.1(x-5)^2 <=0
c must be predefined or guessed in advance, here I supposed c = 2
because your upper bound ub = 2
As a result
x = [0, 2], --> (x-c)^4 -0.1(x-5)^2 <=0
x = [2, 5], --> -0.1(x-5)^2 <=0
cons_Q6(x) is as follow
function [c,ceq]=cons_Q6(x)
c=[(0.0-x)^4-0.1*(0.0-5)^2;
(0.1-x)^4-0.1*(0.1-5)^2;
(0.2-x)^4-0.1*(0.2-5)^2;
(0.3-x)^4-0.1*(0.3-5)^2;
(0.4-x)^4-0.1*(0.4-5)^2;
(0.5-x)^4-0.1*(0.5-5)^2;
(0.6-x)^4-0.1*(0.6-5)^2;
(0.7-x)^4-0.1*(0.7-5)^2;
(0.8-x)^4-0.1*(0.8-5)^2;
(0.9-x)^4-0.1*(0.9-5)^2;
(1.0-x)^4-0.1*(1.0-5)^2;
(1.1-x)^4-0.1*(1.1-5)^2;
(1.2-x)^4-0.1*(1.2-5)^2;
(1.3-x)^4-0.1*(1.3-5)^2;
(1.4-x)^4-0.1*(1.4-5)^2;
(1.5-x)^4-0.1*(1.5-5)^2;
(1.6-x)^4-0.1*(1.6-5)^2;
(1.7-x)^4-0.1*(1.7-5)^2;
(1.8-x)^4-0.1*(1.8-5)^2;
(1.9-x)^4-0.1*(1.9-5)^2;
(2.0-x)^4-0.1*(2.0-5)^2;
-0.1*(2.1-5)^2;
-0.1*(2.2-5)^2;
-0.1*(2.3-5)^2;
-0.1*(2.4-5)^2;
-0.1*(2.5-5)^2;
-0.1*(2.6-5)^2;
-0.1*(2.7-5)^2;
-0.1*(2.8-5)^2;
-0.1*(2.9-5)^2;
-0.1*(3.0-5)^2;
-0.1*(3.1-5)^2;
-0.1*(3.2-5)^2;
-0.1*(3.3-5)^2;
-0.1*(3.4-5)^2;
-0.1*(3.5-5)^2;
-0.1*(3.6-5)^2;
-0.1*(3.7-5)^2;
-0.1*(3.8-5)^2;
-0.1*(3.9-5)^2;
-0.1*(4.0-5)^2;
-0.1*(4.1-5)^2;
-0.1*(4.2-5)^2;
-0.1*(4.3-5)^2;
-0.1*(4.4-5)^2;
-0.1*(4.5-5)^2;
-0.1*(4.6-5)^2;
-0.1*(4.7-5)^2;
-0.1*(4.8-5)^2;
-0.1*(4.9-5)^2;
-0.1*(5.0-5)^2;
];
ceq=[];
The constraints in the range ]2;5] are very necessary keep them
clc
clear
format long;
options = optimoptions(#fmincon, 'Display', 'iter', 'Algorithm',...
'interior-point');
fun=#(x)55/6 - (x^5)/5;
lb = [0];
ub = [2];
[c, A] = fmincon(fun,[0.1],[],[],[],[],lb,ub,#cons_Q6,options)
solution :
c = 1.257432726024430
A = 8.537951710969493

Related

Find values of constants in equation using MATLAB

I have equation F(f)=a*f^3+b*f+c. I have known vectors of the data, p, independent variable, 'f'. I need to find values of a, b, c.
What I tried:
function [ val ] = myfunc(par_fit,f,p)
% This gives me a,b,c
% p= af^3 +bf +c
val = norm(p - (par_fit(1)*(f.^3))+ (par_fit(2)*f) + (par_fit(3)));
end
my_par = fminsearch(#(par_fit) myfunc(par_fit,f,p),rand(1,3));
This gives me my_par = [1.9808 -2.2170 -24.8039], or a=1.9808, b=-2.2170, and c=-24.8039, but I require that b should be larger than 5, and c should be larger than zero.
I think your problem might be because your objective function is incorrect:
val = norm(p - (par_fit(1)*(f.^3))+ (par_fit(2)*f) + (par_fit(3)));
should probably be:
val = norm(p-(par_fit(1)*f.^3+par_fit(2)*f+par_fit(3)));
But you can constrain the values of variables when you do minimisation by using fmincon rather than fminsearch. By setting the lb input to [-Inf -Inf 0], the first two coefficients are allowed to be any real number, but the third coefficient must be greater than or equal to zero. For example: (I've also shown how to solve the problem (without the non-negativity constraint) using a matrix method)
% Sample data
f=(0:.1:1).';
p=2*f.^3+3*f+1+randn(size(f))
% Create Van der Monde matrix
M=[f.^3 f f.^0];
C=M\p; % Solve the matrix problem in a least squares sense if size(f)>size(F)
my_par=fmincon(#(c) norm(p-(c(1)*f.^3+c(2)*f+c(3))),rand(1,3),[],[],[],[],[-Inf 5 0],[])
C.'
plot(f,p,'o',f,M*C,f,my_par(1)*f.^3+my_par(2)*f+my_par(3))

Matlab: finding the maximum point in for loop

For two variable function, say f(x,y)=x^2+y+b, where b is:
b=raylrnd(1*sqrt(2/pi),10^6,1) %% b is 1x1000000 vector
and subject to the constraint that: 2*x+1<=b.
I want to find the maximum of the function for a interval say x is between [-10,10], and y is between [-10,10] (Off course, my actual function is more complete than this, I will need help to set up the framework so I can apply it to my actual function).
Is there a way to implement this?
Attempt:
Step 1: Write a file objfun.m.
function f = objfun(x,b)
f = x(1)^2+(2)+b;
Step 2: Write a file confuneq.m for the nonlinear constraints.
function [c, ceq] = confuneq(x)
% Nonlinear inequality constraints
c = 2*x(1)+1-b;
Step 3: Invoke constrained optimization routine.
for i=1:1:length(b)
bi=b(i);
x0 = [-1,1]; % Make a starting guess at the solution
options = optimoptions(#fmincon,'Algorithm','sqp');
[x,fval] = fmincon(#objfun,x0,[],[],[],[],[],[],...
#confuneq,options);

Error while using "fmincon" in MATLAB

I have a model with linear constraints and a nonlinear objective function, and I'm trying to use "fmincon" toolbox of MATLAB to solve it. Actually, the Aineq is a 24*13 matrix, and the Aeq is a 24*13 matrix as well. But when I insert this command:
>> [x , lambda] = fmincon(#MP_ObjF,Aineq,bineq,Aeq,beq);
I encounter this error:
Warning: Trust-region-reflective method does not currently solve this type of
problem, using active-set (line search) instead.
In fmincon at 439??? Error using ==> fmincon at 692
Aeq must have 312 column(s).
What is probably wrong with it? Why should Aeq have 312 columns?!? I will appreciate any help. Thanks.
If you look at the documentation for fmincon (doc fmincon ) you'll see an input called opt.In this you can set the algorithm used by matlab to solve your minimization problem. If you run
Opt=optimset('fmincon');
Then you can modify the algorithm option using
Opt.algorithm="active-set";
Just send Opt to fmincon and then matlab wont have this problem anymore. Take a look inside Opt and you'll find a ton of options you can change to modify the optimization routine.
As for the number of columns. If you're using linear constraints then you input argument for MPobjF must be a column vector with n rows and 1 column. Then A must be m X n. Where M is the number of constraints and n is the number of variables. This is so that matrix multiplication is well defined.
I'm sorry if my first answer was ambiguous. Maybe it will help if I do an example, as I saw several suspicious things in your comments. Lets say we want to minimize x^2 + y^2 + (z-1)^2 subject to x + y + z = 1, 2x + 3y - 4z <= 5, x,y,z>=-5. The solution is obviously (0,0,1)...
We first have to make our objective function,
fun = #(vec) vec[1]^2 + vec[2]^2 + (vec[3]-1)^2;
For fmincon to work, there can only be one input to the function, but that input can be a vector. So here x = vec[1] and so on...I think your comments are indicating that your objective function has multiple inputs. If you need to pass some parameters that aren't being optimized there is documentation for this on Matlab's site (http://www.mathworks.com/help/optim/ug/passing-extra-parameters.html)
Then we can set the optimization settings
opt = optimset('fmincon');
opt.algorithm = 'active-set';
You may also have to modify the large-scale setting for the algorithm warning to go away, I can't remember...
Then we can set
Aeq = [1,1,1]; % equality constraint, if you had another eq constraint, it would be another row to Aeq
beq = 1; % equality constraint
A = [2,3,-4]; % inequality
b = 5; % inequality
lb = [-5;-5;-5]; % lower bound
x0 = [0.5;0.5;0]; % initial feasible guess, needs to be a column vector
[x,fval] = fmincon(fun,x0,A,b,Aeq,beq,lb,[],[],opt);
Then hopefully this finds x = [0;0;1]

fmincon does not match nonlinear constrains

I trying to minimize function handle with respect to vector of parameters beta0. My function uses built-in mvncdf function which uses positive definite covariance matrix. This matrix is counted from part of vector of parameters. Also there is constraint for absolute value of some parameters to be less than one.
I set constraints to fmincon in two ways: upper and lower bounds to required values and use following nonlinear constraint:
function [c,ceq] = pos_def(beta0)
rho_12 = beta0(end-2,1);
rho_13 = beta0(end-1,1);
rho_23 = beta0(end,1);
sigma111=[1 rho_12 rho_13; rho_12 1 rho_23; rho_13 rho_23 1];
sigma110=[1 rho_12 -rho_13; rho_12 1 -rho_23; -rho_13 -rho_23 1];
sigma101=[1 -rho_12 rho_13; -rho_12 1 -rho_23; rho_13 -rho_23 1];
sigma100=[1 -rho_12 -rho_13; -rho_12 1 rho_23; -rho_13 rho_23 1];
eig111 = eig(sigma111);
eig110 = eig(sigma110);
eig101 = eig(sigma101);
eig100 = eig(sigma100);
c = vertcat(-eig111,-eig110,-eig101,-eig100);
As all matrices are square and symmentric by constraction, as proxy to positive difiniteness I use signs of eigenvalues.
The optimization problem looks like:
opts = optimset ('Display','iter','TolX',1e-15,'TolFun',1e-15,...
'Algorithm','interior-point','MaxIter',100000,'MaxFunEvals',1000000);
xc3_3=fmincon(model, beta,[],[],[],[],lb,ub,#pos_def, opts)
But during estimation fmincon aborts with error
Error using mvncdf (line 193) SIGMA must be a square, symmetric, positive definite matrix.
Under debuging mode I can see that after two iterations of evaluation Matlab tries to estimate beta0 which does not sutisfy my nonlinear constraints,
beta0 =
-46.9208
33.2916
-2.1797
-46.4251
3.8337
-0.3066
6.1213
-20.9480
-1.7760
-0.1807
1.3950
4.5348
-0.9838
0.2600
-6.9887
-24.6157
-0.0112
-0.9923
-0.9284
0.7664
0.3062
And constraint c < 0 does not satisfied:
c =
0.3646
-1.2998
-2.0648
0.3646
-1.2998
-2.0648
0.3646
-1.2998
-2.0648
0.3646
-1.2998
-2.0648
I do not understand why this optimization tool trying to find solution in the prohibited area and how to avoid this problem. Or how to set constrains on positive definiteness in the linear way.
The optimizer is just evaluating points to see if they are feasible directions to move in or not. Within your model you should tell it that a particular direction is not a good one. The pseudo-code would look something like
GetEigvalues
if (positive definite) then
Do what you really want to happen
else
Return a large number
end
or alternatively
try
Do what you really want to happen
catch
Return a large number
end

Minimizing a function in matlab

I would like to minimize w'Hw, with respect to w, where w is a vector, and H is matrix.
And with the following constraint, |w1|+|w2|+|w3| < 3, ie. the l1 norm of the weights vector is less that 3.
How can I do this in matlab?
Thanks
You're trying to solve a quadratic minimization problem with linear constraints (also known as quadratic programming).
Do you know anything about your matrix H -- in particular, is it positive semidefinite? I would really expect this to be the case, since this is usual for the problem domains in which quadratic programming problems usually crop up.
If H really is positive semidefinite, and your only constraint is |w1|+|w2|+|w3| < 3, then, as Richie Cotton has already pointed out, the minimum is trivially at w=0. Maybe you have some additional constraints?
If you do have additional constraints, but H is still positive semidefinite, there are existing efficient solvers for this class of problem. In MATLAB, take a look at quadprog.
You'll have to reformulate your single nonlinear constraint |w1|+|w2|+|w3| < 3 as a series of linear constraints.
In the one-dimensional case, the constraint |w1| < 1 turns into two linear constraints:
w1 < 1
-w1 < 1.
In the two-dimensional case, the constraint |w1| + |w2| < 1 turns into four linear constraints:
w1+w2 < 1
w1-w2 < 1
-w1+w2 < 1
-w1-w2 < 1
I'll leave the extension to three dimensions to you.
you need to use the optimization toolbox, specifically fmincon:
use fun to establish w'Hw, and you want c(eq) = (|w1|+|w2|+|w3| - 3) <0 which you set with nonlcon (in the documentation).
I'd suggest you look at the fminsearch function in the matlab documentation.
Rasman, below is the fmincon code I am using:
function PortfolioWeights = GMVPC1Type2(SCM)
w0 = [0.1 0.1 0.1 0.1 0.1];
n = length(w0);
options = optimset('Display','final-detailed');
PortfolioWeights = fmincon(#myobj2,w0,[],[],ones(1,n),1,[],[],#myconstraint1,options)
function f = myobj2(w)
w = [w(1);w(2);w(3);w(4);w(5)];
f = w'*SCM*w;
end
end
-----------------------------------------------------------------------------
function [c ceq] = myconstraint1(w)
c = abs(w(1))+abs(w(2))+abs(w(3))+abs(w(4))+abs(w(5))-1
ceq = [];
end
------------------------------------------------------------------------------
I added in options = optimset('Display','final-detailed'); as you suggested. I get the following message:
Optimization stopped because the predicted change in the objective function,
6.115031e-009, is less than options.TolFun = 1.000000e-006, and the maximum constraint
violation, 0.000000e+000, is less than options.TolCon = 1.000000e-006.
Optimization Metric Options
abs(steplength*directional derivative) = 6.12e-009 TolFun = 1e-006 (default)
max(constraint violation) = 0.00e+000 TolCon = 1e-006 (default)
Active inequalities (to within options.TolCon = 1e-006):
lower upper ineqlin ineqnonlin
1
PortfolioWeights =
0.2000 0.2000 0.2000 0.2000 0.2000
The matrix I am using is:
0.000257165759136336 8.48196702102889e-05 9.27141501220362e-05 0.000111360154790061 0.000155196440517440
8.48196702102889e-05 0.000277377166669392 0.000101880007672550 0.000107375764193076 0.000117042329431538
9.27141501220362e-05 0.000101880007672550 0.000300697293925817 0.000112004860252653 0.000134354417344316
0.000111360154790061 0.000107375764193076 0.000112004860252653 0.000311028738698100 0.000147296211557256
0.000155196440517440 0.000117042329431538 0.000134354417344316 0.000147296211557256 0.000376418027192374