簡體   English   中英

使用forloop求解python中的耦合微分方程

[英]Using a forloop to solve coupled differential equations in python

我正在嘗試求解一組微分方程,但我一直難以完成這項工作。 我的微分方程包含一個“i”下標,表示從 1 到 n 的數字。 我嘗試按如下方式實現 forloop,但我一直收到此索引錯誤(錯誤消息如下)。 我曾嘗試更改初始條件 (y0) 和其他值,但似乎沒有任何效果。 在此代碼中,我使用的是 solve_ivp。 代碼如下:

import numpy as np
import matplotlib.pyplot as plt
%matplotlib inline
from scipy.integrate import solve_ivp

def testmodel(t, y):
    X = y[0]
    Y = y[1]
    J = y[2]
    Q = y[3]
    a = 3
    S = 0.4
    K = 0.8
    L = 2.3
    n = 100 
    for i in range(1,n+1):
        dXdt[i] = K**a+(Q[i]**a) - S*X[i]
        dYdt[i] = (K*X[i])-(L*Y[i])
        dJdt[i] = S*Y[i]-(K*Q[i])
        dQdt[i] = K*X[i]/L+J[i]
        return dXdt, dYdt, dJdt, dQdt
t_span= np.array([0, 120])
times = np.linspace(t_span[0], t_span[1], 1000) 
y0 = 0,0,0,0
soln = solve_ivp(testmodel, t_span, y0, t_eval=times, 
vectorized=True)
t = soln.t
X = soln.y[0]
Y = soln.y[1]
J = soln.y[2]
Q = soln.y[3]

plt.plot(t, X,linewidth=2, color='red')
plt.show()    

我得到的錯誤是

IndexError                Traceback (most recent call last)
<ipython-input-107-3a0cfa6e42ed> in testmodel(t, y)
     15     n = 100
     16     for i in range(1,n+1):
 --> 17     dXdt[i] = K**a+(Q[i]**a) - S*X[i]
   
 IndexError: index 1 is out of bounds for axis 0 with size 1

我已經分散了 web 來解決這個問題,但我一直無法對這個問題應用任何解決方案。 我不確定我做錯了什么以及實際要改變什么。

我試圖刪除“vectorized=True”參數,但隨后收到一條錯誤消息,指出我無法索引標量變量。 這令人困惑,因為我認為這些值不應該是標量。 我如何解決這個問題,我的最終目標是plot這些微分方程。 先感謝您。

很高興您為標准求解器提供矢量化 ODE function 以進行多點計算。 但默認方法是顯式 RK45,顯式方法不使用雅可比矩陣。 因此不需要對偏導數的差商進行多點求值。

本質上,坐標 arrays 的大小始終為 1,因為評估是在單個點進行的,因此例如Q是一個長度為 1 的數組,唯一有效的索引是 0。請記住,在所有“真正的”編程語言中,數組索引從 0 開始。只有一些 CAS 腳本語言使用“更數學”的 1 作為索引開始。 (設置n=100並忽略求解器提供的 arrays 的長度也是錯誤的。)

你可以避免所有這些並通過考慮到標准算術運算是按元素應用 numpy arrays 來縮短你的例程,所以

def testmodel(t, y):
    X,Y,J,Q = y
    a = 3; S = 0.4; K = 0.8; L = 2.3
    dXdt = K**a + Q**a - S*X
    dYdt = K*X - L*Y
    dJdt = S*Y - K*Q
    dQdt = K*X/L + J
    return dXdt, dYdt, dJdt, dQdt

使用相同的動態修改多個隔間的代碼

您需要將 state 的平面向量傳遞給求解器。第一個設計決策是如何在平面向量中排列隔間及其組件。 與現有代碼最兼容的一種變體是將相同的組件聚集在一起。 然后在 ODE function 中,第一個操作是分離出這些簇。

    X,Y,J,Q = y.reshape([4,-1])

這會將輸入向量分成 4 個等長的片段。 最后,您需要扭轉這種分裂,以便導數再次處於平面向量中。

    return np.concatenate([dXdt, dYdt, dJdt, dQdt])

其他一切都保持不變。 除了初始向量,它需要有 4 個長度為N的片段,其中包含隔間的數據。 這可能只是

    y0 = np.zeros(4*N)

如果初始數據來自任何其他來源,並且以每個隔間的記錄為單位,則您可能必須在展平之前轉置結果數組。

請注意,此構造矢量化,因此請將該選項的默認值False保留為未設置。

對於像圓圈這樣的統一交互模式,我建議使用numpy.roll來繼續避免使用顯式循環。 對於看起來像 a.network 的交互模式,可以使用連接矩陣和掩碼,如Using python built-in functions for coupled ODEs

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM