What does a complete complex number in NumPy's mgrid do?

I am trying to figure out how NumPy's mgrid function works and I read that the syntax creating a simple array works like this:

Arguments are separated by :. First number gives the start, second number the stop.

If you give a real number e.g. 1 as third argument you fix the step-size (stop excluded)

np.mgrid[-5:5:1]
[-5 -4 -3 -2 -1 0 1 2 3 4]

If you give an imaginary third argument you give the number of elements as the coefficient. This time stop included. E.g. 5j gives

np.mgrid[-5:5:5j]
[-5. -2.5 0. 2.5 5. ]

Straightforward enough. I come from a mathematics background and got to know complex numbers with a real and an imaginary part.

z in C --> z = x + iy

with real valued x and y. So I wondered what would happen if one used a complex number that has both a real and an imaginary part and I got this result

np.mgrid[-5:5:1+5j]
[-5. -2.56039219 -0.12078439 2.31882342 4.75843122]

Can someone explain what just happened internally?

2

2 Answers

First, it's easy to understand that

np.mgrid[-5:5:5j]
[-5. -2.56039219 -0.12078439 2.31882342 4.75843122]

means that 5 numbers between -5 and 5 with an equivalent step size.

5j can be understood as 0 + 5j. The total numbers between -5 and 5 are determined by the length of the complex number instead of the imaginary part.

In np.mgrid, we can see the internal code that it uses:

step= abs(Re+Imj)
length = int(step_size)
if step != 1: step = (Interval)/float(step-1)

Apparently, the real part of the complex number increases the number and changes the step size.

For example:

[-5:5:4+5j]
6 = int(abs(4+5j))
array([-5. , -3.14921894, -1.29843788, 0.55234318, 2.40312424, 4.2539053 ])

The number would be 6. And we can compute the step_size by

step = (key.stop-start)/float(step-1)

where key.stop is -5, start equals 5. The final step equals to

[in]: 10/(abs(4+5j) -1)
[out]: 1.8507810593582121

It also shows that np.mgrid[-5:5:4+5j] equals np.mgrid[-5:5:5+4j]

However, the question is how to use it? I don't know, but I think it should be understood from

np.mgrid[Re1+Xj : Re2 +Yj: Re3+ Zj]

mgrid uses np.lib.index_tricks.ndgrid class. The use of the complex step is complicated. I remember at one time it use np.linspace, taking the integer part of the 5j as the number of samples. Now I don't see use of linspace. It's either arange or some home-grown equivalent, which is presumably faster when making a multidimensional grid.

But I've been able to replicate the numbers with:

In [247]: step = 5j
In [248]: np.mgrid[0:5:5j]
Out[248]: array([0. , 1.25, 2.5 , 3.75, 5. ])
In [249]: x = 5/(float(np.abs(step))-1)
In [250]: np.arange(0,5+x,x)
Out[250]: array([0. , 1.25, 2.5 , 3.75, 5. ])

and for:

In [251]: step = 1+5j
In [252]: x = 5/(float(np.abs(step))-1)
In [253]: x
Out[253]: 1.219803902718557
In [254]: np.mgrid[0:5:step]
Out[254]: array([0. , 1.2198039 , 2.43960781, 3.65941171, 4.87921561])
In [255]: np.arange(0,5+x,x)
Out[255]:
array([0. , 1.2198039 , 2.43960781, 3.65941171, 4.87921561, 6.09901951])
In [256]: np.arange(0,5,x)
Out[256]: array([0. , 1.2198039 , 2.43960781, 3.65941171, 4.87921561])

This isn't an exact duplicate, but the numbers match well enough to identify the step size that it's using.

In any case using a full complex number is not documented. It works, but the result is not easily understood.

Your Answer

Sign up or log in

Sign up using Google Sign up using Facebook Sign up using Email and Password

Post as a guest

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

You Might Also Like