我正在尝试解决由 N = 400个神经元组成的网络的动力学问题。
这意味着我有400个符合下列规则的耦合方程:
i = 0,1,2 ... 399
J(i,j)= i和j的某些函数(其中j是伪变量)
I(i)= i的某些功能
dr(i,t)/ dt = -r(i,t)+ j上的总和从0到399 [J(i,j)* r(j)] + I(i)
我该如何解决?
我知道对于3节点的系统。我定义了3个ode和初始条件,然后应用odeint。在这种情况下是否有更好的执行方法?
到目前为止,我尝试了以下代码(因为它进入了无限循环,所以效果不好):
N=400
t=np.linspace(0,20,1000)
J0=0.5
J1=2.5
I0=0.5
I1=0.001
i=np.arange(0,400,1)
theta=(2*np.pi)*i/N
I=I0+I1*cos(theta)
r=np.zeros(400)
x0 = [np.random.rand() for ii in i]
def threshold(y):
if y>0:
return y
else:
return 0
def vectors(x,t):
for ii in i:
r[ii]=x[ii]
for ii in i:
drdt[ii] = -r[ii] + threshold(I[ii]+sum(r[iii]*(J0+J1*cos(theta[ii]-theta[iii]))/N for iii in i))
return drdt
x=odeint(vectors,x0,t)
答案 0 :(得分:3)
做出我认为是对您的代码的明显更正和添加之后,我得以运行它。它实际上并不是无限循环的,只是非常缓慢。通过尽可能“向量化”计算,可以大大提高性能。这允许使用C代码而不是Python计算循环。表达式sum over j from 0 to 399[J(i,j)*r(j)]
暗示了很多改进的余地。这是表示矩阵J与向量r的乘积的另一种方式。因此,我们应该在代码中真正使用J @ r
之类的东西,而不是所有那些显式的Python循环。
再进行一些调整后,这是代码的修改版本。它比原始速度快得多。我也进行了一些重组,并添加了剧情。
import numpy as np
from scipy.integrate import odeint
import matplotlib.pyplot as plt
def computeIJ(N):
i = np.arange(N)
theta = (2*np.pi)*i/N
I0 = 0.5
I1 = 0.001
I = I0 + I1*np.cos(theta)
J0 = 0.5
J1 = 2.5
delta_theta = np.subtract.outer(theta, theta)
J = J0 + J1*np.cos(delta_theta)
return I, J / N
def vectors2(r, t, I, J):
s = J @ r
drdt = -r + np.maximum(I + s, 0)
return drdt
N = 400
I, J = computeIJ(N)
np.random.seed(123)
r0 = np.random.rand(N)
t = np.linspace(0, 20, 1000)
r = odeint(vectors2, r0, t, args=(I, J))
for i in [0, 100, 200, 300, 399]:
plt.plot(t, r[:, i], label='i = %d' % i)
plt.xlabel('t')
plt.legend(shadow=True)
plt.grid()
plt.show()
这是脚本生成的图: