MATLAB Answers

Fmincon passing on variables between functions

36 views (last 30 days)
I have two questionw about the fmincon function in matlab. I'm using it for a large optimization. The objective function takes about 20sec per call.
The first question is: I calculate a lot of data in the objective function, which I also need in the constraint function. Is there a way to pass this data from the objective function to the constraints function. I know that it is possible to transfer data from the main function to the constraint function and from the main function to the objective function by using function handles. I cannot figure out how to transfer data between the objective and constraint function, however. Right now I use a quick fix; I save the data created in the objective function to a .mat file and then load it again in the constraint function. I prefer a neater solution though.
The second question is also about variable transfer. My optimization features 30 variables. I use an active-line approach, which means that the objective function is called 31 times for each iteration. I would like to have a waitbar which displays the status of each iteration. Therefore I'd like to have access to the amount of iterations and function calls in a separate function. A bit like the OutputFcn, but instead one that is called after each function call. A second solution would be to have the number of iterations/function calls available within the objective function.
Any help would be greatly appreciated.

  0 Comments

Sign in to comment.

Accepted Answer

Walter Roberson
Walter Roberson on 14 Jun 2011
Your objective function has two outputs, but objective functions for fmincon must have a single scalar output.
Your objective function is not being created correctly.
Your constraint function must accept a vector of x values as its only input.
Your constraint function is not being created correctly.
Variables will never be considered to be nested in a function if they appear as an input or output argument.
Any variables that you want to share, you have to define in the outer scope before you define the functions that will use them.
Putting these together:
function [] = objectiveconstraints(previous_variables)
objective=@(x) obj(previous_variables,x);
constraint=@con;
aircraft = []; %must initialize shared variables
function f = obj(previous_variables,x)
aircraft = calculations(previous_variables,x)
f = aircraft.objectivevalue;
end
function [c,ceq] = con(x)
%non linear inequalities at x
c = aircraft.c;
% Compute nonlinear equalities at x.
ceq = 0;
end
%Define problem
problem.x0 = x0;
%Define Objective function
problem.objective = objective;
%Define constraint function
problem.nonlcon = constraint;
%Perform optimization
[x,fval] = fmincon(problem);
end

  4 Comments

