1

这是我的脚本的内容:

from sympy import *
x = symbols('x')
init_printing(use_unicode=True)

f = symbols('f', cls=Function)
diffeq = Eq(x**2 * f(x).diff(x, x) + x * f(x).diff(x) - f(x) , 1/((1+x**2)**(3)) )
print dsolve(diffeq, f(x))

该程序返回以下输出:

Eq(f(x), (C1*x**2 + C1 + C2*x**4 + C2*x**2 - 15*x**4*atan(x) - 15*x**3 - 18*x**2*atan(x) - 13*x - 3*atan(x))/(16*x*(x**2 + 1)))

但是当我这样定义变量时diffeq

diffeq = Eq(f(x).diff(x, x) + f(x).diff(x)/x - f(x)/x**(2) , 1 / ((1+x**2)**(3) * x**(2)) )

然后我收到输出:

Traceback (most recent call last):
  File "/home/foo/odeSympyTrial01.py", line 12, in <module>
print dsolve(diffeq, f(x))
  File "/usr/lib/python2.7/dist-packages/sympy/solvers/ode.py", line 625, in dsolve
    x0=x0, n=n, **kwargs)
  File "/usr/lib/python2.7/dist-packages/sympy/solvers/deutils.py", line 235, in _desolve
    raise NotImplementedError(dummy + "solve" + ": Cannot solve " + str(eq))
NotImplementedError: solve: Cannot solve Derivative(f(x), x, x) + Derivative(f(x), x)/x - f(x)/x**2 - 1/(x**2*(x**2 + 1)**3)

当我diffeq像这样定义变量时:

diffeq = Eq(f(x).diff(x, x) * x**(2) + f(x).diff(x) * x**(2) /x - f(x) * x**(2) /x**(2) , 1* x**(2)/((1+x**2)**(3) * x**(2)) )

然后我收到输出:

Eq(f(x), (C1*x**2 + C1 + C2*x**4 + C2*x**2 - 15*x**4*atan(x) - 15*x**3 - 18*x**2*atan(x) - 13*x - 3*atan(x))/(16*x*(x**2 + 1)))

在每一种情况下,微分方程diffeq在数学上都是相等的。因此,我认为dsolve()应该为每种情况返回相同的输出。有人请帮助我理解为什么dsolve()在第二种情况下返回错误。非齐次线性常微分方程应该如何表达才能保证dsolve()不返回错误?

4

1 回答 1

1

简短说明:SymPy ODE 模块的逻辑通常很幼稚,有时甚至不正确。

如最初所写,与

x**2 * f(x).diff(x, x) + x * f(x).diff(x) - f(x)

这符合Cauchy–Euler 方程(也称为 Euler 方程)的形式:每个系数中 x 的幂是导数的阶。SymPy 检测到这种结构并应用适当的方法。但如果除以x**2

f(x).diff(x, x) + f(x).diff(x)/x - f(x)/x**(2) 

现在不再是这种情况:二阶导数没有 的幂,x**2因此匹配失败。更仔细的检查可以在这里检测到潜在的 Cauchy-Euler 结构,但这并没有实现,正如通过查看source可以看到的那样。

你可以检查这确实是怎么回事

classify_ode(diffeq, f(x))

这将在第一种情况下返回 'nth_linear_euler_eq_nonhomogeneous_variation_of_parameters' 而不是第二种情况。


在查看源代码时,还可以看到一个错误逻辑的示例。

        if coeff.is_Mul:
            if coeff.has(f(x)):
                return False
            return x**order in coeff.args

例如,x**2*sin(x)将通过此检查,order=2,这意味着 SymPy 将误认为x**2*sin(x)*f(x).diff(x, x) - f(x) = 0欧拉方程。确实,

dsolve(x**2*sin(x)*f(x).diff(x, x) - f(x), f(x))

错误地“求解”方程。不要相信 SymPy 的 ODE 解决方案。

于 2018-05-19T16:17:48.110 回答