Sympy 奇怪的积分输出
Sympy strange integral output
我正在尝试使用 sympy 求解积分。但它给了我一个错误的解决方案。为什么?
import sympy
from sympy import Integral, exp, oo
x, y = sympy.symbols("x y", real=True)
b, u, l, t = sympy.symbols("b u l t ", real=True, positive=True)
Fortet = Integral(exp(-l * t) * (sympy.sqrt(2 * sympy.pi * t)) ** (-1) * exp(-((b - u * t - y) ** 2) / (2 * t)),
(t, 0, oo))
Fortet.doit()
结果(错误):
Piecewise((-(-b/2 + y)*sqrt(2*l +
u**2)*(-sqrt(pi)*sinh(sqrt(2)*sqrt(b)*sqrt(l +
u**2/2)*sqrt(polar_lift(1 + y**2/(b*polar_lift(b -
2*y))))*sqrt(polar_lift(b - 2*y))) +
sqrt(pi)*cosh(sqrt(2)*sqrt(b)*sqrt(l + u**2/2)*sqrt(polar_lift(1 +
y**2/(b*polar_lift(b - 2*y))))*sqrt(polar_lift(b - 2*y))))*exp(b*u -
u*y)/(sqrt(pi)*(b - 2*y)*(l + u**2/2)), Abs(arg(1 +
y**2/(b*polar_lift(b - 2*y))) + arg(b - 2*y)) <= pi/2),
(Integral(sqrt(2)*exp(-l*t)*exp(-(b - t*u -
y)**2/(2*t))/(2*sqrt(pi)*sqrt(t)), (t, 0, oo)), True))
预期(正确)解决方案:
Solution = (exp((-u)*(b - y)) * exp(sympy.sqrt(u**2 + 2*l)*(b-y)))/(sympy.sqrt(2*l + u**2)) #RIGHT solution
这两个结果其实是一样的。第一个可能稍微更正确。每当 SymPy 在不知道内部事物的符号(集成后)时尝试执行诸如平方根之类的操作时,您往往会看到这些 polar_lift
函数
一个polar_lift
没有出现在下面,但是这个基本的高斯例子表明SymPy试图尽可能通用:
from sympy import *
x = Symbol("x", real=True)
y = Symbol("y", real=True)
s = Symbol("s", real=True) # , positive=True
gaussian = exp(-((x-y)**2)/(2*(s**2)))
nfactor = simplify(integrate(gaussian, (x,-oo,oo)))
print(nfactor)
您需要 s
才能被宣布为阳性:s = Symbol("s", real=True, positive=True)
。在您的示例中,这些类型的 polar_lift(b - 2*y)
函数也会发生类似的事情。它也发生在 the question 我在下面引用。
我不知道为什么,但是 N(polar_lift(x))
对于任何 float
或 int
x
再次给出 x
;然而,SymPy 并没有用符号 x
很好地简化。事实证明,如果你继续简化,你会得到越来越好看的答案。我找不到任何关于 polar_lift 与纯数学相关的信息,所以我不知道它实际上做了什么。
还记得上面的简单示例是如何给出分段的吗?同样的事情在这里。所以我们只取第一部分,因为第二部分是未计算的积分。
在下面的代码中,我使用this question删除了分段函数,然后简化了两次。最后,我手动删除了 polar_lift
.
import sympy as sp
x, y = sp.symbols("x y", real=True)
b, u, l, t = sp.symbols("b u l t ", real=True, positive=True)
Fortet = sp.integrate(sp.exp(-l * t) * (sp.sqrt(2 * sp.pi * t)) ** (-1) *
sp.exp(-((b - u * t - y) ** 2) / (2 * t)),
(t, 0, sp.oo), conds='none')
incorrect = Fortet.simplify().simplify()
correct = eval(str(incorrect).replace("polar_lift", ""))
correct = correct.factor()
print(correct)
结果是:
exp(b*u)*exp(-u*y)*exp(-sqrt(2*l + u**2)*sqrt(b**2 - 2*b*y + y**2))/sqrt(2*l + u**2)
这与您的表达足够接近。无论我多么努力,我都无法让 SymPy 将 sqrt(b**2 - 2*b*y + y**2)
简化为 Abs(b-y)
。
请注意,要么 SymPy 仍然错误,要么你错了,因为分子中的幂是相反的。所以我在 Desmos 上查看了数字答案(第一个是你的):
我正在尝试使用 sympy 求解积分。但它给了我一个错误的解决方案。为什么?
import sympy
from sympy import Integral, exp, oo
x, y = sympy.symbols("x y", real=True)
b, u, l, t = sympy.symbols("b u l t ", real=True, positive=True)
Fortet = Integral(exp(-l * t) * (sympy.sqrt(2 * sympy.pi * t)) ** (-1) * exp(-((b - u * t - y) ** 2) / (2 * t)),
(t, 0, oo))
Fortet.doit()
结果(错误):
Piecewise((-(-b/2 + y)*sqrt(2*l +
u**2)*(-sqrt(pi)*sinh(sqrt(2)*sqrt(b)*sqrt(l +
u**2/2)*sqrt(polar_lift(1 + y**2/(b*polar_lift(b -
2*y))))*sqrt(polar_lift(b - 2*y))) +
sqrt(pi)*cosh(sqrt(2)*sqrt(b)*sqrt(l + u**2/2)*sqrt(polar_lift(1 +
y**2/(b*polar_lift(b - 2*y))))*sqrt(polar_lift(b - 2*y))))*exp(b*u -
u*y)/(sqrt(pi)*(b - 2*y)*(l + u**2/2)), Abs(arg(1 +
y**2/(b*polar_lift(b - 2*y))) + arg(b - 2*y)) <= pi/2),
(Integral(sqrt(2)*exp(-l*t)*exp(-(b - t*u -
y)**2/(2*t))/(2*sqrt(pi)*sqrt(t)), (t, 0, oo)), True))
预期(正确)解决方案:
Solution = (exp((-u)*(b - y)) * exp(sympy.sqrt(u**2 + 2*l)*(b-y)))/(sympy.sqrt(2*l + u**2)) #RIGHT solution
这两个结果其实是一样的。第一个可能稍微更正确。每当 SymPy 在不知道内部事物的符号(集成后)时尝试执行诸如平方根之类的操作时,您往往会看到这些 polar_lift
函数
一个polar_lift
没有出现在下面,但是这个基本的高斯例子表明SymPy试图尽可能通用:
from sympy import *
x = Symbol("x", real=True)
y = Symbol("y", real=True)
s = Symbol("s", real=True) # , positive=True
gaussian = exp(-((x-y)**2)/(2*(s**2)))
nfactor = simplify(integrate(gaussian, (x,-oo,oo)))
print(nfactor)
您需要 s
才能被宣布为阳性:s = Symbol("s", real=True, positive=True)
。在您的示例中,这些类型的 polar_lift(b - 2*y)
函数也会发生类似的事情。它也发生在 the question 我在下面引用。
我不知道为什么,但是 N(polar_lift(x))
对于任何 float
或 int
x
再次给出 x
;然而,SymPy 并没有用符号 x
很好地简化。事实证明,如果你继续简化,你会得到越来越好看的答案。我找不到任何关于 polar_lift 与纯数学相关的信息,所以我不知道它实际上做了什么。
还记得上面的简单示例是如何给出分段的吗?同样的事情在这里。所以我们只取第一部分,因为第二部分是未计算的积分。
在下面的代码中,我使用this question删除了分段函数,然后简化了两次。最后,我手动删除了 polar_lift
.
import sympy as sp
x, y = sp.symbols("x y", real=True)
b, u, l, t = sp.symbols("b u l t ", real=True, positive=True)
Fortet = sp.integrate(sp.exp(-l * t) * (sp.sqrt(2 * sp.pi * t)) ** (-1) *
sp.exp(-((b - u * t - y) ** 2) / (2 * t)),
(t, 0, sp.oo), conds='none')
incorrect = Fortet.simplify().simplify()
correct = eval(str(incorrect).replace("polar_lift", ""))
correct = correct.factor()
print(correct)
结果是:
exp(b*u)*exp(-u*y)*exp(-sqrt(2*l + u**2)*sqrt(b**2 - 2*b*y + y**2))/sqrt(2*l + u**2)
这与您的表达足够接近。无论我多么努力,我都无法让 SymPy 将 sqrt(b**2 - 2*b*y + y**2)
简化为 Abs(b-y)
。
请注意,要么 SymPy 仍然错误,要么你错了,因为分子中的幂是相反的。所以我在 Desmos 上查看了数字答案(第一个是你的):