Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Julia - n-nested loops

Im trying to make a n-nested loop method in Julia

function fun(n::Int64)
    @nloops n i d->1:3 begin\n
        @nexprs n j->(print(i_j))\n
    end
end

But the @nloops definition is limited to

_nloops(::Int64, ::Symbol, ::Expr, ::Expr...)

and I get the error

_nloops(::Symbol, ::Symbol, ::Expr, ::Expr)

Is there any way to make this work? Any help greatly appreciated

EDIT:

What I ended up doing was using the combinations method

For my problem, I needed to get all k-combinations of indices to pull values from an array, so the loops would had to look like

for i_1 in 1:100
    for i_2 in i_1:100
        ...
           for i_k in i_[k-1]:100
like image 580
isebarn Avatar asked Jun 16 '16 13:06

isebarn


2 Answers

The number of loops needs to be a compile-time constant – a numeric literal, in fact: the code generated for the function body cannot depend on a function argument. Julia's generated functions won't help either since n is just a plain value and not part of the type of any argument. Your best bet for having the number of nested loops depend on a runtime value like n is to use recursion.

like image 104
StefanKarpinski Avatar answered Nov 18 '22 07:11

StefanKarpinski


In julia-0.4 and above, you can now do this:

function fun(n::Int)
    for I in CartesianRange(ntuple(d->1:3, n))
        @show I
    end
end

In most cases you don't need the Base.Cartesian macros anymore (although there are still some exceptions). It's worth noting that, just as described in StefanKarpinski's answer, this loop will not be "type stable" because n is not a compile-time constant; if performance matters, you can use the "function barrier technique." See http://julialang.org/blog/2016/02/iteration for more information about all topics related to these matters.

like image 4
tholy Avatar answered Nov 18 '22 08:11

tholy