Почему возведение в степень numpy .float64 возвращает nan? - PullRequest
1 голос
/ 05 февраля 2020

Когда я поднимаю отрицательное значение numpy.float64 до показателя степени, я получаю nan. Почему сложная математика не поддерживается? Является ли единственным обходным решением приведение к float?

>>> from numpy import float64, power
>>> r = float64(-12025.433836763057)
>>> p = 0.74
>>> r**p
nan
>>> power(r, p)
__main__:1: RuntimeWarning: invalid value encountered in power
nan
>>> float(r)**p
(-715.6124638577838+762.049873596874j)
>>> 

У предложенного дубликата есть похожий вопрос, ответ на который указывает, что это ошибка в numpy. Это конец дороги?

Ответы [ 2 ]

1 голос
/ 16 февраля 2020

За кулисами python использует этот float (r) ** p для возврата «сложного» типа.

Функция питания numpy предназначена для работы с numpy массивами-подобными структурами. где все элементы имеют одинаковый размер и хранятся в непрерывном блоке памяти, а его возвращаемый тип определяется из его аргументов.

Если вы ожидаете комплексные числа, лучшим подходом будет использование complex64 или complex128 типы. Они требуют больше памяти, потому что каждый сложный тип состоит из реального и мнимого компонента. Таким образом, complex64 будет состоять из двух чисел с плавающей точкой32, а complex128 будет состоять из двух чисел с плавающей точкой64.

>>> import numpy as np
>>> r = np.complex128(-12025.433836763057)
>>> p = 0.74
>>> np.power(r, p)
(-715.6124638577835+762.0498735968736j)

Вы также можете привести непосредственно к степенной функции:

>>> import numpy as np
>>> r = np.float64(-12025.433836763057)
>>> p = 0.74
>>> np.power(r.astype(np.complex128), p)
(-715.6124638577835+762.0498735968736j)

Но самый простой подход может просто изменить тип возвращаемого значения степенной функции для получения комплексного числа:

>>> import numpy as np
>>> r = np.float64(-12025.433836763057)
>>> p = 0.74
>>> np.power(r, p, dtype=np.complex128)
(-715.6124638577835+762.0498735968736j)

Интересно то, что numpy обычно допускает приведение типов с float64 к complex, если они остаются неизменными уровень точности. Однако, по-видимому, не допускается неявное приведение типов возвращаемых функций ufun c, даже если kwarg casting = 'same_kind' переопределен.

>>> np.can_cast(np.float64, complex)
True
>>> np.can_cast(np.float64, np.complex64)
False  
>>> np.can_cast(np.float64, np.complex128)
True

Согласно документам, если передаются скалярные аргументы для ufun c (в отличие от массивов) он использует logi c в np.result_type и np.promote_types для определения типа возврата ufun c.

https://docs.scipy.org/doc/numpy/reference/ufuncs.html

https://docs.scipy.org/doc/numpy/reference/generated/numpy.result_type.html#numpy .result_type

>>> np.result_type(r, p)
dtype('float64')
1 голос
/ 16 февраля 2020

numpy.float64, вероятно, представлен в виде структуры данных языка C, которая строго типизирована. python float - это pythoni c, поэтому он прекрасно сочетается с обработкой комплексных чисел, которую обеспечивает python.

См .: https://docs.scipy.org/doc/numpy/reference/c-api.dtype.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...