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.arrays 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.