需要帮助在 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)
mpmath
知道gammainc,用它;
npsum
很聪明,不要想变得更聪明,只要求和到无穷大。它会进行一些奇特的计算,以便在需要时停止;
- 如果您关心精度,请尽量使用
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]
这是我的一段代码和总和。它包括一个积分。那里的所有变量都有浮点数或整数值。
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)
mpmath
知道gammainc,用它;npsum
很聪明,不要想变得更聪明,只要求和到无穷大。它会进行一些奇特的计算,以便在需要时停止;- 如果您关心精度,请尽量使用
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]