MathGroup Archive 2005

[Date Index] [Thread Index] [Author Index]

Search the Archive

Re: Re: Nested iterators in Compile

  • To: mathgroup at smc.vnet.net
  • Subject: [mg55068] Re: [mg55032] Re: [mg55010] Nested iterators in Compile
  • From: "Wolf, Hartmut" <Hartmut.Wolf at t-systems.com>
  • Date: Fri, 11 Mar 2005 04:20:44 -0500 (EST)
  • Sender: owner-wri-mathgroup at wolfram.com

Hi Christoph,

I'll give my comments interspersed 

>-----Original Message-----
>From: Christoph Lhotka [mailto:lhotka at astro.univie.ac.at] 
To: mathgroup at smc.vnet.net
>Sent: Thursday, March 10, 2005 11:25 AM
>Subject: [mg55068] [mg55032] Re: [mg55010] Nested iterators in Compile
>
>Hello !
>
>I would define your compiled function this way:
>
>In[..]:=g = Compile[{{n, _Integer}}, Module[{i, j, s = 0},
>      Do[s += j, {i, n}, {j, i}]; 
>      Print[s]], {{s, _Integer}, {i, _Integer}, {j, _Integer}}]
>
>(see Help Browser for more details on how to declare variables inside
>subexpressions at the end of Compile)
>

Defining types for s,i,j wasn't the problem, the compiler can find out!


>The problem is, that you will get a similar error message, 
>when you do not
>define initial values for i and j, but the function worked, as 
>you can see
>here:
>
>In[..]:= g[100]
>Out[..]:=171700
>

In contrast to Maxim, you got your errors at compile time,
but the compiled code seemed to work.

But never ignore error messages: in fact because of your declarations 
of i, j within module, the compiler wasn't abe to compile the loop at
all,
because the i of Module was chosen as the ending value for j of the
inner loop
and that had no value, so the compiler cave up
and inserted a function call to the uncompiled Do-oop into the
incompiled code.

Be aware that the i,j in Module are different from the i,j in Do 
because of scoping for the iteration variables.  Check out in the Book!
In fact the compiler doesn't follow the correct scoping rules, seems to
be
the root of the problem!


>To suppress the error message I defined a value for i and j, 
>which should not
>be wrong, because, i and j are set inside the do - loop. But 
>there seems to be
>a serious problem with it:
>
>In[..]:=In[..]:=g = Compile[{{n, _Integer}}, Module[{i=0, j=0, s = 0},
>      Do[s += j, {i, n}, {j, i}]; 
>      Print[s]], {{s, _Integer}, {i, _Integer}, {j, _Integer}}]
>
>any time, I use the function, it will nothing else return, but 0..
>
>In[..]:=g[10/50/100/...]
>Out[..]:=0
>
>for any other initial value for i I get different results, so...
>

Yes this is because the i chosen by the compiler has a (constant) value,
and compiles with that; the result is the (wrong) function you got.



>HOW CAN THE INITIAL VALUE FOR I INFLUENCE THE RESULT OF THE DO - LOOP?
>
>as you can see in an uncompiled version, this should not 
>influence anything:
>
>In[..]:=G[n_] := Module[{i = 5, j = 3, s = 0}, Do[s += j, {i, 
>n}, {j, i}];
>Print[s]]
>
>In[..]:=G[100]
>Out[..]:=171700
>
>Can anyone give some more explanation to this problem, some 
>more information
>on how the function compile really works?
>
>
[...]


Who knows? 

Here is my speculation (following Matt Cook, Mathematica Conference
1992):

 
In[173]:=
g = Compile[{{n, _Integer}}, Module[{s = 0}, Do[Do[s += j, {j, i}], {i,
n}];
      s]]
Out[173]= CompiledFunction[{n}, 
  Module[{s = 0}, Do[Do[s += j, {j, i}], {i, n}]; s], "-CompiledCode-"]

In[174]:= g[[1]]
Out[174]= {_Integer}

A list of the types of the arguments.

In[175]:= g[[2]]
Out[175]= {{2, 0, 0}, {2, 0, 1}}

interface definition: input integer dim 0  to reg (0);  output integer
dim from reg (1) 

In[176]:= g[[3]]
Out[176]= {0, 7, 0, 0, 0}

number of registers in use {boolean, integer, real, complex, ??}

In[177]:= g[[4]]
Out[177]=
{{1, 4}, {4, 0, 1}, {9, 0, 2}, {4, 0, 3}, {81, 3, 2, 8}, {9, 3, 4}, {4,
0, 
    5}, {81, 5, 4, 4}, {24, 1, 5, 6}, {9, 6, 1}, {44, -3}, {44, -7},
{2}}

compiled instructions

In[178]:= g[[5]]
Out[178]=
Function[{n}, Module[{s = 0}, Do[Do[s += j, {j, i}], {i, n}]; s]]

Uncompiled code

In[182]:= g[3]
Out[182]= 10





Now here my speculation:

In[84]:= g[[4]] // ColumnForm

(the input is in reg 0)

begin #4
load const 0 into reg 1
move reg 0 to reg 2	        
load const 0 into reg 3	
if ++reg 3 > reg 2 then jump +8
move reg 3 to reg 4		
load const 0 into reg 5		
if ++reg 5 > reg 4 then jump +4	
add reg 1, regi 5 and store to reg 6 
move reg 6 to reg 1	
jump -3			
jump -7			
return 			

(returned is reg 1)


--
Hartmut Wolf


  • Prev by Date: Re: Determinant problem
  • Next by Date: Re: Setting the ResultFormat in a ASP.NET WebApplication.
  • Previous by thread: Re: Nested iterators in Compile
  • Next by thread: Re: Re: Nested iterators in Compile