Reputation: 657
What could be an efficient way of creating numpy array containing the coordinates of vertices of the N-dimensional cube centered at origin of coordinates, given the dimension N
.
For example, for N=1
it should return np.array([[1],[-1]])
For N=2
it should return np.array([[1,1],[1,-1],[-1,1],[-1,-1]])
For N=3
: np.array([[1,1,1],[1,1,-1],[1,-1,1],[1,-1,-1],[-1,1,1],[-1,1,-1],[-1,-1,1],[-1,-1,-1]])
Upvotes: 3
Views: 2583
Reputation: 114976
Here's another method: 2*((np.arange(2**N)[:,None] & (1 << np.arange(N))) > 0) - 1
In [25]: N = 1
In [26]: 2*((np.arange(2**N)[:,None] & (1 << np.arange(N))) > 0) - 1
Out[26]:
array([[-1],
[ 1]])
In [27]: N = 2
In [28]: 2*((np.arange(2**N)[:,None] & (1 << np.arange(N))) > 0) - 1
Out[28]:
array([[-1, -1],
[ 1, -1],
[-1, 1],
[ 1, 1]])
In [29]: N = 3
In [30]: 2*((np.arange(2**N)[:,None] & (1 << np.arange(N))) > 0) - 1
Out[30]:
array([[-1, -1, -1],
[ 1, -1, -1],
[-1, 1, -1],
[ 1, 1, -1],
[-1, -1, 1],
[ 1, -1, 1],
[-1, 1, 1],
[ 1, 1, 1]])
What it does:
Numpy broadcasting is used to vectorize the operations.
Upvotes: 2
Reputation: 2726
Here is a pure numpy implementation involving meshgrid and stack. It's a little contrived-- would welcome input to make it better.
pts = np.stack(([-1,1],)*N,0)
vertices = (np.array(np.meshgrid(*pts)).T).reshape(2**N,N)
vertices
N=3
returns
array([[-1, -1, -1],
[-1, 1, -1],
[ 1, -1, -1],
[ 1, 1, -1],
[-1, -1, 1],
[-1, 1, 1],
[ 1, -1, 1],
[ 1, 1, 1]])
N=1
returns
array([[-1],
[ 1]])
Upvotes: 2
Reputation: 6700
You can use product
from itertools
from itertools import product
def vertices(N):
return list(product((1, -1), repeat=N))
print(vertices(1))
# [(1,), (-1,)]
print(vertices(2))
# [(1, 1), (1, -1), (-1, 1), (-1, -1)]
print(vertices(3))
# [(1, 1, 1), (1, 1, -1), (1, -1, 1), (1, -1, -1), (-1, 1, 1), (-1, 1, -1), (-1, -1, 1), (-1, -1, -1)]
Upvotes: 5