簡體   English   中英

使用dopri5繪制矩陣形式的ODE系統

[英]Using dopri5 to plot a system of ODEs in matrix form

我對繪圖感興趣的方程組如下:

在此處輸入圖片說明

通過執行以下操作,我能夠繪制出他們修改的示例的圖:

import scipy as sp
import pylab as plt
import numpy as np
import scipy.integrate as spi

#Constants
c13 = 4.2
c14 = 4.2
c21 = 4.3
c32 = 4.4
c34 = 4.4
c42 = 4.4
c43 = 4.4

e12 = 1.9
e23 = 2.5
e24 = 2.2
e31 = 2.0
e41 = 2.0

#Time
t_end = 700
t_start = 0
t_step = 1
t_interval = sp.arange(t_start, t_end, t_step)

#Initial Condition
r = [0.2,0.3,0.3,0.5]

def model(t,r):
    Eqs= np.zeros((4))
    Eqs[0] = (r[0]*(1-r[0]*r[0]-r[1]*r[1]-r[2]*r[2]-r[3]*r[3])-c21*((r[1]*r[1])*r[0])+e31*((r[2]*r[2])*r[0])+e41*((r[3]*r[3])*r[0]))
    Eqs[1] = (r[1]*(1-r[0]*r[0]-r[1]*r[1]-r[2]*r[2]-r[3]*r[3])+e12*((r[0]*r[0])*r[1])-c32*((r[2]*r[2])*r[1])-c42*((r[3]*r[3])*r[1]))
    Eqs[2] = (r[2]*(1-r[0]*r[0]-r[1]*r[1]-r[2]*r[2]-r[3]*r[3])-c13*((r[0]*r[0])*r[2])+e23*((r[1]*r[1])*r[2])-c43*((r[3]*r[3])*r[2]))
    Eqs[3] = (r[3]*(1-r[0]*r[0]-r[1]*r[1]-r[2]*r[2]-r[3]*r[3])-c14*((r[0]*r[0])*r[3])+e24*((r[1]*r[1])*r[3])-c34*((r[2]*r[2])*r[3]))
    return Eqs

ode =  spi.ode(model)

ode.set_integrator('dopri5')
ode.set_initial_value(r,t_start)
ts = []
ys = []

while ode.successful() and ode.t < t_end:
    ode.integrate(ode.t + t_step)
    ts.append(ode.t)
    ys.append(ode.y)

t = np.vstack(ts)
x1,x2,x3,x4 = np.vstack(ys).T

plt.subplot(1, 1, 1)
plt.plot(t, x1, 'r', label = 'x1')
plt.plot(t, x2, 'b', label = 'x2')
plt.plot(t, x3, 'g', label = 'x3')
plt.plot(t, x4, 'purple', label = 'x4')
plt.xlim([0,t_end])
plt.legend()
plt.ylim([-0.2,1.5])

plt.show()

這肯定給了我想要的情節。 但是,我最終要用這組ODE進行隨機分析,因此,如果以矩陣形式編寫ODE系統,則建模起來會容易得多(這樣,我可以輕松地更改ODE的維數。噪聲,並查看如何影響ODE)。 我了解數學上如何以矩陣形式編寫方程式,但是我不了解如何修改代碼,因此在“ def model(t,r):”部分中,將其讀取為數組/矩陣。 要將等式轉換為矩陣形式,我可以定義:

b = np.array([1, 1, 1, 1]) 
A = np.array([[1, 1+c21, 1-e31, 1-e41], 
              [1-e12, 1, 1+c32, 1+c42],
              [c13+1, 1-e23, 1, 1+c43],
              [c14+1, 1-e24, 1+c34, 1]])

然后方程組將是(其中x是向量(x1,x2,x3,x4)):

x(t)= diag(x)[b ^ {T} -Adiag(x)x]

所以我的問題是:如何修改定義ODE的位置,以便我可以將它們輸入為矩陣而不是單獨寫出每個方程式? (如果以后再查看具有4個以上維度的系統,這也將變得更加容易)

使用實現的numpy.array操作首選項以元素方式起作用(與以矩陣方式操作的numpy.matrix操作相反),方程組的公式很簡單

def model(t,x):
    return x*(b-A.dot(x*x))

x*x產生元素方平方的向量, x**2是另一個選擇, A.dot(x2)numpy.array對象執行矩陣向量乘積, x*(b-...)為再次是兩個操作數向量的向量值逐元素積。


使用u=x*x作為變量將系統簡化為

dotu = 2*u*(b-A.dot(u))

因此,它的度數小1,並且平方度u ,這可能有助於檢查靜止點。 我懷疑它們都是雙曲線的,因此沒有漸近穩定的解決方案。


使用替換u=log(x)並因此

dotu = b-A.dot(exp(2*u))

在負無窮大處隱藏靜止點,因此此替換的分析值可能會受到限制。 但是, x=exp(u)是內置的,這可以允許使用更積極的數值方法,或者使用與以前相同的謹慎性提供更高的精度。

暫無
暫無

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

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