[Numpy-discussion] return value of negative power

Tim Hochberg tim.hochberg at ieee.org
Thu Sep 28 12:08:01 CDT 2006


Stefan van der Walt wrote:
> Hi all,
>
> Currently, the power function returns '0' for negative powers of
> integers:
>
> In [1]: N.power(3,-2)
> Out[1]: 0
>
> (or, more confusingly)
>
> In [1]: N.power(a,b)
> Out[1]: 0
>
> which is almost certainly not the answer you want.  Two possible
> solutions may be to upcast the input to float before calculation, or
> to return nan.
>   
Returning nan seems silly. There really is a result, or rather two 
possible results on a tad more sensible than the other. If we were going 
to punt it makes more sense to raise an exception, but I doubt that's 
necessary. In addition, nan is really a floating point value; if we're 
going to return a floating point value, not an integer, we might as well 
return the actual result.

> This would be consistent with a function like sqrt:
>
> In [10]: N.sqrt(3)
> Out[10]: 1.7320508075688772
>
> In [11]: N.sqrt(-3)
> Out[11]: nan
>
> Does anyone have an opinion on whether the change is necessary, and if
> so, on which one would work best?
>   
This is a complicated tangle of worms. First off there's both "a**b" and 
"power(a, b)". These don't necessarily need to work the same. In fact 
they already differ somewhat in that a**b does some optimization when b 
is a small scalar that power does not (I think anyway -- haven't looked 
at this a while). However, if having them differ in any significant way 
is likely to be quite confusing, so it should be only be considered if 
there's some compelling reason to support multiple behaviors here.

There is a solution that is, IMO, simple obvious and not quite right. 
That is to return floats if the b contains any negative numbers while 
returning integers otherwise. That sounds appealing at first, but will 
cause confusion and memory blow ups when one suddenly has all of ones 
arrays become floats because somewhere or other a negative value crept 
into an exponent. It's fine for the return type to depend on the types 
of the arguments, it's not so good for it to depends on the values. This 
restriction gets a little weaker once future division arrives since ints 
and floats will be closer to indistinguishable, but it still has some 
force. On the other hand, this is consistent with the rest of Python's 
behavior.

Another path is to just always return floats from power. One down side 
of this is that we lose the ability to do true integer powers, which is 
sometimes useful. A second downside is that it introduces a 
inconsistency with Python's scalar 'x**y'.  One way to finesse both of 
these issues is to make numpy.power consistent with math.pow; that is, 
it returns floating point values when passed integers. At the same time, 
make a**b consistent with the python's '**' operator in that any 
negative exponents trigger a floating point return values. This isn't 
perfect, but it's as close to a self consistent solution as I can think of.

That's my two cents.

-tim








More information about the Numpy-discussion mailing list