# Discretizing an n-dimensional line

I have a line residing in some n-dimensional space, that needs to be discretized into a set of points. Given the start, end points, and some the number of points r that are needed, I can accomplish this as follows:

import numpy as np

start, end = (0, 0, 0), (10, 10, 10)
r = 3
dl = zip(*[np.linspace(s_i, e_i, r) for s_i, e_i in zip(start, end)])


This seems to work well enough, but I'd rather the entire thing work as a generator, and right now now the linspace has to be computed for the whole thing. How could I accomplish this?

NumPy works best if you represent all your data as uniform arrays. Then you can vectorize your operations: that is, arrange for each operation to run uniformly on all the elements of an array. This allows NumPy to delegate the operations to fast branchless native code.

Assuming these considerations applies to your case, then what you need here is to convert your input to NumPy arrays:

>>> start = np.array((0, 0, 0))
>>> end = np.array((10, 10, 10))
>>> r = 3


and then construct an array of points along the line:

>>> start + np.linspace(0, 1, r)[..., np.newaxis] * (end - start)
array([[ 0.,  0.,  0.],
[ 5.,  5.,  5.],
[10., 10., 10.]])


This is the type of thing that should be in a function for easy reuse. Also, as Gareth pointed out, it makes sense to return a result as a 2d array instead of a iterable of 1d arrays, as it will likely be faster. Also, we might as well make sure that the start and end points have the same number of dimensions to prevent weird bugs from popping up.

import numpy as np
def discretize(start, end, length):
assert len(start)==len(end)
ans = np.empty((len(start),length))
for row, s_i, e_i in zip(range(len(start)),start, end):
ans[row]=np.linspace(s_i, e_i, length)
return ans