我正在寻找计算类似的东西:
在哪里f(i)是一个返回实数的函数 [-1,1]对于任何 i在 {1,2,...,5000} .
显然,求和的结果在[-1,1]中的某处,但是当我似乎无法使用直接编码在 Python 中计算它时,如 0.5<sup>5000</sup>变成 0和 comb(5000,2000)变成 inf ,这导致计算总和变为 NaN .
所需的解决方案是在两边都使用日志。
即使用身份 a × b = 2<sup>log(a) + log(b)</sup> , 如果我能计算 log(a)和 log(b)我可以计算总和,即使 a很大而且b几乎是0 .
所以我想我想问的是是否有一种简单的计算方法
log2(scipy.misc.comb(5000,2000))
所以我可以简单地计算我的总和
sum([2**(log2comb(5000,i)-5000) * f(i) for i in range(1,5000) ])
@abarnert 的解决方案在为 5000 个数字工作时通过提高计算梳子的精度解决了这个问题。这适用于此示例,但无法扩展,因为如果我们使用 1e7 而不是 5000,则所需的内存将显着增加。
目前,我正在使用一种丑陋的变通方法,但可以保持较低的内存消耗:
log2(comb(5000,2000)) = sum([log2 (x) for x in 1:5000])-sum([log2 (x) for x in 1:2000])-sum([log2 (x) for x in 1:3000])
有没有办法在可读的表达式中这样做?
请您参考如下方法:
总和
是 f 对 binomial distribution 的期望n = 5000 和 p = 0.5。
您可以使用 scipy.stats.binom.expect 来计算它:
import scipy.stats as stats
def f(i):
return i
n, p = 5000, 0.5
print(stats.binom.expect(f, (n, p), lb=0, ub=n))
# 2499.99999997
另请注意,随着 n 趋于无穷大,p 固定,二项分布 approaches the normal distribution具有均值 np 和方差 np*(1-p)。因此,对于较大的 n,您可以改为计算:
import math
print(stats.norm.expect(f, loc=n*p, scale=math.sqrt((n*p*(1-p))), lb=0, ub=n))
# 2500.0
