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

Python SymPy/SciPy:求解具有不同变量的常微分方程组,python,numpy,scipy,sympy,differential-equations,Python,Numpy,Scipy,Sympy,Differential Equations,我对Symphy和Python基本上是新手,目前正在使用Python 2.7和Symphy 0.7.5,目标是: a) 从文本文件中读取微分方程组 b) 解系统 我已经读过和,它们几乎就是我想要的,但我还有一个问题:我事先不知道方程组的形式,所以我无法在脚本中使用def创建相应的函数,如中所示。整个过程必须在运行时进行管理 下面是我的一些代码片段。假设我有一个包含以下内容的文本文件system.txt: dx/dt = 0.0387*x - 0.0005*x*y dy/dt = 0.0036*x

我对Symphy和Python基本上是新手,目前正在使用Python 2.7和Symphy 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列表中的两个符号表达式中。如果我可以从另一个文件中读取ODE系统的初始条件,为了使用
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似乎在同一时间使用一个表达式,而不是系统

提前感谢您的建议:-)

编辑:

只要稍加修改,沃伦的答案就完美无瑕。我在符号列表中列出了所有符号;此外,它们与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”做了一个例外。再次感谢!:-)

如果您要在读取文件的同一脚本中求解系统(因此
systemOfEquations
可用作全局变量),并且如果
systemOfEquations
中使用的唯一变量是
x
y
,可能还有
t
,您可以在同一文件中定义
dX\u 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\u dt
可在
odeint
中使用。在接下来的ipython会话中,我已经运行了创建
systemOfEquations
并定义
dX\u 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]]

“我事先不知道方程组的形式”:变量是否总是在
system.txt
中被称为
x
y
?总是只有两个方程式吗?如果没有,将调用哪些附加变量?为了进一步澄清,我知道所涉及符号的所有名称(我将从另一个文件中读取它们),而系统中的方程式数量可能会有所不同。此外,从下面的这个和沃伦的回答中,我开始看到一种模式;我可以从包含数据的文件中构建一个字典,使用列的名称作为符号,然后尝试Warren的解决方案。