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.

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

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
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
on 13 Jul 2017

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

Start Hunting!
## 0 Comments

Sign in to comment.