How can I expedite the speed of fmincon optimization code
10 views (last 30 days)
Show older comments
I use the following code to optimize my problem, I used 4 different function in my optim function, However it is too slow. I have been runing it from last night ( almost 16 hours) and it still calculated 9 iterations. What should I do to make it faster?
warning('off');
x0=[1;1;1]; % Starting guess
lb=[0.5;0.5;0.5];
ub=[1.25;1.27;4];
options = optimoptions('fmincon','outputfcn',@outfun,'Display','iter','Algorithm','interior-point','Tolx',1e-15,'Tolfun',1e-16,'MaxFunEvals',600,'MaxIter',100);
[x,fval,exitflag,output]=fmincon(@optim,x0,[],[],[],[],lb,ub,[],options)
And my optim function is as follow:
function f=optim(x)
%%%%%x1 H2 for com 12, x2 H2 for com34, x(3) is for interval
%tau=5;
%H1=0.00125;
alpha11=0.1;
alpha12=0.15;
H11=1.25;
H12=1.27;
CI=580;
Cp=3000;
Cr=2000;
for j=2:3 % number of intervals
t1(j-1)=j*x(3);
t2(j-1)=(j-1)*x(3);
Inspcost1(j-1)=MyF(x(1),x(2),t1(j-1));
Inspcost2(j-1)=MyF(x(1),x(2),t2(j-1));
Inspcostall(j-1)=j.*abs((Inspcost2(j-1)-Inspcost1(j-1)));
end
Inspcost=CI*sum(Inspcostall(j-1));%%%%%first item in numerator
for j=2:3
Downcost1(j-1)=abs(Inspcost2(j-1)-Inspcost1(j-1)); %%%%first part in downtime cost
Down211(j-1)=MyF(H11,H12,t1(j-1));
Down212(j-1)=MyF(H11,H12,t2(j-1));
Down21(j-1)= t1(j-1).*abs(Down212(j-1)-Down211(j-1)); %%%%(1) in second part in downtime cost
Down22(j-1)=abs(t1(j-1).*(1-Down211(j-1))-t2(j-1).*(1-Down212(j-1))); %%%%(2) in second part in downtime cost
end
for j=2:3
for m=1:3
Down23each(j-1,m)=IntF(H11,H12,m,t2(j-1),t1(j-1)); %%%%(3) in second part in downtime cost
end
end
for j=2:3
Down23(j-1)=sum(Down23each(j-1,:)); %%%%(3) in second part in downtime cost
Downcost2(j-1)=Down21(j-1)-Down22(j-1)+Down23(j-1); %%%%total second part in downtime cost
Downall1(j-1)=Downcost1(j-1).*Downcost2(j-1);
end
Downcost=Cp*sum(Downall1);
for j=2:3
Lencycle1(j-1)=t1(j-1).*abs((Inspcost2(j-1)-Inspcost1(j-1)));
end
Lenthcycle=sum(Lencycle1); %%%%%denominator
Totalcost=Inspcost+Downcost+Cr; %%%%total numerator
f=10*Totalcost/Lenthcycle;
3 Comments
Accepted Answer
Steven Lord
on 16 Nov 2017
1.
warning('off');
Please don't do this. We don't make code warn simply because we want to show some text. We intend / hope that the warnings alert you to potential problems in your code or ways to improve the behavior and/or the performance of your code.
If you have reviewed a particular warning, understand it, and know that you can safely ignore it I would silence that particular warning using its identifier.
2.
Inspcost1(j-1)=MyF(x(1),x(2),t1(j-1));
What is MyF? If it is your own function, how complicated is it?
3.
Down23each(j-1,m)=IntF(H11,H12,m,t2(j-1),t1(j-1)); %%%%(3) in second part in downtime cost
What is IntF? How complicated is it?
4.
I agree with Stephen's and Matt's suggestions to profile your code. If you can start another session of MATLAB on your machine (leaving your optimization in progress) profile this line of code:
y = optim(x0);
Use the information the profiler gives you to identify the bottlenecks. Also open your code in the MATLAB Editor and see if any of the orange Code Analyzer messages are located where the bottlenecks are. If they are, they may offer guidance on how to improve the performance of that bottleneck.
2 Comments
Steven Lord
on 16 Nov 2017
So one call to your objective function takes almost 2 minutes. Repeat that call in the Profiler to identify what parts of that function takes the most time. If MyF or IntF is the bottleneck, look at the information the Profiler shows for them to see what part of those functions takes the longest.
If you can identify a particular small (no more than 15-20 lines, ideally) segment of code as your bottleneck that's more or less self contained, post it and describe what it's supposed to do and you may receive some suggestions on how to improve the performance of that code.
More Answers (1)
Walter Roberson
on 16 Nov 2017
Sometimes (definitely not always), if you have the Symbolic Toolbox, you can pass a symbolic vector to your optimization routine and get back a single formula that calculates the value. Then you can simplify() the formula. Sometimes the resulting formula is faster to calculate than going through all of the code steps.
A step after that is to use matlabFunction and ask it to write the formula to a file and leave the default optimize option on: the resulting .m file should calculate the formula efficiently, having done sub-expression optimization. In the case of longer expressions, the optimization of the formula can take a fair bit of time (over half an hour) so it is not always worth doing unless the code is going to be executed a lot; I suggest that the first time around that you tell matlabFunction to write to a file, that you tell it to turn off optimization.
2 Comments
Walter Roberson
on 16 Nov 2017
X = sym('X', [3 1]);
Fsym = optim(X);
The above might fail, depending on what you do inside the functions that you did not post. If it works, then
Fsymopt = simplify(Fsym);
f = matlabFunction(Fsymopt, 'vars', {X}, 'File', 'F.m', 'Optimize', false);
If that works, then you can
foo = @()f([1.2;1;1]);
t=timeit(foo)
and see whether you got a speed increase.
The step after that would be to try
fopt = matlabFunction(Fsymopt, 'vars', {X}, 'File', 'Fopt.m', 'Optimize', true);
which might potentially take a fair amount of time. When it finishes then you can
foo = @()fopt([1.2;1;1]);
t=timeit(foo)
and see if you improved.
See Also
Categories
Find more on Get Started with Optimization Toolbox 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!