[Numpy-discussion] Behaviour of integer powers

josef.pktd@gmai... josef.pktd@gmai...
Sun Feb 8 07:02:10 CST 2009


On Sun, Feb 8, 2009 at 5:09 AM, Robert Kern <robert.kern@gmail.com> wrote:
> On Sun, Feb 8, 2009 at 03:54, Stéfan van der Walt <stefan@sun.ac.za> wrote:
>> Hi all,
>>
>> Ticket #955 (http://scipy.org/scipy/numpy/ticket/955) touches on the
>> following issue:
>>
>>>>> 0.0 ** np.array([-1, 0, 1], dtype=np.int32)
>> array([ Inf,   1.,   0.])
>>>>> 0.0 ** np.array([-1, 0, 1], dtype=np.int32)[0]
>> ------------------------------------------------------------
>> Traceback (most recent call last):
>>  File "<ipython console>", line 1, in <module>
>> ZeroDivisionError: 0.0 cannot be raised to a negative power
>>
>> This is on a 32-bit platform.
>>
>> As I understand this happens because, in the second case, Python sees
>> that "-1" is an int and does the power operation.  In other words,
>> when we raise to the power of an array, the NumPy machinery is
>> involved, whereas if we raise to np.int32(-1), it is not.  This is due
>> to the int32 type deriving from the Python int.
>>
>> I can't think of an easy way to address the problem, but I was hoping
>> to get some advice from the list.
>
> I don't think there is anything we can do to fix this except not to
> subclass from int. I think float.__pow__(self, other) checks that
> isinstance(other, int) and does its own thing. numpy.int_.__rpow__
> will never get called, and that's the only place we can implement our
> logic.
>
> We can document the wart and recommend casting the base to a float64
> scalar first.
>
> --
> Robert Kern
>

I thought when in doubt about the domain, the useful way around this, is to call
np.power directly. This is how it is used in stats.distributions.

>>> 0.0 ** np.array([-1, 0, 1], dtype=np.int32)[0]
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
ZeroDivisionError: 0.0 cannot be raised to a negative power
>>> np.power(0.0, np.array([-1, 0, 1], dtype=np.int32)[0])
1.#INF
>>> 0.01 ** np.array([-1, 0, 1], dtype=np.int32)[0]
100.0
>>> np.power(np.nan, np.array([-1, 0, 1], dtype=np.int32)[0])
-1.#IND
>>> np.nan ** np.array([-1, 0, 1], dtype=np.int32)[0]
Traceback (most recent call last):
  File "<interactive input>", line 1, in <module>
ValueError: (33, 'Domain error')


But I just found that nan in the exponent in an array are not propagated:

>>> 0.0 ** np.array([-np.nan, 0, 1], dtype=np.int32)[0]
1.0
>>> np.power(0.0, np.array([-np.nan, 0, 1], dtype=np.int32)[0])
1.0
>>> np.power(0.0, -np.nan)
1.#QNAN
>>> np.power(0.0, np.nan)
-1.#IND

>>> 0.0**np.nan
0.0


More information about the Numpy-discussion mailing list