Message Boards Message Boards

0
|
10705 Views
|
4 Replies
|
0 Total Likes
View groups...
Share
Share this post:

Why doesn't Compile work when I change Function to Compile?

Posted 11 years ago
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. >>
POSTED BY: Richard Gaylord
4 Replies
Compile needs to know the variable type and its rank.
From the documentation:

Compile[ { { x1, t1, n1}, ... }, expr ] assumes that xi is a rank ni array of objects, each of a type that matches ti.
POSTED BY: Frank Kampas
Posted 11 years ago
thanks for the response. unfortumately, i don't understand what it means i have to do to make Compile work in my program 

the variable type - all i'm working with are integers - does that mean the variable type is Integer? i'm aslo using lists of 0;s and 1's (ordered pairs for the update rules and nested lists for the gameboard).
the rank - i have no idea what that means.

can you provide clues or show me how to write the program so i can use Compile? 

and to the point, would using Compile even make the program run faster?

what i want to do is use WL to create a GoL program that runs as fast as possible. i do not want to use CellularAutomaton becuase i don't beleive that the program in the CellularAutomaton is written in WL and even if it is, it is a totally opaque black box and i agree with the statement on Feynman's office  blackboard when he died

"what i cannot create, i cnnot understand"
POSTED BY: Richard Gaylord
Ok, here's a simple example:
sum = Compile[{{x, _Real, 1}}, Plus @@ x]
sum[Range[5]]
15.
POSTED BY: Frank Kampas
Posted 11 years ago
oh, now i understand how to use Compile. thanks much.
POSTED BY: Richard Gaylord
Reply to this discussion
Community posts can be styled and formatted using the Markdown syntax.
Reply Preview
Attachments
Remove
or Discard

Group Abstract Group Abstract