Подтвердить что ты не робот

Какую дополнительную работу выполняет np.power?

Я понял, что np.power(a, b) медленнее, чем np.exp(b * np.log(a)):

import numpy as np
a, b = np.random.random((2, 100000))
%timeit np.power(a, b) # best of 3: 4.16 ms per loop
%timeit np.exp(b * np.log(a)) # best of 3: 1.74 ms per loop

Результаты те же (с несколькими численными ошибками порядка 1е-16).

Какая дополнительная работа выполняется в np.power? Кроме того, как я могу найти ответ на эти вопросы самостоятельно?

4b9b3361

Ответ 1

Под капотом оба выражения вызывают соответствующие функции C pow или exp и log и запускает профилирование на тех, что есть на С++, без какого-либо numpy-кода, дает:

pow      : 286 ms
exp(log) :  93 ms

Это согласуется с таймингом numpy. Похоже, что основное отличие состоит в том, что функция C pow медленнее, чем exp(log).

Почему? Похоже, что часть резона состоит в том, что выражения не эквивалентны для всех входных данных. Например, с отрицательным a и целым числом b, power работает, пока exp(log) терпит неудачу:

>>> np.power(-2, 2)
4
>>> np.exp(2 * np.log(-2))
nan

Другим примером является 0 ** 0:

>>> np.power(0, 0)
1
>>> np.exp(0 * np.log(0))
nan

Следовательно, трюк exp(log) работает только на подмножестве входов, а power работает на всех (действительных) входах.

В дополнение к этому power гарантируется полная точность в соответствии с стандартом IEEE 754, а exp(log) может пострадать от ошибок округления.