我有一个大型(>2000 个方程)ODE 系统,我想用 python scipy 的 odeint 来求解。
我有三个问题想要解决(也许我需要问 3 个不同的问题?)。
为了简单起见,我将在这里用一个玩具模型来解释它们,但请记住我的系统很大。
假设我有以下 ODE 系统:
dS/dt = -beta*S
dI/dt = beta*S - gamma*I
dR/dt = gamma*I
β = cpI
其中 c、p 和 gamma 是我要传递给 odeint 的参数。
odeint 期待这样的文件:
def myODEs(y, t, params):
c,p, gamma = params
beta = c*p
S = y[0]
I = y[1]
R = y[2]
dydt = [-beta*S*I,
beta*S*I - gamma*I,
- gamma*I]
return dydt
然后可以像这样传递给 odeint :
myoutput = odeint(myODEs, [1000, 1, 0], np.linspace(0, 100, 50), args = ([c,p,gamma], ))
我在 Mathematica 中生成了一个文本文件,例如 myOdes.txt,其中文件的每一行对应于我的 ODE 系统的 RHS,所以它看起来像这样
#myODEs.txt
-beta*S*I
beta*S*I - gamma*I
- gamma*I
我的文本文件看起来与 odeint 所期望的类似,但我还没有完全实现。
我有三个主要问题:
- 如何传递我的文本文件以便 odeint 理解这是我系统的 RHS?
- 如何以智能的方式(即系统的方式)定义我的变量?由于它们的数量超过 2000 个,我无法手动定义它们。理想情况下,我会将它们定义在一个单独的文件中并读取它。
- 我如何也将参数(有很多)作为文本文件传递?
I read 这个问题这与我的问题 1 和 2 很接近,并尝试复制它(我直接输入参数值,这样我就不必担心上面的第 3 点):
systemOfEquations = []
with open("myODEs.txt", "r") as fp :
for line in fp :
systemOfEquations.append(line)
def dX_dt(X, t):
vals = dict(S=X[0], I=X[1], R=X[2], t=t)
return [eq for eq in systemOfEquations]
out = odeint(dX_dt, [1000,1,0], np.linspace(0, 1, 5))
但我收到错误:
odepack.error: Result from function call is not a proper array of floats.
ValueError: could not convert string to float: -((12*0.01/1000)*I*S),
编辑:我将代码修改为:
systemOfEquations = []
with open("SIREquationsMathematica2.txt", "r") as fp :
for line in fp :
pattern = regex.compile(r'.+?\s+=\s+(.+?)$')
expressionString = regex.search(pattern, line)
systemOfEquations.append( sympy.sympify( expressionString) )
def dX_dt(X, t):
vals = dict(S=X[0], I=X[1], R=X[2], t=t)
return [eq for eq in systemOfEquations]
out = odeint(dX_dt, [1000,1,0], np.linspace(0, 100, 50), )
这是可行的(我不太明白 for 循环的前两行在做什么)。但是,我希望更自动地定义变量的过程,并且我仍然不知道如何使用此解决方案并在文本文件中传递参数。同样,如何在 dX_dt 函数内定义参数(取决于变量)?
提前致谢!