4
$\begingroup$

I have written an implementation of eight variants of the PSO-algorithm and I want to test them over a set of test functions. I am using parallelization as it improves the speed a lot and I have also, without much know-how, done some compiling. As I just very recently discovered that such a thing as "compile" even exists, I would like to ask if I have done it properly in the sample below. Are there any bad mistakes?

Another thing is the actual algorithm part. I recently asked about a problem I encountered when switching to ParallelDo from Do and I was told that I really should use functions without side-effects. Is there any obvious way to do better than what I have done concerning the parallelization?

(*Some parameters*)
d=30;ksi=0.72984;m=10;it=300; 

(*Sum of squares*)
sqc=Compile[{{x,_Real,1}},Total[x^2],CompilationOptions->
{"InlineExternalDefinitions"->True},Parallelization->True]

(*Attempt to speed up subtraction of two vectors*)
dif=Compile[{{a,_Real,1},{b,_Real,1}},(a-b),CompilationOptions->
{"InlineExternalDefinitions"->True},Parallelization->True]

(*The speed update equation*)
vupd1=Compile[{{v,_Real,1},{x,_Real,1},{z1,_Real,1},{z2,_Real,1},
{z3,_Real,1}},ksi(v+Total[{RandomReal[{0.,4.1},{d}]*dif[z1,x],
RandomReal[{0.,4.1},{d}]*dif[z2,x],RandomReal[{0.,4.1},
{d}]*dif[z3,x]}]/3.),CompilationOptions->
{"InlineExternalDefinitions" -> True},Parallelization->True]

(*Function to be minimized and boundary enforcing*)
f[x_]:=If[AllTrue[x,-100.<#<100.&],sqc[x],Infinity](*Sphere*)

SetSharedVariable[resm];

(*More parameters*)
resm={};rangx={50.,100.};rangv={-100.,100.};
max=Abs[rangv[[2]]-rangv[[1]]]/2;S=50;Y=Table[Mod[{n-1,n,n+1},S],{n,0.,S-1}]+1;

(*The algorithm*)
(*Start loop generating runs of the algorithm and initialize some values*) 
ParallelDo[res={};x=Table[RandomReal[rangx,d],{S}];
v=Table[RandomReal[rangv,d],{S}];v=(v-x)/2;xb=x;bv=Map[f,xb];gb=MinimalBy[x,f][[1]];H=f[gb];
 (*Actual algorithm loop*)
 Do[For[i=1,i<=S,i++,v[[i]]=vupd1[v[[i]],x[[i]],xb[[Y[[i]][[1]]]],xb[[Y[[i]][[2]]]],
xb[[Y[[i]][[3]]]]];
x[[i]]=x[[i]]+v[[i]];
R=f[x[[i]]]; (*This is the only actual call of the function*)
(*All the rest if for updating the values based on the single function call*)
If[R<=bv[[i]],xb[[i]]=x[[i]];bv[[i]]=R;If[R<=H,gb=x[[i]];H=R]];];
res={res,gb};,{it}];AppendTo[resm,Partition[Flatten[res],d]];,{m}]; 
$\endgroup$
  • 1
    $\begingroup$ I haven't looked at your code in detail. But just be aware that Compile and all the parallel functions have many subtleties and limitations, and are not easy to use. In fact, their incautious use can produce subtle bugs and reduce performance drastically. Things like sums of squares and subtraction of vectors as you show here will not gain much/anything from being compiled; compilation is most beneficial for procedural code. So, I would compile what you place into ParallelDo and leave the rest alone, if I were you. $\endgroup$ – Oleksandr R. Oct 20 '15 at 16:30

Your Answer

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

Browse other questions tagged or ask your own question.