因此,我的教授要求我创建一个程序,该程序将使用Runge-Kutta方法(二阶)来解决该问题。但是我得到一个IndexError:列表索引超出范围,这可以回到我的第一个函数。我不完全了解这是什么错误,如果有人向我解释了该错误,我将很高兴
import numpy as np
def f(a, rec, inf, j, b, q):
f = b*(1-inf[j]-rec[j])*(a[j][0]*inf[0]+a[j][1]*inf[1]+a[j][2]*inf[2]+a[j][3]*inf[3]+a[j][4]*inf[4]+a[j][5]*inf[5]+a[j][6]*inf[6]+a[j][7]*inf[7]+a[j][8]*inf[8]+a[j][9]*inf[9]) - q*inf[j]
return f
def rk2a(I, R, b, q):
beta = b
sigma = q
I.astype(float)
R.astype(float)
n = len(I)
S = 1 - I - R
A = np.array([[0,1,1,1,0,0,0,0,0,0],
[1,0,1,1,1,0,0,0,0,0],
[1,1,0,1,1,1,0,0,0,0],
[1,1,1,0,1,1,1,0,0,0],
[0,1,1,1,0,1,1,1,0,0],
[0,0,1,1,1,0,1,1,1,0],
[0,0,0,1,1,1,0,1,1,1],
[0,0,0,0,1,1,1,0,1,0],
[0,0,0,0,0,1,1,1,0,1],
[0,0,0,0,0,0,1,0,1,0]])
y_coef = []
old_I = []
for i in range(0,50,1):
print(I.transpose())
for j in range(0,n-1,1):
k1 = f(A,R,I,j,beta,sigma)
y_coef.append(I[j])
old_I.append(I[j])
y_coef[j] = I[j]+(k1/2)
k2 = f(A, R, y_coef, j, beta, sigma)
I[j] = old_I[j] + k2
return None
infect = np.array([0, 1, 0, 0, 0, 0, 0, 1, 0, 0])
recov = np.array([0,0, 0, 0, 0, 0, 0, 0, 0, 0])
rk2a(infect, recov, 0.3, 0.1)
答案 0 :(得分:0)
尝试运行:
def f(a, rec, inf, j, b, q):
print('---- DEBUG -----')
print('a', a, 'rec', rec, 'inf', inf, 'j', j, 'b', b, 'q', q, sep="\n")
print('---------------')
f = b*(1-inf[j])*(a[j][0]*inf[0]+a[j][1]*inf[1]+a[j][2]*inf[2]+a[j][3]*inf[3]+a[j][4]*inf[4]+a[j][5]*inf[5]+a[j][6]*inf[6]+a[j][7]*inf[7]+a[j][8]*inf[8]+a[j][9]*inf[9]) - q*inf[j]
return f
您错误地传递了 inf 数组...
答案 1 :(得分:0)
完全省略索引。所有的numpy数组算术运算都是逐单元进行的。线性代数矩阵向量乘积是numpy.dot
或数组的.dot
方法。所以你可以重写
def f(inf, rec, A,b,q)
susc = 1-inf-rec # computes the susceptibles in every node
trans = b*susc*A.dot(inf) # newly infected in time span
recov = q*inf # recovered in time span
return trans-recov, recov
然后迭代
for t in time[:-1]:
k1i, k1r = f(inf,rec,A,b,q)
k2i, k2r = f(inf+k1i*dt/2,rec+k1r*dt/2,A,b,q)
inf, rec = inf + k2i*dt, rec+k2r*dt
I.append(inf); R.append(rec);