需要帮助在 python 中更快地进行求和计算

Need help making a sum calculation faster in python

这是我的一段代码和总和。它包括一个积分。那里的所有变量都有浮点数或整数值。

import numpy as np
import math
import scipy.integrate
from mpmath import nsum, inf

sum1 = nsum(lambda m: (1/(math.factorial(m))*((ra/a1)**(2*m))*(1/(math.factorial((m+1)-1)))*(scipy.integrate.quad(lambda u:((u**((m+1)-1))*(math.exp(-u))) ,0,(d**2)/(4*(a1**2)),limit = 50))[0]),[0,100])

有什么方法可以让它更快吗?我需要能够循环数百次。目前需要一个多小时。这是原始的完整方程式。我在此处粘贴的代码部分只是方程式中的第一个和 (sigma),其中 m 从 0 到无穷大。我在这里的代码中暂时将它从 0 更改为 m 到 100。

非常感谢!

更新:

我试过另一种方法。我认为那些评论的人是对的,我之前使用 scipy 是错误的。我想我已经修好了。就我的目的而言,它仍然很慢,但现在重复数百次只需要 30 分钟。 (我还猜测您可以使用“def”结构或“lambda”结构来传递四边形)。如果您有任何建议可以更快地完成此类操作,我将不胜感激,但我感谢你们帮助找到答案。

for m in range(0,100):

    # def integrand(u,m):
    #     return (u**((m+1)-1))*(math.exp(-u)) 

    f = lambda u,m:(u**((m+1)-1))*(math.exp(-u)) 
    
    sumfunc =1/(math.factorial(m))*((ra/a1)**(2*m))*(1/(math.factorial((m+1)-1)))*scipy.integrate.quad(f,0,(d**2)/(4*(a1**2)),args=(m,))[0] 
    
    tosum.append(sumfunc)
    
sum1 = sum(tosum)
  1. mpmath知道gammainc,用它;
  2. npsum很聪明,不要想变得更聪明,只要求和到无穷大。它会进行一些奇特的计算,以便在需要时停止;
  3. 如果您关心精度,请尽量使用 mpmath 类型

代码如下:

from mpmath import *

a1 = mpf('0.62')
ra = mpf('0.99')

def the_sum(d, a, **kwargs): # added `a` for reuse in the complete formula
    r_ = (ra / a) ** 2
    d_ = d ** 2 / (4 * a ** 2)
    return nsum(
        lambda m: r_ ** m / factorial(m) * gammainc(m + 1, 0, d_, regularized=True),
        [0, inf],
        **kwargs
    )

和一些基准

%time [sum_OP(d) for d in range(5)]                                                                                                                                                                
CPU times: user 684 ms, sys: 2.97 ms, total: 687 ms
Wall time: 685 ms
[mpf('0.0'),
 mpf('0.93752967676144794'),
 mpf('5.3589089548240878'),
 mpf('10.711751972234245'),
 mpf('12.600516476806067')]

%time [the_sum(d, a1) for d in range(5)]                                                                                                                                                               
CPU times: user 28.7 ms, sys: 1.3 ms, total: 30 ms
Wall time: 28.8 ms
[mpf('0.0'),
 mpf('0.93752967676144794'),
 mpf('5.3589089548240905'),
 mpf('10.711751972234246'),
 mpf('12.600516476806067')]

如果你真的想让事情变得更快,想要比 nsum 更聪明,并且有信心在这种情况下它会起作用(我相信),你可以告诉它使用 direct 方法:

 %time [the_sum(d, a1, method='d') for d in range(5)]                                                                                                                                               
CPU times: user 20.7 ms, sys: 613 µs, total: 21.3 ms
Wall time: 20.9 ms
[mpf('0.0'),
 mpf('0.93752967676144794'),
 mpf('5.3589089548240905'),
 mpf('10.711751972234246'),
 mpf('12.600516476806067')]

最后,您似乎不需要任何多精度,不需要使用 mpmath,并坚持使用一些低精度版本:

a1 = 0.62
ra = 0.99
def sum_low_prec(d, a):
    return sum(
        (ra/a)**(2*m) / (math.factorial(m)) * scipy.special.gammainc(m + 1, (d**2)/(4*(a**2)))
         for m in range(30)
    )

%time [sum_low_prec(d, a1) for d in range(5)]                                                                                                                                                     
CPU times: user 871 µs, sys: 3 µs, total: 874 µs
Wall time: 877 µs
[0.0,
 0.9375296767614478,
 5.358908954824089,
 10.711751972234243,
 12.600516476806066]