我正在建模黎曼θ函数:
import numpy as np def theta(s, n=100): a_range = np.arange(2, n + 1) return 1 + sum(1/(a_range ** s))
它对否定无效s; 例如theta(-2)导致此错误:
s
theta(-2)
1 def theta(s, n=100): 2 a_range = np.arange(1) ----> 3 return 1 + sum(1/(a_range ** s)) 4 5 theta(-2) ValueError: Integers to negative integer powers are not allowed.
为什么?x^-1应该只是1/x如果我正确地记得我的数学。
x^-1
1/x
在NumPy中,用于选择类似操作的输出a_range ** sdtype的逻辑基于dtype,而不是值。这意味着a_range ** -2必须具有与相同的输出dtype a_range ** 2。
a_range ** s
a_range ** -2
a_range ** 2
numpy.array([2]) ** 2给出整数输出之类的东西很重要,这意味着numpy.array([2]) ** -2必须给出整数或什么都不给出。他们什么也没捡。将整数提高为负整数幂是NumPy中的错误。
numpy.array([2]) ** 2
numpy.array([2]) ** -2
如果要浮点输出,请进行浮点输入:
a_range = np.arange(2, n + 1, dtype=float)
要么
a_range = np.arange(2, n + 1).astype(float)
从上面的描述中可能不会想到NumPy的类型规则的一些奇怪方面。一种是对于涉及标量和数组的操作,在使用输入dtypes选择结果dtype之前,实际上可以根据标量的dtype将其dtype降级:
>>> (numpy.array([1], dtype='int8') + numpy.int32(1)).dtype dtype('int8') >>> (numpy.array([1], dtype='int8') + numpy.array([1], dtype='int32')).dtype dtype('int32')
在这里,标量numpy.int32(1)被“降级”到int8,但数组不会降级。(实际上,这不仅比降级为int8还复杂,尤其是对于有符号/无符号处理;有关详细信息,请参见实现。)
numpy.int32(1)
其次,当涉及到uint64s时,NumPy突然看起来可以接受负指数:
>>> numpy.arange(5, dtype='uint64') ** -2 __main__:1: RuntimeWarning: divide by zero encountered in power array([ inf, 1. , 0.25 , 0.11111111, 0.0625 ])
这是因为NumPy无法找到足够大的整数dtype来容纳uint64值和负值,因此它放弃并将输入强制为浮点数。只要避免使用标量类型“降级”,对于带符号dtype的正指数,可以看到相同的结果:
>>> numpy.arange(5, dtype='uint64') ** numpy.array([2], dtype='int32') array([ 0., 1., 4., 9., 16.])