In a
this Wolfram blog it says (see #2) that using Compile instead of Function can greatly speed up a program. Compile is also used by an unkown individual in a CA program given in a nice unpublshed manuscript by Fateman (http://www.cs.berkeley.edu/~fateman/papers/cashort.pdf) (see sections 2.1 and 2.5). Moreover, in the Wolfram blog it says (see secton 9) that one should use pattern-matching sparingly in order to increase speed.
i am guilty of making extensive use of both Function and pattern-matching in my programs because (1) i like to write one-liner code (i'm peverse that way) which i do using Function and/or its shorthand notation (...#...)& and (2) pattern-matching is compatible with the way i think.
side note: one could argue that the mind is a pattern-matching machine and this is related to the use of analogy which is fundamental to thinking in general and to model building in sclence, specifically - but that discussion belongs in a different group - note: i think that a community group for philosophical (but with no b...sh.....g.'ing) discussions related to computation, cellular automata, NKS, etc would be nice.
i accept the view taken by SW when he was creating Mathematica - i recall him saying that one should not develop software based on current hardware limitations - and by analogy, i write programs that work the way my mind works rather than the way my computer works. i.e. i want the code for a model to be as direct a transcription of the way i formulate the model in my head as possible.
e.g. when i give travel directions, i say say something like "go two blocks, turn left, continue to the traffic light, ..." which uses both nested function calls (and no temporary variable names) with 'go followed by turn followed by continue' and pattern-matching with 'to the traffic light'.
Once a program has been created, it can then be modified in order to optiimize it for speed if that's worth the trouble to do (i personally don't care much about execution time unless it's the time left until my execution)
with that lengthy preamble, i was wondering what the speed increase would be, if any. if the one-liner Game of Life program in the final section of my tutorial was modified accordingly.
my one-liner makes use of 4 anonymous (pure) function and i've been trying to replace them with the use of Compile but have not made much (any) progress on doing that.
According to the Wolfram blog, all i need to do is:
(1) enclose the 4 formal parameters in the various anonymous functions in {}
(2) replace the word Function with the word Compile (note: i am not familiar with Compile because that function wasn't yet a part of WL when i learned the language and i have never used it).
here's the code (i have specifed the gameboard (the starting configuration) and the number of time steps but these can be changed for Timing tests).
i was able to get rjg3 simply by changing rjg2 so that it uses Function[w, ...] instead of (...#...)& for the outermost anonymous function and i was able to get rjg4 simply by using {} to enclose the formal parameters in the 4 Function calls. but then, following the blog, simply replacing Function with Compile in rjg4 to get rjg5 doesn't work.
Can someone tell me how to use Compile in the GoL one-liner code so i can then do Timing tests?
Thanks
In[1]:= gliderLife = {{0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0,
0}, {0, 0, 1, 1, 0, 0, 0}, {0, 0, 1, 0, 1, 0, 0}, {0, 0, 1, 0, 0,
0, 0}, {0, 0, 0, 0, 0, 0, 0}, {0, 0, 0, 0, 0, 0, 0}};
In[2]:= LifeGame[steps_] :=
Module[{gameboard, liveNeighbors, update},
gameboard = gliderLife;
liveNeighbors[mat_] := Apply[Plus, Map[RotateRight[mat, #] &,
{{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1,
0}, {1, 1}}]];
update[1, 2] := 1;
update[_, 3] := 1;
update[_, _] := 0;
SetAttributes[update, Listable];
NestList[update[#, liveNeighbors[#]] &, gameboard, steps]]
In[3]:= rjg1 = LifeGame[4];
In[4]:= rjg2 =
NestList[(MapThread[List,
Function[
x, {x, Function[y,
Apply[Plus, Map[Function[z, RotateRight[y, z]],
{{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0,
1}, {1, -1}, {1, 0}, {1, 1}}]]][x]}][#], 2] /.
\
{{1, 2} ->
1, {_, 3} -> 1, {_, _} -> 0}) &, gliderLife, 4];
In[5]:= rjg1 == rjg2
Out[5]= True
In[6]:= rjg3 =
NestList[Function[w,
MapThread[List,
Function[
x, {x, Function[y,
Apply[Plus, Map[Function[z, RotateRight[y, z]],
{{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0,
1}, {1, -1}, {1, 0}, {1, 1}}]]][x]}][w], 2] /.
\
{{1, 2} ->
1, {_, 3} -> 1, {_, _} -> 0}], gliderLife, 4];
In[7]:= rjg1 == rjg3
Out[7]= True
In[8]:= rjg4 =
NestList[Function[{w},
MapThread[List,
Function[{x}, {x,
Function[{y},
Apply[Plus, Map[Function[{z}, RotateRight[y, z]],
{{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0,
1}, {1, -1}, {1, 0}, {1, 1}}]]][x]}][w], 2] /.
\
{{1, 2} ->
1, {_, 3} -> 1, {_, _} -> 0}], gliderLife, 4];
In[9]:= rjg1 == rjg4
Out[9]= True
In[10]:= rjg5 =
NestList[Compile[{w},
MapThread[List,
Compile[{x}, {x,
Compile[{y},
Apply[Plus, Map[Compile[{z}, RotateRight[y, z]],
{{-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0,
1}, {1, -1}, {1, 0}, {1, 1}}]]][x]}][w], 2] /.
\
{{1, 2} ->
1, {_, 3} -> 1, {_, _} -> 0}], gliderLife, 4];
During evaluation of In[10]:= MapThread::list: List expected at position 2 in MapThread[List,Compile[{x},{x,Compile[{y},Plus@@Compile[{<<1>>},RotateRight[<<2>>]]/@{{<<2>>},{<<2>>},{<<2>>},{<<2>>},{<<2>>},{<<2>>},{<<2>>},{<<2>>}}][x]}][w],2]. >>
During evaluation of In[10]:= Compile::cprank: Compile cannot determine the rank of the result tensor. The length of Compile[{x},{x,Compile[{y},Plus@@Compile[{z},RotateRight[y,z]]/@{{-1,-1},{-1,0},{-1,1},{0,-1},{0,1},{1,-1},{1,0},{1,1}}][x]}][w] in MapThread[List,Compile[{x},{x,Compile[{y},Plus@@Compile[{<<1>>},RotateRight[<<2>>]]/@{{<<2>>},{<<2>>},{<<2>>},{<<2>>},{<<2>>},{<<2>>},{<<2>>},{<<2>>}}][x]}][w],2] is unknown at compiling time; evaluation will use the uncompiled function. >>
During evaluation of In[10]:= CompiledFunction::cfsa: Argument {{0,0,0,0,0,0,0},{0,0,0,0,0,0,0},{0,0,1,1,0,0,0},{0,0,1,0,1,0,0},{0,0,1,0,0,0,0},{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}} at position 1 should be a machine-size real number. >>
During evaluation of In[10]:= CompiledFunction::cfsa: Argument {{0,0,0,0,0,0,0},{0,0,0,0,0,0,0},{0,0,1,1,0,0,0},{0,0,1,0,1,0,0},{0,0,1,0,0,0,0},{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}} at position 1 should be a machine-size real number. >>
During evaluation of In[10]:= CompiledFunction::cfsa: Argument {{0,0,0,0,0,0,0},{0,0,0,0,0,0,0},{0,0,1,1,0,0,0},{0,0,1,0,1,0,0},{0,0,1,0,0,0,0},{0,0,0,0,0,0,0},{0,0,0,0,0,0,0}} at position 1 should be a machine-size real number. >>
During evaluation of In[10]:= General::stop: Further output of CompiledFunction::cfsa will be suppressed during this calculation. >>