Number of loops not known at compile time

166 views
Skip to first unread message

Giuseppe Ragusa

unread,
Sep 28, 2015, 11:24:40 AM9/28/15
to julia-users
I am having problems (serious problems!) to deal with algorithms that boil down do nested for loops but whose number of loops is not known at compile time. As an example consider this:

```
 function tmp()
     r = 3
     n = 100
     λ = zeros(r)
     u = rand(n, r)
     counter = 0
     Y = Array(Float64, n)

     @inbounds for j_1 = 0:k
         
         for i = 1:n
             Y[i] = pow(u[i, 1], j_1)
         end
         
         λ[1] = j_1
         for j_2 = 0:(k-j_1)
             λ[2] = j_2
             for i = 1:n
                 Y[i] *= pow(u[i, 2], j_2)
             end
             
             for j_3 = 0:(k-j_1-j_2)
                 λ[3] = j_3
                 for i = 1:n
                     Y[i] *= pow(u[i, 3], j_3)
                 end
                 counter += 1
                 println(λ, " ", " => ", j_1, j_2, j_3, " counter =>", counter)
             end
         end
     end
 end
 ```

This is what I want when `r = 3`. For larger `r = 4` there would be an additional loop. etc. Now, everything is complicated by the fact that `r` is not know at compile time. 

I have tried to generate the loops using the macros in  Base.Cartesian and then using generated functions to accomplish what I want, but I cannot get what I want. The main difficulty is that Base.Cartesian I can't get the ranges I want). 

Does anybody have suggestions on how to deal with this?


Steven G. Johnson

unread,
Sep 28, 2015, 12:42:18 PM9/28/15
to julia-users


On Monday, September 28, 2015 at 11:24:40 AM UTC-4, Giuseppe Ragusa wrote:
I am having problems (serious problems!) to deal with algorithms that boil down do nested for loops but whose number of loops is not known at compile time. As an example consider this:

In this sort of algorithm, I usually employ recursion (on the dimension being looped over), where the base case is 1 or 2 nested loops (big enough to amortize the recursion overhead). 

Erik Schnetter

unread,
Sep 28, 2015, 2:23:48 PM9/28/15
to julia...@googlegroups.com
Guiseppe

In addition to using recursion, you can also use a macro to generate the code.

However, this functionality is available in the "Cartesian" module which is part of Base Julia. You are probably looking for "@nloops".

-erik

Giuseppe Ragusa

unread,
Sep 28, 2015, 2:33:46 PM9/28/15
to julia-users
@erik thank you. I know of Base.Cartesian, but I was not able to make it work for my use case. 

@steven yes, that is what i was afraid of (I was trying to shy away from recursion). 

Tim Holy

unread,
Sep 28, 2015, 3:26:35 PM9/28/15
to julia...@googlegroups.com
If I were doing this, I'd make u a Vector of NTuples, pass it in as an
argument, and use N in @generating the body of the function. You can use
Cartesian macros in the body of a generated function (many examples in base).

--Tim

jonatha...@alumni.epfl.ch

unread,
Sep 28, 2015, 4:39:45 PM9/28/15
to julia-users
If I understand correctly, the trick is to encode the dimension into the type of the arguments (using parametric types), then the @generated macro allows you to "write" a function just when the type of the arguments is known,
so you can create the right numbers of loops on the fly.


Maybe this is a good example:

Reply all
Reply to author
Forward
0 new messages