Show 1 older comment
Maximilian Hoffmann
Maximilian Hoffmann on 12 Jul 2017
I've got a similar problem and it's not working as well. Has anyone a suggestion what I'm doing wrong?
function [Curve, kappa, rho, my, psiKurveneu, Curveneu] = FunktionRollenhebelMulti (psiKurve,r,L,M,G)
u=[0 0 0 0 0 0.125 0.25 0.375 0.5 0.625 0.75 0.875 1 1 1 1 1];
x0=linspace(0,360,12);
k=5;
Curve=zeros(length(psiKurve),1);
Mrel=zeros(length(psiKurve),3);
kappa=zeros(length(psiKurve),1);
rho=zeros(length(psiKurve),1);
my=zeros(length(psiKurve),1);
a1=1/u(k+1);
a2=1/u(k+2);
a3=1/(1-u(length(x0)-1));
a4=1/(1-u(length(x0)));
a5=1/u(k+3);
a6=1/(1-u(length(x0)-2));
Aeq=[1 0 0 0 0 0 0 0 0 0 0 0;
0 0 0 0 0 0 0 0 0 0 0 1;
-a1 a1 0 0 0 0 0 0 0 0 a4 -a4;
a1^2 -(a1^2+a1*a2) a1*a2 0 0 0 0 0 0 -a3*a4 (a4^2+a3*a4) -a4^2;
-a1^3 a1*(a1^2+a1*a2+a2^2) -a1*(a1*a2+a2^2+a2*a5) a1*a2*a5 0 0 0 0 a3*a4*a6 -a4*(a3*a4+a3^2+a3*a6) a4*(a4^2+a4*a3+a3^2) -a4^3];
beq=[0;360;0;0;0];
objective=@(x) obj(x,u,r,L,M,G);
constraint=@(x) con(x,u,r,L,M,G);
%objectivevalue=0;
aircraft = []; %must initialize shared variables
function f = obj(x,u,r,L,M,G)
aircraft = calculations(x,u,r,L,M,G);
f = aircraft.objectivevalue;
end
function [c,ceq] = con(x,u,r,L,M,G)
%non linear inequalities at x
c = aircraft.c;
% Compute nonlinear equalities at x.
ceq = 0;
end
%Define problem
problem.x0 = x0;
%Define Objective function
problem.objective = objective;
%Define constraint function
problem.nonlcon = constraint;
problem.Aeq = Aeq;
problem.beq = beq;
problem.solver = 'fmincon';
options = optimoptions('fmincon');
problem.options = options;
%Perform optimization
[x,~] = fmincon(problem);
P=x;
[du,dP]=bspline_deriv(k,u,P);
[ddu,ddP]=bspline_deriv(k-1,du,dP);
[C,~]=DeBoor(k,u,P,241);
[dC,~]=DeBoor(k-1,du,dP,241);
[ddC,~]=DeBoor(k-2,ddu,ddP,241);
psiKurveneu=[C(1,:)' dC(1,:)'*pi/180/(2*pi) ddC(1,:)'*(pi/180)/(2*pi)^2];
Curveneu=zeros(length(psiKurveneu),1);
for i=1:length(psiKurve)
[Mrel(i, :)]=GLK_R(L(i, :),psiKurveneu(i, :),M(i, :));
[Curveneu(i), kappa(i), rho(i)]=GLK_Q(Mrel(i, :), r, -1);
[my(i)]=GLK_UD(G(i, :), M(i, :), exp(pi/180*psiKurveneu(i,1)*1i), Mrel(i, 2));
end
end
function [objectivevalue,c]= calculations (x,u,r,L,M,G)
k=5;
P=x;
[du,dP]=bspline_deriv(k,u,P);
[ddu,ddP]=bspline_deriv(k-1,du,dP);
[C,~]=DeBoor(k,u,P,241);
[dC,~]=DeBoor(k-1,du,dP,241);
[ddC,~]=DeBoor(k-2,ddu,ddP,241);
psiKurve=[C(1,:)' dC(1,:)'*pi/180/(2*pi) ddC(1,:)'*(pi/180)/(2*pi)^2];
Curve=zeros(length(psiKurve),1);
Mrel=zeros(length(psiKurve),3);
kappa=zeros(length(psiKurve),1);
rho=zeros(length(psiKurve),1);
my=zeros(length(psiKurve),1);
for i=1:length(psiKurve)
[Mrel(i, :)]=GLK_R(L(i, :),psiKurve(i, :),M(i, :));
[Curve(i), kappa(i), rho(i)]=GLK_Q(Mrel(i, :), r, -1);
[my(i)]=GLK_UD(G(i, :), M(i, :), exp(pi/180*psiKurve(i,1)*1i), Mrel(i, 2));
end
objectivevalue=max(-my(:));
c1=-min(dC(1,:))*pi/180/(2*pi);
c2=1./min(rho(rho(:)>0)).*(1/0.7-1)-1/r;
c3=-1./max(rho(rho(:)<0))-1/r;
c=[c1;c2;c3];
end
Namely, I want to use my B-Spline-Calculation in the function "calculations" simultaneously for my objective- and constraint-function. My Problem is, that I don't know how to use the "airplane" properly.
Walter Roberson
Walter Roberson on 12 Jul 2017
It is not guaranteed that the nonlinear constraint function will be called after each call to the objective function, and the nonlinear constraint function might be called multiple times in a row to try to find a position in range to evaluate. You therefore cannot count on the value having been calculated in the other routine.
If you have R2017a or later, see https://www.mathworks.com/matlabcentral/answers/348109-approximating-derivative-of-numerical-solution-within-event-function#comment_468397 for my demonstration of using memoization to save duplicate calculations.
Maximilian Hoffmann
Maximilian Hoffmann on 13 Jul 2017
Thank you very much! This was my initial doubt about it, because my function needs only 0,03 seconds per call due to my optimization of it. So shifting those variables between two functions every tenth call in obj-function for the constraint-function will probably take longer than running the function when needed. However many many thanks and best regards! Max :)

Sign in to comment.

More Answers (2)

Walter Roberson
Walter Roberson on 13 Jun 2011
You could use nested functions and shared variables; see here

  1 Comment

Jorrit
Jorrit on 14 Jun 2011
Thank you. Could you maybe elaborate a bit on the exact usage of the nested functions in combination with fmincon? I've added an answer, since the code it getting unreadable in this comment.

Sign in to comment.


Jorrit
Jorrit on 14 Jun 2011
Thanks Walter. I did a lot of searching and as I understand, the overall structure needs to be something like this:
function [] = objectiveconstraints(previous_variables)
objective=@obj
constraint=@con
function [f,aircraft] = obj(previous_variables,x)
aircraft = calculations(previous_variables,x)
f = aircraft.objectivevalue;
end
function [c,ceq] = con(aircraft)
%non linear inequalities at x
c = aircraft.c;
% Compute nonlinear equalities at x.
ceq = 0;
end
%Define problem
problem.x0 = x0;
%Define Objective function
problem.objective = objective(previous_variables,x0);
%Define constraint function
problem.nonlcon = constraint(aircraft);
%Perform optimization
[x,fval] = fmincon(problem);
end
I thought this should work, but I cannot seem to extract the aircraft structure, containing all calculation data from the objective and making it available inside the constraints function. I do really appreciate any help on this.

  0 Comments

Sign in to comment.

Community Treasure Hunt

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

Start Hunting!

Translated by