我正在尝试使用来自scipy的odeint()
解决耦合ODE的以下问题。系统看起来像这样:
X'_k =平均值(Y_k)+ F
Y'_ {k,j} = X_k-Y_ {k,j}
这是一个具有3个X变量的系统,对于每个X变量,还有其他3个Y变量。
根据我从文档以及示例here和here中所获得的信息,我可以将方程组作为列表传递。这就是我在以下示例中尝试的内容:
import numpy as np
from scipy.integrate import odeint
def dZdt(Z, t):
X = Z[0]
Y = Z[1]
F = 4
d_x = np.zeros(3)
d_y = np.zeros(3*3).reshape(3,3)
# Compute the Y values
for k in range(3):
for j in range(3):
d_y[k][j] = X[k] - Y[k][j]
# X values
d_x[k] = Y[k].mean() + F
d = [d_x, d_y]
return d
# Initial conditions
X0 = np.random.uniform(size=3)
Y0 = np.random.uniform(size = 3*3).reshape(3,3)
Z0 = [X0, Y0]
t = range(20)
Z = odeint(dZdt, Z0, t)
其中k,j =(1,2,3)和Z = [X,Y]
但恐怕会出现以下错误:
ValueError: could not broadcast input array from shape (3,3) into shape (3)
我的实际问题更加复杂,因为j和k可能大于3(它们分别从1到j_max和K_max),所以我不能一一写出12个变量。
我的猜测是,在代码中的某处,试图将Y变量填充为X形状...但是不知道在哪里。
有什么想法我做错了吗?
答案 0 :(得分:2)
您试图通过列表内的两个数组来表示未知函数。它必须是一维数组。因此,必须是12个变量的固定列表,而不是3个X变量和9个Y变量。像这样:
def dZdt(Z, t):
X = Z[:3]
Y = Z[3:].reshape(3, 3)
F = 4
d_x = np.zeros(3)
d_y = np.zeros((3, 3))
# Compute the Y values
for k in range(3):
for j in range(3):
d_y[k, j] = X[k] - Y[k, j]
# X values
d_x[k] = Y[k].mean() + F
d = np.concatenate((d_x.ravel(), d_y.ravel()))
return d
# Initial conditions
X0 = np.random.uniform(size=3)
Y0 = np.random.uniform(size=(3, 3))
Z0 = np.concatenate((X0.ravel(), Y0.ravel()))
t = range(20)
Z = odeint(dZdt, Z0, t)
NumPy数组索引为Y[k, j]
,而不是Y[k][j]
。并且有足够的矢量化机会可以消除dZdt
的计算中的循环。像这样:
def dZdt(Z, t):
X = Z[:3]
Y = Z[3:].reshape(3, 3)
F = 4
d_y = X[:, None] - Y
d_x = Y.mean(axis=1) + F
d = np.concatenate((d_x.ravel(), d_y.ravel()))
return d