我有一個龐大(> 2000方程)的ODE系統,我想用python scipy的odeint解決。如何從文本文件中讀取微分方程組來解決scipy.odeint的系統問題?
我有三個問題,我想解決(也許我會問3個不同的問題?)。 爲了簡單起見,我會在這裏用玩具模型來解釋它們,但請記住我的系統很大。 假設我有ODE的以下系統:
dS/dt = -beta*S
dI/dt = beta*S - gamma*I
dR/dt = gamma*I
使用β= C p我
,其中C,P和γ是我想傳遞給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],))
我產生了數學的文本文件,說myOdes.txt,其中文件的每一行對應於我的ODE系統的RHS,所以看起來像這樣
#myODEs.txt
-beta*S*I
beta*S*I - gamma*I
- gamma*I
我的文本文件看起來類似於odeint的期望,但我還沒有完成。 我有三個主要問題:
- 我怎樣才能把我的文本文件,以便odeint明白,這是我的系統的RHS?
- 如何以一種智能的方式,即系統地定義我的變量?由於它們有2000多個,我不能手動定義它們。理想情況下,我會在一個單獨的文件中定義它們,並讀取它們。
- 如何將參數(也有很多)作爲文本文件傳遞?
我讀this question接近於我的問題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函數中定義參數(取決於變量)?
在此先感謝!
感謝您的回答。 – Laura
感謝您的回答。我同意,不使用sympy會更快更好,因爲我已經將我的方程式的格式與odeint所期望的幾乎相同,所以它對我沒有多大意義。事實上,我之前所擁有的甚至都沒有工作:( 我知道我可以在不使用任何變量的情況下定義myOdes,並直接用向量y寫出eqs,但是我有超過2000個變量,並且根據術語編寫eqs y是非常麻煩和容易出錯的,這就是爲什麼我想寫變量的eqs並傳遞一個表格的列表: S = X [0],I = X [1]等 – Laura