我正在尝试用python可视化振荡器系统。只要其中一个变量没有积累(使用dirac delta函数),系统就可以工作。但是,当我试图包含它时,系统似乎没有任何变化。在下面你可以找到我所经历的过程和我的一些问题。在
我用python编写了一些代码,能够正确地可视化常规的振荡器行为。然而,当在其中一个变量中包含逐步递增时,系统不会对此作出反应。下面,您可以找到包含增量的版本。代码运行,但给出的输出就好像不存在增量一样。在这段代码下,你可以找到我在获得正确解决方案方面的问题。在
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
a4 = 5.68
aAPD = 9.09
deltaZ = 0.41
gamma = 1.33
negV = 1
n=500
def f(V):
if V<=-60:
return V/20 + 4
elif V>=20:
return V/20 - 1
else:
return -V/80 + 1/4
def alpha(V):
if V<0:
return a4
else:
return -aAPD
def g(q):
return q/(q+1)
def step(V):
global negV
if V>0 and negV == 1:
negV = 0
return deltaZ
elif V<=0 and negV == 0:
negV = 1
return 0
else:
return 0
# function that returns dz/dt
def model(z,t):
V = z[0]
y = z[1]
q = z[2]
dVdt = 25000*(y - f(V))
dydt = alpha(V) - a4*g(q)
dqdt = -gamma*g(q) + step(V)
dzdt = [dVdt,dydt,dqdt]
return dzdt
# initial condition
z0 = [0,0,0]
# time points
t = np.linspace(0,0.5,n)
# solve ODE
z = odeint(model,z0,t)
# plot results
plt.plot(t,z[:,0],label='Voltage')
plt.plot(t,z[:,1],label='y')
plt.plot(t,z[:,2],label='Z')
plt.ylabel('response')
plt.xlabel('time')
plt.legend(loc='best')
plt.show()
问题出在函数step(V)
。振荡器在某一时刻与值V=0相交。此时,q的值应该以deltaZ递增。在
在python的odesolver中有几点我不理解或不知道如何访问正确的值。因此,这里有一个简短的问题清单:
if V[i]>0 and V[i-1]<0: return deltaZ
的语句,那就更好了。这些信息应该可以在某处找到,因为你最后画出了V的值,但是我不知道如何才能访问V之前的值我最好能解决这三个问题,但如果你能给出其中一个的答案,我也会得到很多帮助。在
我强烈建议在scipy中使用
solve_ivp
函数,使用一个事件来检测V=0
交叉。见here。在如果使用终端事件,则解决方案将精确地在
V=0
处停止。然后,您可以使用您的即时更改更新ODE集成器外部的解决方案,并将其用作第二次调用solve_ivp
以完成集成的初始条件。我假设V=0
的交叉只发生一次,但是您可以构建逻辑来处理事件的多个交叉。在相关问题 更多 >
编程相关推荐