Python 3.x 我应该如何处理sympy以获得';正常';积分的结果?

Python 3.x 我应该如何处理sympy以获得';正常';积分的结果?,python-3.x,sympy,Python 3.x,Sympy,我的练习是将一些函数与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(integr

我的练习是将一些函数与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)))
(注意:我仅使用打印来获得此可复制结果) 但结果真的很糟糕:

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

结果是

2*sqrt(2)*a/sqrt(pi)
但据我所知,唯一一个既不为负也不为正的实数是零,这应该被排除在‘非零=真’部分之外


Q:如何处理我的第一个代码以获得“好”的结果?

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

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))
但仍有改进的余地。我建议在会议上提出一个问题

权变措施 分段的原因是,如果条件
pi/2>2*Abs(arg(a))
不成立,则Symphy不确定积分是否收敛。由于您知道它在您的上下文中会收敛,您可以通过设置
conds=“none”
,告诉SymPy不要为收敛条件操心:

或者,使用假设:在
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
在更大的计算环境中保持原样

解释 下面是一个非正式的解释,解释为什么假设集(实的和非零的)比(正的)或(负的)影响小

  • 如果已知
    A
    为正,则可以执行特定的操作,并产生良好的输出
  • 如果已知
    a
    为负数,则可以执行另一项操作,从而获得良好的输出 考虑到
    a
    是实数且非零,SymPy问:我能做第一件事吗?否,因为不能保证
    a
    为正。然后它问:我能做第二件事吗?否,因为不能保证
    a
    为负值。所以,两者都没有完成

    核心问题是,使用Python逻辑执行符号逻辑存在局限性。在Python逻辑中,所有内容都必须计算为一个真值。在符号逻辑中,表达式可能具有未知的真值。另一个例子是被排除在外的中间法则。Python不知道在不首先计算“stuff”的情况下,“stuff”或“notstuff”总是正确的。符号逻辑可以知道这一点,即使“东西”的真值未知


    谢谢你详细的回答!您是否使用了任何限制(如real=True)来获得第一个结果?我也在考虑用一个正变量替换a,但是第二个积分中有一个abs(a),我认为该方法在替换后不会给出abs(a),而只是a。我做了,但是结果是一样的,没有任何假设。区别在于我使用了dev版本(),其中简化了收敛条件。条件仍然存在,只是看起来不那么难看。底线是,
    a**2
    的平方根被取下,这使得
    a
    的符号未知的问题变得复杂。如果已知,则根计算为
    a
    -a
    ,从而简化了事情。我在这一点上做了一些扩展。对于您的用例来说,
    conds=“none”
    可能是最好的选择。
    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))
    
    >>> integrate(v*f, (v, 0, oo), conds="none") 
    2*sqrt(2)*a/sqrt(pi)
    
    >>> apos = symbols('apos', positive=True)
    >>> integrate(v*f.subs(a, apos), (v, 0, oo)).subs(apos, a)
    2*sqrt(2)*a/sqrt(pi)