Finding hyperrectangle vertex coordinates
Tiny post Python NumPy N-dimensional
For the past two years I have been working on a python library for tiling and merging of n-dimensional numpy arrays, tiler. From the first release it had a method to return bounding boxes of resulting tiles but it returned only minimum (i.e., bottom-left) and maximum (i.e., top-right) corners. Recently I needed to find all vertices of such bounding box, based on two original opposite vertices returned by
The solutions that come to mind first are to calculate coordinates with multiple nested for loops. While this part is not very performance critical, I was still interested in trying to rewrite that in numpy to avoid for loops. I found an algorithm on stackoverflow that involved iterating through 2^n numbers and then iterating through each bit of that number in binary. Pretty cool approach, but implementing this straight in Python seemed a nuissance: converting an integer to binary produces a string (i.e.,
bin(9) => '0b1001'), then iterating through that string and checking with and if-else whether it is 0 or 1 and then sampling correct coordinate...
I didn't see any other implementation of this on the internet, so here I am, sharing my Sunday night solution, with just one list comprehension. Essentially it creates an array of combinations of bits up to 2^n and then use it for indexing from interval array.
Probably it can be optimized even further 🤔
def get_all_corners(bottom_left_corner, top_right_corner): n_dim = len(bottom_left_corner) mins = np.minimum(bottom_left_corner, top_right_corner) maxs = np.maximum(bottom_left_corner, top_right_corner) intervals = np.stack([mins, maxs], -1) indexing_bits = np.array(list(itertools.product([0, 1], repeat=n_dim))) corners = np.stack([intervals[x][indexing_bits.T[x]] for x in range(n_dim)], -1) return corners