微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何优化 SymPy 积分的数值评估?

如何解决如何优化 SymPy 积分的数值评估?

我是 SymPy 的新手,希望有人能指出优化我的代码方法

我需要对小数位非常高(150-300)的有点复杂的表达式进行数值计算,并且每个参数集需要 30 秒或更长时间 - 鉴于要计算的参数空间,这很长。

我已将 lambdifympmath 后端和 meijerg=True 一起用于整体处理,它显着降低了运行时间。有没有其他方法可以使用?理想情况下,将评估时间推到 1 秒以下会很棒。我的代码是:

import mpmath
from mpmath import mpf,mp
mp.dps = 150 # ideally would like to have this set to 300 
import numpy as np
from sympy import besselj,symbols,hankel2,legendre,sin,cos,tan,summation,I
from sympy import  lambdify,expand,Integral
import time
x,alpha,k,m,n,r1,R,theta = symbols('x alpha k m n r1 R theta')

r1 = (R*cos(alpha))/cos(theta) #

Imn_part1 = (n*hankel2(n-1,k*r1)-(n+1)*hankel2(n+1,k*r1))*legendre(n,cos(theta))*cos(theta)
Imn_part2 = n*(n+1)*hankel2(n,k*r1)*(legendre(n-1,cos(theta)-legendre(n+1,cos(theta))))/k*r1
Imn_parts = expand(Imn_part1+Imn_part2)
Imn_expr = expand(Imn_parts*legendre(m,cos(theta))*(r1**2/R**2)*tan(theta))
Imn = Integral(Imn_expr,(theta,alpha)).doit(meijerg=True)

# the lambdified expression
Imn_lambdify = lambdify([m,alpha],Imn,'mpmath')

函数提供数字输入时 - 需要很长时间(30 到 40 秒)。

substitute_dict = {'alpha':mpf(np.radians(10)),'k':5,'R':mpf(0.1),'m':20,'n':10}

print('starting calculation...')
start = time.time()
output = Imn_lambdify(substitute_dict['m'],substitute_dict['n'],substitute_dict['k'],substitute_dict['R'],substitute_dict['alpha'])
print(time.time()-start)

使用的操作系统/软件包版本:

  • Linux Mint 19.2
  • Python 3.8.5
  • SymPy 1.7.1
  • MPMath 1.2.1

解决方法

设置 meijerg=True 只是导致 SymPy 在评估积分时不那么努力。它仍然无法评估它,但它已将其拆分为 5 个子积分,您可以通过打印 Imn 来查看这些子积分。您不妨将其作为一个整体保留(去掉 doit()):

Imn = Integral(Imn_expr,(theta,alpha))

对我来说,分裂积分的计算速度要快一些,但这也是差不多的速度

Imn = Integral(simplify(Imn_expr),alpha))

最终,使事情变慢的是您使用的位数。如果您实际上不需要这么多数字,则不应使用它们。注意 mpmath 会在内部自动增加精度以避免取消,所以没有必要自己这样做。我得到相同的值(数字更少),默认 dps 为 15 和 150。

您可以尝试将您的值直接替换到您的表达式中,如果它们没有改变,并查看 SymPy 是否可以使用它们进一步简化 Imn_expr。

顺便说一句,您使用的是 np.radians(10),它是机器浮动的,因为这是 NumPy 使用的。这完全违背了将最终答案计算为 150 位数的目的,因为此输入参数只能精确到 15。请考虑使用 mpmath.pi/18 来获取与您指定的位数正确的值。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。