Skip to main content
 首页 » 编程设计

python之Python 中的对数计算

2025年05月04日9daizhj

我正在寻找计算类似的东西:

在哪里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