return value of negative power
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. 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? Regards Stéfan
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
participants (2)
-
Stefan van der Walt
-
Tim Hochberg