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