我意识到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
结果是相同的(有一些 1e-16 阶的数值误差)。
还做了哪些额外工作np.power
?此外,我自己怎样才能找到这些问题的答案呢?
在引擎盖下 https://github.com/numpy/numpy/blob/3b7908d299fc3287486bbe453e2335c1fa50fc29/numpy/core/src/npymath/npy_math_internal.h.src两个表达式都调用各自的 C 函数pow
or exp
and log
and 对 C++ 中的内容运行分析 https://gist.github.com/adler-j/a440d4539ad1bbaa7dc3e2727f93e8b1,没有任何 numpy 代码,给出:
pow : 286 ms
exp(log) : 93 ms
这与 numpy 时序一致。因此,主要区别似乎是 C 函数pow
慢于exp(log)
.
为什么?看来部分原因是表达式对于所有输入并不等效。例如,带有负数a
和整数b
, power
工作同时exp(log)
fails:
>>> 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 标准 https://en.wikipedia.org/wiki/IEEE_754, while exp(log)
可能会出现舍入误差。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)