【问题标题】:What should I do with the sympy to get a 'normal' result for the integral?我应该如何处理 sympy 以获得积分的“正常”结果?
【发布时间】:2018-03-12 21:58:01
【问题描述】:

我的练习是将一些功能与 sympy 集成。第一个积分是(我要在图片上加,因为这里不能用latex,但是代码里也可以看到):



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)))

(注意:我只使用 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))

但随着修改

v, a = symbols('v, a', positive=True)

v, a = symbols('v, a', negative=True)

结果是

2*sqrt(2)*a/sqrt(pi)

但据我所知,唯一具有既不是负也不是正的属性的实数是零——应该用“非零=真”部分排除。

问:如何使用我的第一个代码来获得“不错”的结果?

【问题讨论】:

    标签: python-3.x sympy


    【解决方案1】:

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

    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))
    

    不过,仍有改进的余地。我建议在issue tracker 提出问题。

    解决方法

    Piecewise 的原因是如果条件 pi/2 &gt; 2*Abs(arg(a)) 不成立,SymPy 不确定积分是否收敛。既然你知道它确实在你的上下文中收敛,你可以通过设置 conds="none" 来告诉 SymPy 不要打扰收敛条件:

    >>> integrate(v*f, (v, 0, oo), conds="none") 
    2*sqrt(2)*a/sqrt(pi)
    

    或者,使用假设:在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)
    

    这允许a 在更大的计算上下文中保持原样。

    说明

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

    1. 如果知道a 是正数,则可以做某事,并产生良好的输出。
    2. 如果知道a 是负数,可以做另一件事,它会产生很好的输出。

    鉴于a 是真实且非零的,SymPy 会问:我可以做第一件事吗?不,因为不能保证a 是肯定的。然后它问:我可以做第二件事吗?不,因为不能保证a 是否定的。所以,两者都没有完成。

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

    【讨论】:

    • 感谢您的详细解答!您是否使用任何限制(如 real=True)来获得第一个结果?我也在考虑用正变量替换a,但是第二个积分中有一个abs(a),我认为替换后该方法不会给出abs(a),而只是a。
    • 我做了,但没有任何假设,结果是一样的。不同之处在于我使用了开发版本(cloned from github),其中recent PR 简化了收敛条件。情况仍然存在,只是看起来不那么丑了。
    • 底线是,a**2 的平方根被取了,这使得a 的符号未知的事情变得复杂。如果已知,根的计算结果为a-a,从而简化事情。我在这一点上做了一些扩展。
    • conds="none" 可能是您的用例的最佳选择。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-02-24
    • 1970-01-01
    • 2014-05-12
    • 1970-01-01
    • 2011-12-05
    • 2021-09-11
    相关资源
    最近更新 更多