在尝试运行我自己的代码时,我遇到了numba的麻烦(超出了教程示例)。似乎编译器没有正确处理power函数,而且我得到了垃圾(所有的)。真正的结果是p系列和,应该给出:
2 1.64493306685
3 1.20205690315
4 1.08232323371
如果不使用电源功能而是使用像分区一样愚蠢的东西,我会得到预期的结果,所以这是特定的pow功能的问题。尝试使用numpy的幂函数,相同的奇怪行为。
from numba import autojit
from numpy import power as npow
N=1000000
def psum(p):
pval = 0.0
for ix in xrange(1,N):
pval+=pow(ix,-p)
return pval
nsum = autojit()(psum)
for p in range(2,5):
print p, nsum(p)
在你因为没有足够pythonic而对我的代码大喊大叫之前,我知道psum可以写成一行代码: 返回和([x(1,N)中ix的[pow(ix,-p)])
但其他人已经指出numba不处理列表推导的功能。
答案 0 :(得分:1)
看起来numpy.power
的行为有所不同,具体取决于输入的类型。不同类型的参数被强制转换为相同的类型(例如int
- > float
如果一个是int
而另一个是float
)。你输入整数,所以你得到整数取幂(无论那意味着什么)。放在一个漂浮物中,一切都与世界一致。
>>> numpy.power(2, -10)
0
>>> numpy.power(2., -10)
0.0009765625
>>> numpy.power(2, -10.)
0.0009765625
换句话说,你想要:
pval += pow(float(ix), -p)
或者,或许更高效的是将p
作为浮点数传递:
print p, nsum(float(p))
答案 1 :(得分:0)
在Python中are a few rules on type coercion有助于了解何时进行数学工作。我相信您使用内置pow
函数遇到其中一个,这要归功于使用numba
的不同强制规则。 (让人惊讶!)
当您需要进行准确性非常重要的数学运算时,您应该更新代码以提供float
值。
以下是使用输出更新的代码:
from numba import autojit
N = 1000000
def psum(p):
pval = 0.0
for ix in xrange(1, N):
pval += pow(float(ix), float(-p))
return pval
nsum = autojit()(psum)
for p in range(2, 5):
print p, nsum(p), psum(p)
python tests.py
的输出:
2 1.64493306685 1.64493306685
3 1.20205690315 1.20205690315
4 1.08232323371 1.08232323371