0
$\begingroup$

I have a function which runs fine when I evaluate it. However, when I try to find its optimal parameters using FindMinimum it quickly consumes all available memory (i.e., it runs for some time and the memory in the "resource monitor" keeps increasing very fast until the computer eventually freezes).

The following code defines my function:

f=With[{Kj=150., w=20., Vf=100., cap=2500., n=90,m=225, p=40, RML=35, L=3., delta=1., dt=1./900, dx=1./9, Ssteps=5},
Compile[{{rm,_Integer,1}, {a,_Real}, {b,_Real},{c,_Real}},
    Module[{k0=Table[0.,{n}], kr=Table[0.,{n-2},{p}], Fk=Table[0.,{5},{n}], Rk=Table[0.,{5},{n-2},{p}],
          Fq=Table[0.,{4},{n-1}], Fin=Table[0.,{4},{n-2}], Rq=Table[0.,{4},{n-2},{p}], Shutoff=False,
          j=1, fi, qin, qr,qf,qsum,TT=0.,FTT=0.,RTT=0.,Tsteps=Quotient[Length[rm],Ssteps],RM,RMori,
          RMChngd=False, RMChngd1=False},
          RM=Table[rm[[(jj-1)*Ssteps+Floor[ii dx/2]+1]] 300.,{jj,Tsteps},{ii,1,n-2}]; RMori=Table[a,{n-2}]; 
          kr=Rk[[-1,All]]=ReplacePart[#,(a delta/Vf),1]&/@kr;
          RTT=TT=Total@Total@kr dx;
          While[TT>0.,
               If[RMChngd==False&&Max[k0]>L cap/Vf, RMori=RM[[1]]; RMChngd=True];
               If[RMChngd1==False&&j>c 100,RMori=RM[[2]];RMChngd1=True];
               fi=demR[Last/@kr] gamma[Take[k0,{2,-2}],Take[k0,{3,-1}]];
               qf=Fq[[Mod[j,4]+1]]=floF[Most@k0,Rest@(Fk[[1]]),Total@Fq,Join[Total@Fin,{0.}],Join[fi dx,{0.}]];
               qin=Fin[[Mod[j,4]+1]]=Subtract[fi,b Most@qf] dx;
               Fk=RotateLeft[Fk];
               k0=Fk[[-1]]=cMin[Join[{0.},Divide[Subtract[Most@qf,Rest@qf]+qin,Vf],{0.}]+k0,L Kj];
               qsum=Total@Rq;
               qr=Transpose[Join[Transpose[floR[Most/@kr,Rest/@Rk[[1]],Most/@qsum]],{fi}]];
               qr[[All,RML]]=cMin[RMori,qr[[All,RML]]];
               Rq[[Mod[j,4]+1]]=qr;
               Rk=RotateLeft[Rk];
               kr=Rk[[-1]]=((Join[{0.},#]&/@(Divide[Subtract[Most/@qr,Rest/@qr],Vf]))+kr);
               If[(Shutoff==False)&&j>m,Shutoff=True;kr=ReplacePart[#,0.,1]&/@kr];
               FTT+=Total@k0;RTT+=Total@Total@kr dx;If[j>m,TT=Total@k0];
               j++];(RTT+FTT) dt dx],CompilationOptions->{"InlineExternalDefinitions"->True}]];

The definition of f above uses the following methods:

Kj=150.;w=20.;Vf=100.;cap=2500.;L=3.;dx=1./9;
demF=Compile[{{p1,_Real},{p2,_Real}}, Max[0,Subtract[Min[p1 Vf,L cap],p2]], CompilationOptions->{"InlineExternalDefinitions"->True}];
demR=Compile[{{p1,_Real}}, Min[p1 Vf,cap], Parallelization->True,RuntimeAttributes->{Listable},CompilationOptions->{"InlineExternalDefinitions"->True}];
supF=Compile[{{p1,_Real}}, Min[Subtract[L Kj,p1] w,L cap], CompilationOptions->{"InlineExternalDefinitions"->True}];
NsupF=Compile[{{p1,_Real},{p2,_Real},{p3,_Real},{p4,_Real}}, Max[0,Min[Subtract[L Kj,p1] Vf-(p2+p3),L cap]-p4], CompilationOptions->{"InlineExternalDefinitions"->True}];
NsupR=Compile[{{p1,_Real},{p2,_Real}}, Min[Subtract[Kj,p1] Vf-p2,cap], CompilationOptions->{"InlineExternalDefinitions"->True}];
floF=Compile[{{p1,_Real},{p2,_Real},{p3,_Real},{p4,_Real},{p5,_Real}}, Min[demF[p1,p5],NsupF[p2,p3,p4,p5]], Parallelization->True,RuntimeAttributes->{Listable},CompilationOptions->{"InlineExternalDefinitions"->True,"InlineCompiledFunctions"->True}];
floR=Compile[{{p1,_Real},{p2,_Real},{p3,_Real}}, Min[demR[p1],NsupR[p2,p3]], Parallelization->True,RuntimeAttributes->{Listable},CompilationOptions->{"InlineExternalDefinitions"->True,"InlineCompiledFunctions"->True}];
gamma=Compile[{{p1,_Real},{p2,_Real}}, Min[1,Divide[supF[p2],(demF[p1,0.]+0.001)]], Parallelization->True,RuntimeAttributes->{Listable},CompilationOptions->{"InlineExternalDefinitions"->True,"InlineCompiledFunctions"->True}];
cMin=Compile[{{p1,_Real,1},{p2,_Real,1}}, p1 #+p2 Subtract[1,#]&@UnitStep[Subtract[p2,p1]]];

Sample test:
sample code runs 1000s of times without any increase in memory

Do[f[{5, 5, 5, 5, 5, 5, 5, 5, 5, 5}, 1200, 0.12, 3], {10000}] 

However, when I use the following FindMinimum function, the memory keeps increasing and the computer freezes.

FindMinimum[{f[{x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10]},2500,0.12,cc],2<=cc<=5&&And@@Thread@LessEqual[1,{x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10]},8]&&{x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10],cc}\[Element]Integers},{x[1],x[2],x[3],x[4],x[5],x[6],x[7],x[8],x[9],x[10],cc}];

I ran across this related question on memory problems, but no solutions. So there is something happening during the FindMinimum iterations that is indefinitely increasing the memory. Any insight is greatly appreciated!

$\endgroup$
2
$\begingroup$

I suspect part of the problem may be in specifying integer variables, e.g. if the underlying code does branching (offhand I don't know if this happens though). So you could change it to take a real vector and use Round on that in f[...]. Also it is best to avoid symbolic preprocessing. THis can be done by "black boxing" the objective so that it only exists on explicit numeric input. Like so:

g[aa : {_Real ..}, bb_Integer, cc_Real, dd_Real] := f[aa, bb, cc, dd]

FindMinimum[{g[{x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], 
     x[10]}, 2500, 0.12, cc], 
   2 <= cc <= 5 && 
    And @@ Thread@
      LessEqual[
       1, {x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], x[9], 
        x[10]}, 8]}, {x[1], x[2], x[3], x[4], x[5], x[6], x[7], x[8], 
   x[9], x[10], cc}]

I do not know if these changes are sufficient to make it run safely to completion (my test run is still going). They seem like a reasonable place to start though.

$\endgroup$
  • $\begingroup$ So far so good...mine running too without any problem. earlier it would crash by now. on a side note, I expect FindMinimum to be very fast compared to NMinimize since the former only looks for local minima. Is that true? $\endgroup$ – brama Nov 20 '14 at 23:02
  • $\begingroup$ It might be true in general but when Round is used in FindMinimum I really don't know what to expect. Well, one thing I expect is that it might not give a very good result; I don't think it has particularly good ideas about dealing with that whereas NMinimize can sometimes handle discrete valuedness reasonably well. $\endgroup$ – Daniel Lichtblau Nov 20 '14 at 23:32
  • $\begingroup$ unfortunately it is not converging incorrectly, {2182.88, {x[1] -> 1.70007, x[2] -> 1.70007, x[3] -> 1.70007, x[4] -> 1.70007, x[5] -> 1.70007, x[6] -> 1.70007, x[7] -> 1.70007, x[8] -> 1.70007, x[9] -> 1.70007, x[10] -> 1.70007, cc -> 2.3}}. Any small perturbation of x[i] gives a better result. $\endgroup$ – brama Nov 21 '14 at 22:00
  • $\begingroup$ By "it" I assume you mean "FindMinimum". I'd suggest going with NMinimize and taking the speed hit. It has a better chance of dealing with discrete values. $\endgroup$ – Daniel Lichtblau Nov 21 '14 at 22:16
  • $\begingroup$ Yes. I mean FindMinimum. But the problem with NMinimize is that for larger number of variables, the search space increases exponentially and NMinimize takes too long to converge to global optima. Do you suggest using fewer iterations to converge to a local optima? $\endgroup$ – brama Nov 22 '14 at 3:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.