3

When given a matrix of n-dimension and a grid size of 1 I'd like to calculate the nearest neighbours of a field. Given below is an example for a 2-dimensional field

P = (1,1)

p_neighbours = [(0,0),(2,2),(0,1),(0,2),(1,0),(2,0),(2,1),(1,2)]

Mathematically this can be as easily described as P +/- 1 in a vectorian system (as far as I understand). The size of the n-dimensional neighbour array is described as (n^3)-1 I've already found a pretty good old topic, anyhow I couldn't understand how any of the presented solutions could be extended to a n-dimensional function..

Community
  • 1
  • 1
Fohlen
  • 192
  • 2
  • 18

4 Answers4

7
from itertools import product

def stencil(dim):
    stencils = list(product([-1,0,1], repeat=dim))
    zero = ((0,) * dim)
    stencils.remove(zero)
    return stencils

def neighbours(P):
    stencils = stencil(len(P))
    return [tuple([sum(x) for x in zip(P,s)]) for s in stencils]

P = (4, 4, 4)

print(neighbours(P))
hvwaldow
  • 1,296
  • 1
  • 11
  • 13
  • wuh. this is amazing. works for me, gotta study that in detail! – Fohlen Oct 27 '16 at 20:02
  • stencil just produces a list of the dim-dimensional cartesian product of [-1,0,1]: The relative positions of the neighbours. This includes the dim - dimensional zero, e.g. (0,0,0) which is then removed. neighbours just adds each of those "shift vectors" to P and it is the second line in that function that I find confusing. I guess using numpy is a good idea if you do things like that more frequently. – hvwaldow Oct 27 '16 at 20:24
1

To be correctly, the size of the n-dimensional neighbour array isn't (n^3)-1, it is (3^n)-1 (if n > 3 the array-size is way larger!) To generate neighbours in any dimension, you have to implement a recursive algorithm, that iterates over the dimension and calls itself (I don't know exactly how to implement this, but I'm working on it)

Aemyl
  • 1,501
  • 1
  • 19
  • 34
0

I guess should be something like this

p_neighbours = []
for x in [-1,0,1]:
  for y in [-1,0,1]:
    p_neighbours.append((P(0)+x,P(1)+y))
0

I think the clearest way to go here is to use a simple list comprehension:

p = (1,1)
px, py = p
p_neighbours = [(px+x,py+y) for x in range(-1,2) for y in range(-1,2) if (x,y) != (0,0)]

Here we check that (x,y) is not (0,0) to avoid adding p itself to its neighbors.

Daniel
  • 11,332
  • 9
  • 44
  • 72
  • 1
    Apparently you didn't read the question properly .. I know very well how to do that for a 2-dimensional array. The interesting part was the n-dimensional recursion that's talked about below. – Fohlen Oct 27 '16 at 19:33