How can I perform non-linear constrained optimization using fmincon over a range of values for the non-linear constraint?
Show older comments
I'm trying to minimize an objective function (portfolio risk) subject to a non-linear constraint (portfolio return) by finding optimal asset shares within the portfolio. At the moment I have been able to do so for a given level of return entered manually into the non-linear contraint function as a scalar. However, I would like to be able to calculate and store optimal asset shares over a range of levels of return without having to manually change them in the constraint function each time.
The objective function is:
function f = objecfun(x);
p=csvread('trialpolitical.csv');
f = p'*(x.*x);
end
The non-linear constraint (with a manually entered level of return 'g' of 0.0252):
function [c, ceq] = nonlconstr(x)
c = [];
r=csvread('trialreturns.csv');
g=0.0252;
ceq = [g-(ones(1,35)*(x.*r))];
end
The file I am running the optimization from is:
clear all
x0=csvread('x0.csv');
r=csvread('trialreturns.csv'); %asset returns
p=csvread('trialpolitical.csv'); %asset political risk
m=csvread('trialconstraints.csv'); %maximum asset shares
options = optimset;
% Modify options setting
options = optimset(options,'Display', 'off');
options = optimset(options,'Algorithm', 'interior-point');
A=[];
b=[];
Aeq=ones(1,35);
beq=1;
lb=zeros(35,1);
ub=m;
[x fval] = fmincon(@objecfun,x0,A,b,Aeq,beq,lb,ub,@nonlconstr);
Any help would be much appreciated!
Answers (1)
Rewrite your nonlinear constraint this way. By the way, these constraints look pretty linear to me
function [c, ceq] = nonlconstr(x,g,r)
c = [];
ceq = [g-(ones(1,35)*(x.*r))];
end
Then call fmincon as
i=0;
for g=range_of_g
i=i+1;
[x(i),fval(i)]=fmincon(@objecfun,x0,A,b,Aeq,beq,lb,ub,@(x)nonlconstr(x,r,g));
end
Except of course it's better to pre-allocate x(i) and fval(i).
3 Comments
John D'Errico
on 29 Apr 2023
Edited: John D'Errico
on 29 Apr 2023
@Frank, if you don't like the answer, then you are completely free to post your own answer, insted of saying how bad this answer is. That is, if you know a better way to solve it, then show the better way. If you don't know how to solve the problem, then maybe your complaint is not appropriate?
@Frank It is not possible to store solutions for a continuum of g as the OP said he wished to do. A digital computer can only store a finite number of results. However, if you wanted to pursue a single solution x valid for an upper and lower bound on the portfolio return, it would be trivial to modify the proposed code:
function [c, ceq] = nonlconstr(x,gLower,gUpper, r)
ceq = [];
c(1) = [+gLower-(ones(1,35)*(x.*r))];
c(2) = [-gUpper+(ones(1,35)*(x.*r))];
end
As in 2012, though, I still think it would be better to write these as linear constraints, which the problem-based workflow will now do automatically for us,
x=optimvar('x',35,'Lower',0,'Upper',m);
y=sum(x.*r);
Constraints.con_sum=sum(x)<=1;
Constraints.con_gLower=y>=gLower;
Constraints.con_gUpper=y<=gUppper;
sol = solve( optimproblem( 'Objective',x.'*(x.*p),'Constraints',Constraints) )
Categories
Find more on Quadratic Programming and Cone Programming in Help Center and File Exchange
Community Treasure Hunt
Find the treasures in MATLAB Central and discover how the community can help you!
Start Hunting!