[英]Python plotting using dopri5
我的目标是绘制以下一组耦合的ODE:
odeint方法给我带来了问题(例如某些x_i呈现负值,而解析上不会发生),因此我决定使用四阶Runge-Kutta求解器。 我在下面的示例中使用dopri5方法(对scipy.integrate.ode 使用自适应步长 ):
import scipy as sp
import pylab as plt
import numpy as np
import scipy.integrate as spi
#Constants
c13 = 6.2
c14 = 1.0
c21 = 7.3
c32 = 2.4
c34 = 12.7
c42 = 5.7
c43 = 5.0
e12 = 1.5
e23 = 2.5
e24 = 2.0
e31 = 3.0
e41 = 4.8
#Time
t_end = 700
t_start = 0
t_step = 1
t_interval = sp.arange(t_start, t_end, t_step)
#Initial Condition
ic = [0.2,0.3,0.3,0.5]
def model(t,ic):
Eqs= np.zeros((4))
Eqs[0] = (ic[0]*(1-ic[0]*ic[0]-ic[1]*ic[1]-ic[2]*ic[2]-ic[3]*ic[3])-c21*((ic[1]*ic[1])*ic[0])+e31*((ic[2]*ic[2])*ic[0])+e41*((ic[3]*ic[3])*ic[0]))
Eqs[1] = (ic[1]*(1-ic[0]*ic[0]-ic[1]*ic[1]-ic[2]*ic[2]-ic[3]*ic[3])+e12*((ic[0]*ic[0])*ic[1])-c32*((ic[2]*ic[2])*ic[1])-c42*((ic[3]*ic[3])*ic[1]))
Eqs[2] = (ic[2]*(1-ic[0]*ic[0]-ic[1]*ic[1]-ic[2]*ic[2]-ic[3]*ic[3])-c13*((ic[0]*ic[0])*ic[2])+e23*((ic[1]*ic[1])*ic[2])-c43*((ic[3]*ic[3])*ic[2]))
Eqs[3] = (ic[3]*(1-ic[0]*ic[0]-ic[1]*ic[1]-ic[2]*ic[2]-ic[3]*ic[3])-c14*((ic[0]*ic[0])*ic[3])+e24*((ic[1]*ic[1])*ic[3])-c34*((ic[2]*ic[2])*ic[3]))
return Eqs
ode = spi.ode(model)
ode.set_integrator('dopri5')
ode.set_initial_value(ic,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.3])
plt.show()
生成以下图:
但是,我的图有一些奇怪的地方– x1值似乎随机上升到1以上。因为(1,0,0,0)是动力系统的固定点,所以对我而言,这没有多大意义峰值超过一个(可能是峰值显示某种重复模式的原因,但在图中它们看起来是随机的,所以我想知道这是否与数字积分有关而不是与实际动态)。 更改参数也会更改尖峰(我尝试过的某些参数值仍然有尖峰,但要小得多)。 因此,我有两个问题:
1)是什么导致这些尖峰出现? 我最初的想法是“ t_step”很大,所以我尝试使用它(这使我想到了第二个问题)
2)我尝试将步长从1更改为0.1。 但是,它生成了该图,实际上看起来与步长为1时有很大不同(我认为较低的步长会生成更精确的图?)在此图中,似乎每个x_i花费接近1的时间比如果步长是1而不是0.1,并且尖峰的高度都相等-考虑到这些图之间存在实质性差异,我如何知道哪个图对真实系统更准确?
我正在研究的问题的真正症结在于查找x3和x4之间的交互,但是我想确保正确设置了仿真,以便可以得到关于x3和x4的准确结果!
通过Gronwall引理,“好” ODE的误差传播由以Lipschitz常数L
为因子的指数控制。 这意味着在时刻发生的任何地方误差贡献t
得到(可能)通过的因子放大exp(L(Tt))
在时间T
。
慷慨的可以为您的系统使用L=10
。 在10
的时间间隔内,这会得出exp(100)=2.688e+43
的误差放大倍率,或者数值与初始值和精确解的总解耦。
因此,令人惊讶的是,直到t=80
为止,两个解决方案的相似性都得以保留。
关于理论的注释,尖峰:没有限制变量保持在区间[0,1]内或具有某些守恒量的相同效果的任何限制。 最好的办法是使用Ljapunov函数,例如V(x)=sum(x*x)
,该V(x)=sum(x*x)
然后给出将解限制在两个球体之间的界限。
这些不动点都是双曲的,雅可比行列是秩不足且无迹的,不包括稳定的不动点。 然后,尖峰只是这些双曲线点的稳定和不稳定歧管/轴方向的结果。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.