Hello everyone.
I’m trying to use generated functions to write functions that would return the sum of the values of the nearest neighbors of given site in a multidimensional integer periodic lattice.
For example: In a periodic 2D lattice, the sum of the values of the nearest neighbors of the site s would be
lattice[mod1(s[1] - 1, size(lattice, 1)), s[2]] + lattice[mod1(s[1] + 1, size(lattice, 1)), s[2]] + lattice[s[1], mod1(s[2] - 1, size(lattice, 2))] + lattice[s[1], mod1(s[2] + 1, size(lattice, 2))]
My attempt
Reading through the examples provided in the Manual, I came up with the following:
# Sum of nearest neighbors of site $s$ in a periodic integer lattice
function square_lattice_nn_sum_impl(lattice::Type{Array{Int,dims}}, s::Type{NTuple{dims,Int}}) where dims
# Accumulate final expression
ex = :()
# Loop on the dimensions
for d in 1:dims
# Indices for both nearest neighbors in the current dimension
idx_prev_nn = :(mod1(s[$d] - 1, size(lattice, $d)))
idx_next_nn = :(mod1(s[$d] + 1, size(lattice, $d)))
# Fill indices before the current dimension
idx_before = :()
for k in d-1:-1:1
idx_before = :(s[$k], $idx_before)
end
# Fill indices after the current dimension
idx_after = :()
for k in d+1:dims
idx_after = :($idx_after, s[$k])
end
# Accumulate sum
ex = :($ex + lattice[$idx_before $idx_prev_nn $idx_after] + lattice[$idx_before $idx_next_nn $idx_after])
end
return :($ex)
end
# Extract generated function to the body of a regular function
@generated function square_lattice_nn_sum(lattice::Array{Int,dims}, s::NTuple{dims,Int}) where dims
square_lattice_nn_sum_impl(lattice, s)
end
For the 2D case, my program returns the following expression:
julia> square_lattice_nn_sum_impl(Array{Int,2}, NTuple{2,Int})
:((() + lattice[() mod1(s[1] - 1, size(lattice, 1)) ((), s[2])] + lattice[() mod1(s[1] + 1, size(lattice, 1)) ((), s[2])]) + lattice[(s[1], ()) mod1(s[2] - 1, size(lattice, 2)) ()] + lattice[(s[1], ()) mod1(s[2] + 1, size(lattice, 2)) ()])
Which would be the desired result if it wasn’t for the several misplaced parentheses.
My questions
Is it possible to accumulate quoted expression without parentheses around them?
Is there a better way of achieving this?
Are generated functions even the right tool for this job?
Thanks.