SymPy/SciPy:求解具有不同变量的常微分方程组 [英] SymPy/SciPy: solving a system of ordinary differential equations with different variables
问题描述
我通常对SymPy和Python还是陌生的,目前我正在使用Python 2.7和SymPy 0.7.5,目标是: a)从文本文件中读取微分方程组 b)解决系统
I am new to SymPy and Python in general, and I am currently working with Python 2.7 and SymPy 0.7.5 with the objective to: a) read a system of differential equations from a text file b) solve the system
我已经阅读了这个问题和其他问题,它们几乎是我正在寻找的东西,但是我还有一个问题:我事先不知道方程组的形式,所以我无法创建相应的函数在脚本内使用def
,如此示例 .整个事情必须在运行时进行管理.
I already read this question and this other question, and they are almost what I am looking for, but I have an additional issue: I do not know in advance the form of the system of equations, so I cannot create the corresponding function using def
inside the script, as in this example. The whole thing has to be managed at run-time.
因此,这是我的代码的一些摘要.假设我有一个包含以下内容的文本文件 system.txt :
So, here are some snippets of my code. Suppose I have a text file system.txt containing the following:
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可读的函数,例如:
At this point, I am stuck with the two symbolic expressions inside the systemOfEquation list. Provided that I can read the initial conditions for the ODE system from another file, in order to use scipy.integrate.odeint
, I would have to convert the system into a Python-readable function, something like:
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)
Is there a nice way to create this at run-time? For example, write the function to another file and then import the newly created file as a function? (maybe I am being stupid here, but remember that I am relatively new to Python :-D)
我已经看到,使用sympy.utilities.lambdify.lambdify
可以将符号表达式转换为lambda函数,但是我想知道这是否对我有帮助... lambdify当时似乎只适用于一个表达式,而不适用于系统.
I've seen that with sympy.utilities.lambdify.lambdify
it's possible to convert a symbolic expression into a lambda function, but I wonder if this can help me...lambdify seems to work with one expression at the time, not with systems.
预先感谢您的任何建议:-)
Thank you in advance for any advice :-)
通过最少的修改,沃伦的答案就完美地发挥了作用.我在 listOfSymbols 中有所有符号的列表;此外,它们以与odeint将使用的数据 X 列相同的顺序出现.所以,我使用的功能是
With minimal modifications, Warren's answer worked flawlessly. I have a list of all symbols inside listOfSymbols; moreover, they appear in the same order as the columns of data X that will be used by odeint. So, the function I used is
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]
在我的特定问题中,我只是将变量时间"设为例外.再次感谢! :-)
I just make an exception for the variable 'time' in my specific problem. Thanks again! :-)
推荐答案
如果要使用读取文件的同一脚本来解决系统(因此systemOfEquations
可作为全局变量使用),并且<在systemOfEquations
中使用的仅em 变量是x
,y
以及可能的t
,您可以像这样在同一文件中定义dX_dt
:
If you are going to solve the system in the same script that reads the file (so systemOfEquations
is available as a global variable), and if the only variables used in systemOfEquations
are x
, y
and possibly t
, you could define dX_dt
in the same file like this:
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
的脚本:
dX_dt
can be used in odeint
. In the following ipython session, I have already run the script that creates systemOfEquations
and defines 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]]
这篇关于SymPy/SciPy:求解具有不同变量的常微分方程组的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!