Suppose we have a hollow square lamina of size n. That is, we have a nxn square from which a k*l rectangle has been removed (1<=k,l<=n-2). I want to calculate an average of distances between 2 random, uniformly distributed points within such hollow square lamina. For the sake of simplicity let's consider n=3, k=l=1, or a 3x3 square from whose center a unit square has been removed
I wrote this code for numpy, but it has at least 2 problems: I have to throw away approximately 1/9 of all generated points and removing the numpy.array elements requires lots of RAM:
x,y = 3*np.random.random((2,size,2))
x = x[
np.logical_not(np.logical_and(
np.logical_and(x[:,0] > 1, x[:,0] < 2),
np.logical_and(x[:,1] > 1, x[:,1] < 2)
))
]
y = y[
np.logical_not(np.logical_and(
np.logical_and(y[:,0] > 1, y[:,0] < 2),
np.logical_and(y[:,1] > 1, y[:,1] < 2)
))
]
n = min(x.shape[0], y.shape[0])
UPD:Here size
is the sample size of which I'm going to calculate average.
Is there an elegant way to generate those points right away, without removing the unfit ones?
UPD: Here is the full code just for the reference:
def calc_avg_dist(size):
x,y = 3*np.random.random((2,size,2))
x = x[
np.logical_not(np.logical_and(
np.logical_and(x[:,0] > 1, x[:,0] < 2),
np.logical_and(x[:,1] > 1, x[:,1] < 2)
))
]
y = y[
np.logical_not(np.logical_and(
np.logical_and(y[:,0] > 1, y[:,0] < 2),
np.logical_and(y[:,1] > 1, y[:,1] < 2)
))
]
n = min(x.shape[0], y.shape[0])
diffs = x[:n,:] - y[:n,:]
return np.sum(np.sqrt(np.einsum('ij,ij->i',diffs,diffs)))/n