我应该如何处理 sympy 以获得积分的“正常”结果?

Bot*_*ond 6 sympy python-3.x

我的练习是将一些功能与 sympy 集成。第一个积分是(我将把它添加到图像上,因为我在这里不能使用乳胶,但你也可以在代码中看到它):
在此输入图像描述

在此输入图像描述
a 是实常数。

这是我的代码:

%pylab inline
from sympy import *
init_printing()
v, a = symbols('v, a', real=True, nonzero=True)
f = sqrt(2/pi)*(v**2*exp((-v**2)/(2*a**2)))/(a**3)
print(integrate(v*f, (v, 0, oo)))
Run Code Online (Sandbox Code Playgroud)

(注意:我只使用 print 来获得这个可复制的结果)但结果真的很难看:

Piecewise((2*sqrt(2)*a/sqrt(pi), Abs(periodic_argument(polar_lift(a)**(-2), oo)) < pi/2), (Integral(sqrt(2)*v**3*exp(-v**2/(2*a**2))/(sqrt(pi)*a**3), (v, 0, oo)), True))
Run Code Online (Sandbox Code Playgroud)

但随着修改

v, a = symbols('v, a', positive=True)
Run Code Online (Sandbox Code Playgroud)

或者

v, a = symbols('v, a', negative=True)
Run Code Online (Sandbox Code Playgroud)

结果是

2*sqrt(2)*a/sqrt(pi)
Run Code Online (Sandbox Code Playgroud)

但据我所知,唯一既不为负也不为正的实数是零 - 并且应该将其与“nonzero=True”部分一起排除。

问:我可以用我的第一个代码做什么来获得“好的”结果?

小智 4

在当前的开发版本中,输出不太难看:

Piecewise((2*sqrt(2)*a/sqrt(pi), pi/2 > 2*Abs(arg(a))), (Integral(sqrt(2)*v**3*exp(-v**2/(2*a**2))/(sqrt(pi)*a**3), (v, 0, oo)), True))
Run Code Online (Sandbox Code Playgroud)

不过,仍有改进的余地。我建议在问题跟踪器上提出问题。

解决方法

pi/2 > 2*Abs(arg(a))使用 Piecewise 的原因是,如果条件不成立,SymPy 不确定积分是否收敛。由于您知道它确实在您的上下文中收敛,因此您可以通过设置告诉 SymPy 不要理会收敛条件conds="none"

>>> integrate(v*f, (v, 0, oo), conds="none") 
2*sqrt(2)*a/sqrt(pi)
Run Code Online (Sandbox Code Playgroud)

或者,使用假设:设置“积极”假设a就足够了。您可以在积分步骤中通过临时交换a正号来执行此操作。

>>> apos = symbols('apos', positive=True)
>>> integrate(v*f.subs(a, apos), (v, 0, oo)).subs(apos, a)
2*sqrt(2)*a/sqrt(pi)
Run Code Online (Sandbox Code Playgroud)

这允许a在更大的计算环境中保持原样。

解释

以下是对为什么假设集(实数和非零)的影响小于(正数)或(负数)影响的非正式解释。

  1. 如果某件事已知a是积极的,那么就可以做它,并且它会产生良好的输出。
  2. a如果已知结果为负,则可以做另一件事,并且会产生良好的输出。

鉴于这a是实数且非零,SymPy 会问:我可以做第一件事吗?不,因为不能保证是a积极的。然后它问:我可以做第二件事吗?不,因为不能保证结果a是负数。所以,两者都没有完成。

核心问题是使用Python逻辑来做符号逻辑是有限制的。在 Python 逻辑中,所有内容都必须评估为单个真值。在符号逻辑中,表达式可能具有未知的真值。另一个例子是排中律。如果不先评估“stuff”,Python 就不知道“stuff 或 not stuff”始终为 True。符号逻辑可以知道这一点,即使“东西”的真值未知。https://github.com/sympy/sympy/wiki/假设历史