5

I want to generate an n-dimensional grid.

For a 3D grid, I have the following working code (which creates a grid of 5X5X5 between (-1,1 )

import numpy as np
subdivision = 5
step = 1.0/subdivision
grid= np.mgrid[ step-1 : 1.0-step: complex(0, subdivision),
                step-1 : 1.0-step: complex(0, subdivision),
                step-1 : 1.0-step: complex(0, subdivision)]

I want to generalize this to n dimensions so something like

grid = np.mgrid[step-1 : 1.0-step: complex(0,subdivision) for i in range(n)]

But this obviously doesnt work. I also tried

temp = [np.linspace(step-1 , 1.0-step, subdivision) for i in range(D)]
grid = np.mgrid[temp]

But this doesn't work either since np.mgrid accepts slices

5
  • What's the reason for using complex? With your 3D code I get 3x5x5x5. Is this intended? Commented Aug 9, 2017 at 6:48
  • @kazemakase From the documentation: "However, if the step length is a complex number (e.g. 5j), then the integer part of its magnitude is interpreted as specifying the number of points to create between the start and stop values, where the stop value is inclusive.". When a non-complex number is used, the stop value is exclusive. Commented Aug 9, 2017 at 6:59
  • 1
    @Evert Oh, thank you, I didn't know this. Seems like an obscure feature... Commented Aug 9, 2017 at 7:02
  • @kazemakase A keyword argument would be better, but that's not really an option here, so I guess someone came up with this option. Saves people from thinking to add half the step to the upper limit to make the normal case inclusive. Commented Aug 9, 2017 at 7:05
  • @Evert right, I guess that's the reason. Anyway, in this case it seems to make things worse as the OP had to explicitly adjust the upper limit. (Assuming it was intentional to make the lower and upper limit non-inclusive.) Commented Aug 9, 2017 at 7:09

3 Answers 3

5

Instead of using complex you can define the step size explicitly using real numbers. In my opinion this is more concise:

grid= np.mgrid[ step-1 : 1.0: step * 2,
                step-1 : 1.0: step * 2,
                step-1 : 1.0: step * 2]

Dissecting above snippet, we see that step-1 : 1.0: step * 2 defines a slice, and separating them by , creates a tuple of three slices, which is passed to np.mgrid.__getitem__.

We can generalize this to n dimensions by constructing a tuple of n slices:

n = 3
grid= np.mgrid[tuple(slice(step - 1, 1, step * 2) for _ in range(n))]
Sign up to request clarification or add additional context in comments.

Comments

2

As suggested by kazemakase, you should replace the "short hand" slicing notations step-1 : 1.0-step: complex(0,subdivision) with an explicit call to slice, and then combine it in a "tuple generator":

D = 6
grid = np.mgrid[tuple(slice(step-1, 1.0-step, complex(0,subdivision)) for i in range(D))]

Results with a 6D grid.

Comments

0

You can use meshgrid and linspace to do what you want.

import numpy as np
X1, X2, X3 = np.meshgrid(*[np.linspace(-1,1,5),
                           np.linspace(-1,1,5),
                           np.linspace(-1,1,5)])

For many dimensions, you can do

D = 4
subdivision = 5
temp = [np.linspace(-1.0 , 1.0, subdivision) for i in range(D)]
res_to_unpack = np.meshgrid(*temp)
assert(len(res_to_unpack)==D)

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.