getting random sampling from cartesian product

41 views Asked by At

Consider the complex number z = x+iy. I have an object constructor class that can take a complex number and plot something from it, say pole(x,y).

I want to construct an array that considers all the possible combinations of x and y so that I can plot a square grid. Suppose that x and y are

a = [0,1,2]
b = [0,1,2]

then my array of interest is c = np.asarray(list(it.product(a,b)))

Using another complex number w = u+iv, I can also plot the following point by point: pole(x,y)*pole(u,v). I want to construct an array that considers all the possible combinations of z and w, and for this my attempt is

d = c.copy()
e = np.asarray(list(it.product(c,d)))

Up until this point, the code is working as intended especially if I consider an initial array a,b with only five elements. However, in the original problem, I need to consider an initial array a,b with at least 1000 elements. Worst, I need to consider pole(x,y)*pole(u,v)*pole(...)*pole(...) which means I get to have an array with (1000*1000)^4 elements.

What do you suggest I do to create an array that stores all the possible combinations of 2 parameters, 2x2 parameters, 2x2x2 parameters and so on?

I tried using np.meshgrid thinking it is more efficient than it.product but I am at lost after the first instance of

x,y = np.transpoe(np.meshgrid(a,b)).reshape(-1,2)

If I want to consider the next complex number w, I am not sure how to implement meshgrid.

I am also thinking of instead listing all the possible combinations of (x,y), (x,y) and (u,v), and so on, I could randomly pick from their combinations without constructing a huge list to conserve memory. However, I am not sure how to redefine this (documentation

def random_product(*args, **kwds):
    "Random selection from itertools.product(*args, **kwds)"
    pools = map(tuple, args) * kwds.get('repeat', 1)
    return tuple(random.choice(pool) for pool in pools)

to accommodate what I want.

1

There are 1 answers

0
MegaIng On

(1000*1000)^4 bytes is 1 yottabyte, so constructing an array is not an option, your PC does not have enough memory.

The function you have needs to be fixed for python3 compatibility and slightly adjusted for your usecase:

def random_product(*args, **kwds):
    "Random selection from itertools.product(*args, **kwds)"
    pools = list(args) * kwds.get('repeat', 1)
    return tuple(random.choice(pool) for pool in pools)

You can then use it like this:

x,y, u,v, s,t = random_product(a, b, c, d, e, f)

Where a-f are the lists or 1-D numpy arrays defining the possibly coordinates in each dimension you care about.

The results can now be joined into complex numbers: x + y*1j, u + v*1j, s + t*1j

If you never want to use the repeat keyword (so using the same values for c,d as for a,b is not an option), it would be a bit better to not have the second line of the function at all and just use args instead of pools in the return statement.