A negative numpy.float64
exponentiated with a fractional (i.e., decimal, i.e., rational) number will yield a nan
result and a warning.
The same number using Python's float
type returns a complex
result.
Here is a minimal example using Python 3.6.6 (for a comment on Python 2.7.15, see below):
>>> import numpy as np
>>> f = -2.0
>>> npf = np.float64(-2.0)
>>> f**1.1
(-2.0386342710747223-0.6623924280875919j)
>>> npf ** 1.1
__main__:1: RuntimeWarning: invalid value encountered in double_scalars
nan
I tried the numpy.power
function getting a different warning and the same result.
>>> np.power(f, 1.1)
__main__:1: RuntimeWarning: invalid value encountered in power
nan
>>> np.power(npf, 1.1)
nan
The warning in the latter appears only after whatever is executed first.
I ran into this using numpy.array
s of floats, which in all other cases(?) just behave the same as Python floats. The conversion from float
to numpy.float64
happens implicitly so it took me a while to find the source of the problem.
Now, I can get around this by explicitly converting to or specifying the dtype
when creating the array as numpy.complex
:
>>> npc = np.complex(-2.0)
>>> npc ** 1.1
(-2.0386342710747223-0.6623924280875919j)
>>> np.power(npc, 1.1)
(-2.0386342710747223-0.66239242808759191j)
(note the different precision of the output O_o, I can live with that, though)
My question is: Why?? Why doesn't numpy return a numpy.complex
when necessary. It does convert to numpy.float64
when, e.g., dividing a numpy.int64
:
>>> ai = np.array([1])
>>> ai.dtype
dtype('int64')
>>> ai/2
array([ 0.5])
>>> (ai/2).dtype
dtype('float64')
Why not apply the same philosophy when numpy.float64
is not capable of expressing the result of a calculation and use numpy.complex64
instead?
comment on Python 2.7.15: with this version, exponentiating a float
with a fractional number throws an exception, explicitly using complex
solves the problem:
>>> f ** 1.1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: negative number cannot be raised to a fractional power
>>> complex(-2.0) ** 1.1
(-2.0386342710747223-0.6623924280875919j)
This is equivalent to the behaviour of numpy.