SymPy/SciPy:求解含不同变量的常微分方程组

6 投票
1 回答
3958 浏览
提问于 2025-04-18 01:08

我刚接触SymPy和Python,正在用Python 2.7和SymPy 0.7.5做一些事情,目标是:
a) 从文本文件中读取一个微分方程组
b) 解这个方程组

我已经看过这个问题另一个问题,它们几乎是我想要的,但我还有一个额外的问题:我不知道方程组的具体形式,所以不能像这个例子那样在脚本里用def创建相应的函数。所有的事情都必须在运行时处理。

所以,这里是我代码的一些片段。假设我有一个文本文件system.txt,里面包含以下内容:

dx/dt = 0.0387*x - 0.0005*x*y
dy/dt = 0.0036*x*y - 0.1898*y

我做的事情是:

# imports
import sympy
import scipy
import re as regex

# define all symbols I am going to use
x = sympy.Symbol('x')
y = sympy.Symbol('y')
t = sympy.Symbol('t')

# read the file
systemOfEquations = []
with open("system.txt", "r") as fp :
   for line in fp :
            pattern = regex.compile(r'.+?\s+=\s+(.+?)$')
            expressionString = regex.search(pattern, line) # first match ends in group(1)   
            systemOfEquations.append( sympy.sympify( expressionString.group(1) ) )

到目前为止,我在systemOfEquation列表里的两个符号表达式上卡住了。假设我可以从另一个文件中读取微分方程组的初始条件,为了使用scipy.integrate.odeint,我需要把这个方程组转换成Python能读的函数,像这样:

def dX_dt(X, t=0):
return array([ 0.0387*X[0] - 0.0005*X[0]*X[1] ,
              -0.1898*X[1] + 0.0036*X[0]*X[1] ])

有没有什么好的方法在运行时创建这个?比如,把函数写到另一个文件里,然后把新创建的文件作为函数导入?(也许我在这里有点傻,但请记住我对Python还比较陌生 :-D)

我看到用sympy.utilities.lambdify.lambdify可以把符号表达式转换成lambda函数,但我在想这能不能帮到我……lambdify似乎一次只能处理一个表达式,而不是处理整个系统。

提前谢谢任何建议 :-)

编辑:

经过最小的修改,Warren的回答完美地解决了我的问题。我在listOfSymbols里有了所有符号的列表;而且,它们的顺序和将被odeint使用的数据X的列顺序是一样的。所以,我用的函数是

def dX_dt(X, t):
    vals = dict()
    for index, s in enumerate(listOfSymbols) :
            if s != time :
                    vals[s] = X[index]
    vals[time] = t
    return [eq.evalf(subs=vals) for eq in systemOfEquations]

我只是对我特定问题中的变量'time'做了个例外。再次感谢! :-)

1 个回答

4

如果你打算在读取文件的同一个脚本中解决这个系统(这样systemOfEquations就可以作为全局变量使用),而且在systemOfEquations中使用的变量只有xy,可能还有t,那么你可以在同一个文件中这样定义dX_dt

def dX_dt(X, t):
    vals = dict(x=X[0], y=X[1], t=t)
    return [eq.evalf(subs=vals) for eq in systemOfEquations]

dX_dt可以在odeint中使用。在下面的ipython会话中,我已经运行了创建systemOfEquations并定义dX_dt的脚本:

In [31]: odeint(dX_dt, [1,2], np.linspace(0, 1, 5))
Out[31]: 
array([[ 1.        ,  2.        ],
       [ 1.00947534,  1.90904183],
       [ 1.01905178,  1.82223595],
       [ 1.02872997,  1.73939226],
       [ 1.03851059,  1.66032942]]

撰写回答