range builder `r_` - slice with complex (but not i

2019-01-28 19:04发布

Playing with the NumPy concatenation and range building object r_ I stumbled over the following behavior: apparently, a complex step no matter whether real, imaginary or proper complex has its absolute value taken as the number of steps in a linspace like way.

>>> import numpy as np
>>> 
>>> np.r_[0:12:4]           # start : stop : step
array([0, 4, 8])            # that's expected
>>> np.r_[0:12:4j]          # start : stop : imaginary step
array([ 0.,  4.,  8., 12.]) # that's in the docs
>>> np.r_[0:12:4+0j]        # real step of complex type ?
array([ 0.,  4.,  8., 12.]) # this is not as far as I can tell
# you can even do stuff like
>>> np.r_[0:12:-4+3j]        # proper complex step ?
array([ 0.,  3.,  6.,  9., 12.])

Question: I just wanted to know whether that's an official feature, because I couldn't find it documented.

Why is it relevant? Well, r_ primarily being a keystroke saving convenience there are a few cases where this feature could save you a few characters.

1条回答
等我变得足够好
2楼-- · 2019-01-28 19:33

The code does take the absolute value:

if isinstance(step, complex):
    size.append(int(abs(step)))

but this is not a documented guarantee. The docs only guarantee behavior for imaginary numbers, not arbitrary complex numbers:

if step is an imaginary number (i.e. 100j) then its integer portion is interpreted as a number-of-points desired and the start and stop are inclusive

You should not rely on the behavior for not-purely-imaginary complex inputs, as it is not a documented guarantee.

That said, it is possible that it was intended to be a guarantee. The furthest back I've been able to trace numpy.r_'s code is this commit. (That's not where it originated - I can find references to scipy.r_ dating back even further - but despite finding references to scipy.r_, I have not been able to locate the code for scipy.r_, and I suspect neither the SciPy nor NumPy GitHub repositories contain the original code. It seems like this would be the right commit, except that GitHub seems to only have a fragment of the original non-Git commit.)

r_ was not documented in the earliest commit I can trace it to, but mgrid was also present in that commit, and mgrid's similar behavior for complex numbers was documented in that commit as

However, if the step length is a COMPLEX NUMBER (e.g. 5j), then the integer
part of it's magnitude is interpreted as specifying the number of points to
create between the start and stop values, where the stop value
IS INCLUSIVE.

The furthest I've been able to trace numpy.r_'s documentation is this commit 7 years later, labelled "Merge from doc wiki". I believe the doc wiki is now gone, and I have been unable to determine who originally contributed those docs, but it seems likely that those docs were not based on the original intent of numpy.r_'s author.

查看更多
登录 后发表回答