Optimization: share additional output of cost function with constraint function

5 views (last 30 days)
I have a well defined optimization problem in which I have a separate cost function and a separate constraint function:
Cost = @(C)costcenterroad(C,lp,xref,yref,T,rw);
Nonlinconstr=@(C)nonlcon(C,lp,rw,xref,yref,sol);
[C,fval] = fmincon(Cost,C1,[],[],[],[],[],[],Nonlinconstr);
Inside the cost function (which is called first by fmincon), I evaluate nonlinear functions of the decision variables (C in this case). The outputs of the nonlinear function determine the cost.
However, in the constraint function I need to evaluate the same function, with the same decesion variables (thats the way fmincon works; first the cost, then the contraints). Hence, I would rather use the values already calculated in the cost functions.
I tried to do this by using a structure SOL as an output of the cost function, and provide it as an input to the constraint function hence (also see code above);
function [J,sol]=costcenterroad(C,lp,xref,yref,T,rw)
function [c,ceq]=nonlcon(C,lp,rw,xref,yref,sol)
However, Matlab will tell that "sol" is unknown. I'am guessing that "sol" is not an output when the function `costcenterroad` is called. I also used 'sol' as a global variable, but this is not very elegant and fast.
Does anyone have any suggestions how to do this? Your help will be greatly appreciated!
  2 Comments
Martijn
Martijn on 7 Mar 2012
I just did some extra testing and found out that indeed, saving in the cost function globally, and calling it in the constraint function globally, is slower than evaluating the functions just for a second time separately in the constraint function.
Hence, there must be a smart solution without the use of global variables that will save my day!
Martijn
Martijn on 7 Mar 2012
Based on what Seth DeLand referred to, I tried the following:
[Cost,Nonlincontr]=ObjectiveAndConstraints
[C,fval] = fmincon(Cost,C1,[],[],[],[],[],[],Nonlincontr,lp,L,v,xref,yref,T,rw);
The set {lp,L,v,xref,yref,T,rw} are constrant parameters in the optimization, defined a-priori.
And this:
function [Cost,Nonlincontr]=ObjectiveAndConstraints
Cost = @costroad;
Nonlincontr=@nonlc;
%Will store items calculated in the objective function.
d=[];
dteta=[];
phi=[];
u1=[];
x=[];
y=[];
J=[];
c=[];
ceq=[];
function J=costroad(C) %some function which requires v,L,C
[x,y,dx,dy,ddx,ddy]=evalcubspline(lp,C); %evaluate spline
%Left out code that translates these {x,..,ddy} to cost
J=sum(cost)
end
function [c,ceq]=nonlc %requires intermediate solution from cost function
c=[d-rw; -(phi'+pi/3); phi'-pi/3; -(u1'+pi/3); u1'-pi/3];
ceq=[x(1)-xref(1);x(end)-xref(end);y(1)-yref(1);y(end)-yref(end)]; %equality constraints;
end
end
%%%%%%%%%%%%%
Unfortunatly I get the error:
Error using ObjectiveAndConstraints>costroad
Too many input arguments.
Error in fmincon (line 601)
initVals.f = feval(funfcn{3},X,varargin{:});
Error in RoadSegment (line 132)
[C,fval] =
fmincon(Cost,C1,[],[],[],[],[],[],Nonlincontr,lp,L,v,xref,yref,T,rw);
Caused by:
Failure in initial user-supplied objective function evaluation.
FMINCON cannot continue.

Sign in to comment.

Accepted Answer

Seth DeLand
Seth DeLand on 7 Mar 2012
There was a good discussion on this issue here: http://www.mathworks.com/matlabcentral/newsreader/view_thread/269936
The technical term for this practice is "Memoization". There's some more good information on memoization in MATLAB in Loren's blog post:

More Answers (1)

Martijn
Martijn on 7 Mar 2012
I found the answer after some struggeling with passing on the parameters. Here is the solution:
[Cost,Nonlincontr]=ObjectiveAndConstraints(lp,L,v,xref,yref,T,rw);
[C,fval] = fmincon(Cost,C1,[],[],[],[],[],[],Nonlincontr)
Where the set {L,..,rw} are parameters (array,structures whatever).
The function ObjectiveAndConstraints looks like:
function [Cost,Nonlincontr]=ObjectiveAndConstraints(lp,L,v,xref,yref,T,rw)
Cost = @(C)costroad(C,lp,L,v,xref,yref,T,rw);
Nonlincontr=@(C)nonlc(C,lp,L,v,xref,yref,T,rw);
%Will store items calculated in the objective function.
d=[];
dteta=[];
phi=[];
u1=[];
x=[];
y=[];
function J=costroad(C,lp,L,v,xref,yref,T,rw)
J=something based on inputs
end
function [c,ceq]=nonlc(C,lp,L,v,xref,yref,T,rw)
c=something based on inputs
ceq=something based on iputs
end
end
Hopefully this well help someone else :)

Products

Community Treasure Hunt

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

Start Hunting!