3 回答

TA貢獻1808條經驗 獲得超4個贊
問題在于來自spring(y,t,par)
odeint
期望從 中返回 2 個單值,而是在 中獲取單個值,然后在 中獲取一個長度數組。ydot[0]
ydot[1]
spring()
ydot[0]
len(F)
ydot[1]
改變
ydot[1] = F / m - c * y[1] / m - k * y[0] / m
自
ydot[1] = F[0] / m - c * y[1] / m - k * y[0] / m
并檢查發生了什么。

TA貢獻1886條經驗 獲得超2個贊
將值數組傳遞給導數函數,而沒有任何方法將其條目與函數的計算時間相關聯,這是完全錯誤的。請記住,參數 和 是狀態向量和(單個標量)時間,求解器需要計算數值方法中的下一階段。最簡單的方法是作為函數傳遞,以便可以直接計算其值。FtytF
def spring(y,t,par):
m,k,c,F = par
return [ y[1], F(t)/m-c*y[1]/m-k*y[0]/m ]
#cases:[ti,tf,x0,xdot0,c]
A=[0.0,0.3,0.1,0.0,37.7]
B=[0.0,3.0,0.0,1.0,37.7]
C=[0.0,3.0,0.1,1.0,377]
D=[0.0,5.0,0.0,0.0,37.7]
E=[0.0,3.0,0.0,0.0,37.7]
cases = [A, B, C, D, E] #0,1,2,3,4
m=10.0
k=3553.0
h = 0.01
使用元組賦值來解壓縮參數元組更具有詩意味,在一行中完成以前分布在多個參數上的內容,也使參數的順序更加可見。
刪除一些不必要的并發癥,例如具有額外的計數機制,請使用該機制。此外,不要使用顯式構造的參數列表,因為在可選參數中臨時構造它要容易得多(如果有數百個系統構造的條目,這將有所不同)。enumerate(list)parargs
在常規設置中,可能是使用 中的方法生成的插值函數。在這里,將給定的方程轉換為lambda表達式以定義相應的標量函數就足夠了。Fscipy.interpolate
for cont,case in enumerate(cases):
ti,tf,x0,xdot0,c = case
y = [x0,xdot0]
t = np.arange(ti, tf, h)
F = lambda t: 0
if cont == 3:
F = lambda t: 1000*np.sin(np.pi*t+np.pi/2)
elif (cont == 4):
F = lambda t: 1000 if t >= 0.5 else 0
Y = ode(spring,y,t,args=([m,k,c,F],))
Xn,Vn = Y.T
graph.figure(figsize=(9,3))
graph.subplot(1,3,1); graph.plot(t,Xn)
graph.subplot(1,3,2); graph.plot(t,Vn)
graph.subplot(1,3,3); graph.plot(Xn,Vn)
graph.tight_layout(); graph.show()
其他一切都像以前一樣進行,使用子圖將不同的圖形組合在一張圖片中。例如,第 4 個示例給出了混沌振蕩的結果

TA貢獻1859條經驗 獲得超6個贊
在修復問題后,當您嘗試運行時,代碼中還會出現其他問題。但為了準確起見,我將回答你的問題。
問題出在以下代碼行中:
ydot[1] = F/m-c*y[1]/m-k*y[0]/m
此處的 F 當前作為列表提供。在數學中,如果將向量除以標量,則假定您執行元素除法。Python 列表不會復制這種行為,但麻木數組會復制。因此,只需將您的列表轉換為numpy數組,如下所示:
F = np.array(F)
ydot[1] = F/m-c*y[1]/m-k*y[0]/m
添加回答
舉報