python解常微分方程_Python-sympy.dsolve求解常微分方程(组)

这里分别介绍怎么利用sympy.dsolve求解常微分方程和常微分方程组。

#首先利用sympy.dsolve求解单个的常微分方程:

#代码

from sympy import Function, dsolve, Derivative, symbols

from sympy.abc importt

#sympy.abc表示This module exports all latin and greek letters as Symbols。上行代码意思是导入字母t,因为t字母在dsolve函数中要被使用,而dsolve函数中的x这里不需要导入是因为在下一行会声明x变量

x = Function('x')

#上行代码等效于x = symbols('x', cls=Function),意思是声明x为因变量函数

result=dsolve(Derivative(x(t), t, 4) - 22*Derivative(x(t), t, 2) - 24*x(t))

#result=dsolve(Derivative(x, t, 4) - 22*Derivative(x, t, 2) - 24*x),这样写是不可以的

#Derivative(x(t), t, i)可以写成diff(x(t), t, i),或者写成Derivative(x(t), t, t, t, t)和diff(x(t), t, t, t, t)都表示函数x(t)对t的四阶导数,注意如果要使用diff函数,在第一行代码中要加入from sympy import diff。此外,diff()除了作为函数使用,还可以作为一个表达式的属性,如x(t)对t的四阶导数可以表示为x(t).diff(t).diff(t).diff(t).diff(t)

print (result)

#result=Eq(x(t), C1*exp(-t*sqrt(11 + sqrt(145))) + C2*exp(t*sqrt(11 + sqrt(145))) + C3*sin(t*sqrt(-11 + sqrt(145))) + C4*cos(t*sqrt(-11 + sqrt(145))))

#其次利用sympy.dsolve求解常微分方程组:

#代码

from sympy import Function, dsolve, Derivative, symbols, Eq

#from sympy.abc importt

t=symbols('t')

x, y=symbols('x, y', cls=Function)

#注意这里的x和y之间的逗号可以省略,即可以写成x, y=symbols('x y', cls=Function)。这行代码等效于x=Function('x')和y=Function('y')

eq=(Eq(Derivative(x(t),t, 2), 12*(x(t) + y(t))), Eq(Derivative(y(t),t, 2), 12*x(t) + 10*y(t)))

#注意这里使用了Eq()函数,所以在第一行导入了from sympy import Eq。Eq()函数内的逗号相当于是等于号,等号左边和右边分别为微分方程左边和右边的表达式,如对于本例的第一个微分方程,除了写成Eq(Derivative(x(t),t, 2),12*(x(t)+y(t)))外,还可以写成Eq(Derivative(x(t),t, 2)-12*(x(t)+y(t)), 0),注意这后面的0不能省略。

#同样地,对于第一个例子求解单个微分方程的情况,如果要使用Eq函数,则应该写成eq=Eq(Derivative(x(t), t, 4) - 22*Derivative(x(t), t, 2) - 24*x(t), 0)和result=dsolve(eq),并且要在第一行代码导入Eq函数。

#如果在该例中,我们不想使用Eq()函数,则上行代码应该写为eq=(Derivative(x(t), t, 2)-12*(x(t) + y(t)), Derivative(y(t), t, 2)- 12*x(t) - 10*y(t))

#简而言之就是,如果要使用Eq函数,则需要写成微分方程等号左右两边的表达式,当右边为0时,也需要写出来;如果不使用Eq函数,则只需要写出微分方程等号左边的表达式,此时等号右边应为0,且不需要写出来。

result=dsolve(eq)

print (result)

#result=[Eq(x(t), 12*C1*exp(t*CRootOf(l**4 - 22*l**2 - 24, 0)) + 12*C2*exp(t*CRootOf(l**4 - 22*l**2 - 24, 1)) + 12*C3*exp(t*CRootOf(l**4 - 22*l**2 - 24, 2)) + 12*C4*exp(t*CRootOf(l**4 - 22*l**2 - 24, 3))), Eq(y(t), C1*(-12 + CRootOf(l**4 - 22*l**2 - 24, 0)**2)*exp(t*CRootOf(l**4 - 22*l**2 - 24, 0)) + C2*(-12 + CRootOf(l**4 - 22*l**2 - 24, 1)**2)*exp(t*CRootOf(l**4 - 22*l**2 - 24, 1)) + C3*(-12 + CRootOf(l**4 - 22*l**2 - 24, 2)**2)*exp(t*CRootOf(l**4 - 22*l**2 - 24, 2)) + C4*(-12 + CRootOf(l**4 - 22*l**2 - 24, 3)**2)*exp(t*CRootOf(l**4 - 22*l**2 - 24, 3)))]

#CRootOf(表达式, i)应该就是“表达式=0”的第i+1个根(CRootOf(表达式, i)相当于会形成“表达式=0”的根的列表),这一点我还不确定,可以进一步讨论。至于为什么CRootOf中的表达式看着像数字,但却不直接计算出来而是写成式子的形式这一点,我的学Python比较好的同学说是为了语言的形式简便所以利用了表达式的形式,但是我觉得CRootOf中的表达式的I像是复数符号,这一点我还不确定,可以进一步讨论。

我们注意到其实第一个例子的单个微分方程就是第二个例子的微分方程组通过求导和互相代入得到的,因此第一个例子中求出来的x(t)应该和第二例子求出来的x(t)等价,有兴趣的可以验证这一点(应该会使用到欧拉方程exp(It)=cost+Isint,其中I为复数符号),这一点我还不确定,可以进一步讨论。

你可能感兴趣的:(python解常微分方程)