Minimizing a function in matlab - 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

Related

Strange wrong result for (un)coupled PDEs using MATLAB's pdepe, time is doubled

I am trying to solve two coupled reaction diffusion equations in 1d, using pdpe, namely
$\partial_t u_1 = \nabla^2 u_1 + 2k(-u_1^2+u_2)$
$\partial_t u_2 = \nabla^2 u_1 + k(u_1^2-u_2)$
The solution is in the domain $x\in[0,1]$, with initial conditions being two identical Gaussian profiles centered at $x=1/2$. The boundary conditions are absorbing for both components, i.e. $u_1(0)=u_2(0)=u_1(1)=u_2(1)=0$.
Pdepe gives me a solution without prompting any errors. However, I think the solutions must be wrong, because when I set the coupling to zero, i.e. $k=0$ (and also if I set it to be very small, say $k=0.001$), the solutions do not coincide with the solution of the simple diffusion equation
$\partial_t u = \nabla^2 u$
as obtained from pdepe itself.
Strangely enough, the solutions $u_1(t)=u_2(t)$ from the "coupled" case with coupling set to zero, and the solution for the case uncoupled by construction $u(t')$ coincide if we set $t'=2t$, that is, the solution of the "coupled" case evolves twice as fast as the solution of the uncoupled case.
Here's a minimal working example:
Coupled case
function [xmesh,tspan,sol] = coupled(k) %argument is the coupling k
std=0.001; %width of initial gaussian
center=1/2; %center of gaussian
xmesh=linspace(0,1,10000);
tspan=linspace(0,1,1000);
sol = pdepe(0,#pdefun,#icfun,#bcfun,xmesh,tspan);
function [c,f,s] = pdefun(x,t,u,dudx)
c=ones(2,1);
f=zeros(2,1);
f(1) = dudx(1);
f(2) = dudx(2);
s=zeros(2,1);
s(1) = 2*k*(u(2)-u(1)^2);
s(2) = k*(u(1)^2-u(2));
end
function u0 = icfun(x)
u0=ones(2,1);
u0(1) = exp(-(x-center)^2/(2*std^2))/(sqrt(2*pi)*std);
u0(2) = exp(-(x-center)^2/(2*std^2))/(sqrt(2*pi)*std);
end
function [pL,qL,pR,qR] = bcfun(xL,uL,xR,uR,t)
pL=zeros(2,1);
pL(1) = uL(1);
pL(2) = uL(2);
pR=zeros(2,1);
pR(1) = uR(1);
pR(2) = uR(2);
qL = [0 0;0 0];
qR = [0 0;0 0];
end
end
Uncoupled case
function [xmesh,tspan,sol] = uncoupled()
std=0.001; %width of initial gaussian
center=1/2; %center of gaussian
xmesh=linspace(0,1,10000);
tspan=linspace(0,1,1000);
sol = pdepe(0,#pdefun,#icfun,#bcfun,xmesh,tspan);
function [c,f,s] = pdefun(x,t,u,dudx)
c=1;
f = dudx;
s=0;
end
function u0 = icfun(x)
u0=exp(-(x-center)^2/(2*std^2))/(sqrt(2*pi)*std);
end
function [pL,qL,pR,qR] = bcfun(xL,uL,xR,uR,t)
pL=uL;
pR=uR;
qL = 0;
qR = 0;
end
end
Now, suppose we run
[xmesh,tspan,soluncoupled] = uncoupled();
[xmesh,tspan,solcoupled] = coupled(0); %coupling k=0, i.e. uncoupled solutions
One can directly check by plotting the solutions for any time index $it$ that, even if they should be identical, the solutions given by each function are not identical, e.g.
hold all
plot(xmesh,soluncoupled(it+1,:),'b')
plot(xmesh,solcoupled(it+1,:,1),'r')
plot(xmesh,solcoupled(it+1,:,2),'g')
On the other hand, if we double the time of the uncoupled solution, the solutions are identical
hold all
plot(xmesh,soluncoupled(2*it+1,:),'b')
plot(xmesh,solcoupled(it+1,:,1),'r')
plot(xmesh,solcoupled(it+1,:,2),'g')
The case $k=0$ is not singular, one can set $k$ to be small but finite, and the deviations from the case $k=0$ are minimal, i.e. the solution still goes twice as fast as the uncoupled solution.
I really don't understand what is going on. I need to work on the coupled case, but obviously I don't trust the results if it does not give the right limit when $k\to 0$. I don't see where I could be making a mistake. Could it be a bug?
I found the source of the error. The problem lies in the qL and qR variables of bcfun for the coupled() function. The MATLAB documentation, see here and here, is slightly ambiguous on whether the q's should be matrices or column vectors. I had used matrices
qL = [0 0;0 0];
qR = [0 0;0 0];
but in reality I should have used column vectors
qL = [0;0];
qR = [0;0];
Amazingly, pdpe didn't throw an error, and simply gave wrong results. This should perhaps be fixed by the developers.

Why does MATLAB fmincon ignore non-linear constraints?

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

Simulate left Truncated Gamma distribution with mean = 1 and variance =0.4

Suppose X~Γ(α, β), I would like to truncate all values of X
MATLAB codes:
t = 0.5; theta = 0.4;
syms alpha beta
EX = beta*( igamma(alpha+1,t/beta) / igamma(alpha,t/beta) ); %Mean
EX2 = beta^2*( igamma(alpha+2,t/beta) / igamma(alpha,t/beta) );%Second moment
VarX = EX2 -EX^2; %Variance
cond1 = alpha > 0; cond2 = beta > 0; cond3 = EX==1; cond4 = VarX ==theta;
conds =[cond1 cond2 cond3 cond4]; vars = [alpha, beta];
sol = solve(conds, [alpha beta], 'ReturnConditions',true);
soln_alpha = vpa(sol.alpha)
soln_beta = vpa(sol.beta)
The above code returns a numeric answer only if the constraint that α>0 is relaxed. The numeric answer has a negative value of α which is wrong since both α (shape parameter) and β (scale parameter) must be strictly positive.
Based on your title, I take it you want to generate samples from a Gamma distribution with mean = 1 and variance = 0.4 but want the distribution truncated to [0, inf].
If X ~ Gamma(alpha,beta), then by definition it must be nonnegative (see Gamma Distribution wiki, or MATLAB page). Indeed, both shape and scale parameters are also nonnegative. Note: MATLAB uses the (k,theta) parameterization found on the wiki page.
MATLAB has implemented probability distribution objects which make a lot of things very convenient from a practitioner perspective (or anyone who uses numerical approaches).
alpha = 0.4;
beta = 0.5;
pd = makedist('Gamma',alpha,beta) % Define the distribution object
Generating samples is now very easy.
n = 1000; % Number of samples
X = random(pd,n,1); % Random samples of X ~ Gamma(alpha,beta)
All that is left is to identify the shape and scale parameters that such that E[X] = 1 and Var(X) = 0.4.
You need to solve
alpha * beta = E[X],
alpha * (beta^2) = Var(X),
for alpha and beta. It is a system of two nonlinear equations with two unknowns.
However, truncation makes these obsolete but numerical approaches will work fine.
LB = 0.5; % lower bound (X > LB)
UB = inf; % upper bound (X < UB)
pdt = truncate(pd,LB,UB) % Define truncated distribution object
Xt = random(pd,n,1);
pdt =
GammaDistribution
Gamma distribution
a = 0.4
b = 0.5
Truncated to the interval [0.5, Inf]
Fortunately, the mean and variance of a distribution object are accessible whether or not it is truncated.
mean(pdt) % compare to mean(pd)
var(pdt) % compare to var(pd)
You can numerically solve this problem to obtain your parameters with something like fmincon.
tgtmean = 1;
tgtvar = 0.4;
fh_mean =#(p) mean(truncate(makedist('Gamma',p(1),p(2)),LB,UB));
fh_var =#(p) var(truncate(makedist('Gamma',p(1),p(2)),LB,UB));
fh =#(p) (fh_mean(p)-tgtmean).^2 + (fh_var(p)-tgtvar).^2;
[p, fval] = fmincon(fh,[alpha;beta],[],[],[],[],0,inf)
You can test the answer for validation:
pd_test = truncate(makedist('Gamma',p(1),p(2)),LB,UB);
mean(pd_test)
var(pd_test)
ans = 1.0377
ans = 0.3758
Note this seems ill-conditioned due to the desired truncation and target mean. This might be good enough depending on your application.
histogram(random(pd_test,n,1)) % Visually inspect distribution
Mean and variance combinations must be feasible under the base distribution (here, Gamma distribution), but if truncating, that further restricts the set of feasible parameters. For example, it would be impossible to truncate X~Gamma() to the interval [5, 500] and seek to get a mean of 2 or a mean of 600.
MATLAB code verified with version R2017a.
Also note that solutions from nonlinear solvers like fmincon may be sensitive to the initial starting point for some problems. If that numerical approach is giving issues, it may be a feasibility issue (as alluded to above) or it may require using multiple start points and multiple fmincon calls to get multiple answers, then use the best one.

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