我是SymPy和Python的新手,我目前正在使用Python 2.7和SymPy 0.7.5,其目标是: a)从文本文件中读取微分方程组 b)解决系统问题
我已经阅读了this question和this other question,而且他们几乎我正在寻找什么,但我还有一个问题:我事先并不知道表格方程组,所以我无法在脚本中使用def
创建相应的函数,如this example中所示。整个过程必须在运行时进行管理。
所以,这里是我的代码的一些片段。假设我有一个文本文件 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似乎可以使用一个表达式当时,而不是系统。
提前感谢您的任何建议: - )
编辑:
经过极少的修改,沃伦的答案完美无瑕。我有 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'做了一个例外。在我的具体问题。再次感谢! : - )
答案 0 :(得分:4)
如果要在读取文件的同一脚本中解析系统(因此systemOfEquations
可用作全局变量),并且{{> 变量仅用于{{ 1}}是systemOfEquations
,x
,可能是y
,您可以在同一个文件中定义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
中使用。在下面的ipython会话中,我已经运行了创建odeint
的脚本并定义了systemOfEquations
:
dX_dt