# Nested loops

Hi,

I need a program where I’m computing a 2D NxN lattice, and for that I need N^2 nested loops, for N=2 would be:

``````for S[1,1] in [-1,1], S[1,2] in [-1,1], S[2,1] in [-1,1], S[2,2] in [-1,1]
...
end
``````

But I need to compute N in the range 2:5, and doing like that I would need 1 code for each N. Is there a way to optimize that, so I can use just one program?

I tried something like that:

``````for i in 1:N, j in 1:N, S[i,j] in [-1,1]
...
end
``````

but didn’t work as I wanted.

Thanks for the help.

Edit: It was N^2 not N^N

I am not entirely sure what you want. The loop you describe does what it is expected to do, for each position `(i, j)` it first set `S[i, j]` value to `-1` and execute the body, then it sets `S[i, j]` to `1` and execute the body.

Do you want to run the body for every possible matrix of values `1` and `-1`? If so, I would recommend looking at `Combinatorics.jl`.

2 Likes

Yep, I want to run on all the 2^(N*N) possibilities, so I would need N^2 nested loops with [-1,1].

I’ll take a look, thanks for the recommendation.

Edit: N^2 not N^N

If I’m getting this right, it sounds like you want all `NxN` matrices `S` for which `Sᵢⱼ ∈ {-1, 1}`. You can create these in a loop over `i in 2^(N*N)` using the binary representation of `i` to set the values of `S`.

``````S′ = ones(Int, N, N)
digs = zeros(Bool, N*N) # a vector to hold the bit representation of `i`.
for i in 1:2^(N*N)
digits!(digs, i-1, base=2)
S = S′ .- 2reshape(digs, size(S′))
# use S
end
``````

Above I use two different matrices for the process, but that’s not important. You can just as easily do the whole thing in-place if you preferred. Note that it’s easy for `2^(N*N)` to overflow (you literally can’t go past `N=7`…). You can use `big(2)^(N*N)` to get around that, but at that point the problem would be intractable anyway.

2 Likes

Turns out you can also use `multiset_permutations` from `Combinatorics`. The input set needs N² `1` values and the same number of `-1` values. Choosing any N² subset of these (in every permutation) will give the same as the above solution.

``````for perm in multiset_permutations([ones(Int, N^2); -ones(Int, N^2)], N^2)
S = reshape(perm, N, N)
end``````
2 Likes

In addition to the combinatorics solutions suggested above, I also want to point out the Cartesian indices facilities in Base and the lower-level `@nloops` macro. These allow you to effectively have `N` efficient nested loops in such a way that the code is generic over `N`.

4 Likes