两个多变量耦合ODE的系统

时间:2018-10-09 14:30:37

标签: python scipy odeint

我正在尝试使用来自scipy的odeint()解决耦合ODE的以下问题。系统看起来像这样:

  

X'_k =平均值(Y_k)+ F

     

Y'_ {k,j} = X_k-Y_ {k,j}

这是一个具有3个X变量的系统,对于每个X变量,还有其他3个Y变量。

根据我从文档以及示例herehere中所获得的信息,我可以将方程组作为列表传递。这就是我在以下示例中尝试的内容:

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形状...但是不知道在哪里。

有什么想法我做错了吗?

1 个答案:

答案 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