Python 使用完整矩阵在scipy中模拟ode(对象对于所需阵列来说太深)

Python 使用完整矩阵在scipy中模拟ode(对象对于所需阵列来说太深),python,numpy,scipy,ode,Python,Numpy,Scipy,Ode,在m*m矩阵S中有一个微分方程组。S[I,j]是一个特定的物种浓度,受S[I-1,j]和S[I,j-1]的影响 我可以在每一步得到每个条目的dx/dt(由update_矩阵返回),但我需要将其积分以更新我的初始浓度(x与x_计数相同)。但是,scipy的integrate.odeint不接受矩阵作为输入(或返回值),并引发对象太深的错误 有什么办法可以调整它来使用矩阵上的积分器吗?我提供了一段代码:diffeq为每个条目返回dx/dt。update_矩阵返回矩阵B,其中B[I.j]=dx[I,j

在m*m矩阵S中有一个微分方程组。S[I,j]是一个特定的物种浓度,受S[I-1,j]和S[I,j-1]的影响

我可以在每一步得到每个条目的dx/dt(由update_矩阵返回),但我需要将其积分以更新我的初始浓度(x与x_计数相同)。但是,scipy的integrate.odeint不接受矩阵作为输入(或返回值),并引发对象太深的错误

有什么办法可以调整它来使用矩阵上的积分器吗?我提供了一段代码:diffeq为每个条目返回dx/dt。update_矩阵返回矩阵B,其中B[I.j]=dx[I,j]/dt

def diffeq(x,i,j,coeffs):
    if (i==1 and j==0):
        return (-(coeffs.M(1,0)-coeffs.L(1,0)))+coeffs.d(1,0)-coeffs.get_phi()*x[1][0]
    elif j==0:
        return (-(coeffs.M(i,0)+coeffs.L(i,0)))*x[i][0]+coeffs.L(i-1,0)*x[i-1][0]+coeffs.d(i,j)-coeffs.get_phi()*x[i][0]
    elif (i>1 and j>0):
        return (-(coeffs.M(i,j)+coeffs.L(i,j)))*x[i][j]+coeffs.M(i,j-1)*x[i][j-1]+coeffs.L(i-1,j)*x[i-1][j]+coeffs.d(i,j)-coeffs.get_phi()*x[i][j]
    elif i==1 and j>0:
        return (-(coeffs.M(1,j)+coeffs.L(1,j)))*x[1][j]+coeffs.M(1,j-1)*x[1][j-1]+coeffs.d(1,j)-coeffs.get_phi()*x[1][j]
    elif i==0 and j==1:
        return -x[0][1]+coeffs.d(0,1)-coeffs.get_phi()*x[0][1]
    elif i==0 and j>1:
        return -j*x[0][j]+(j-1)*x[0][j-1]+coeffs.d(0,j)-coeffs.get_phi()*x[0][j]


def update_matrix(x,coeffs,m):
    update_matrix=numpy.zeros((m,m))
    for i in range(m+1):
        for j in range(m+1-i):
            update_matrix[m][m]=diffeq(x,i,j,coeffs)
    return update_matrix


def run_simulation_R2(a,q,m):

    x_counts=numpy.zeros((m,m))
    x_counts[1][0]=1
    x_counts[0][1]=1
    coeffs=R2(a,q,m,x_counts)
    t=range(0,100)
    output = integrate.odeint(update_matrix, x_counts, t, args=(coeffs, m))

如果
odeint
需要一个向量,而不是一个矩阵,你就必须给它一个向量。如果你不想把代码的逻辑改变太多,你可以通过自由地应用
.reforme(-1),使
x
成为一个
(m**2,)
函数外的向量,但函数内仍然是
(m,m)
矩阵
任何地方都需要。您没有提供足够的信息对其进行全面测试,但类似的方法可能会奏效:

def update_matrix(x,coeffs,m):
    x = x.reshape(m, m)
    update_matrix=numpy.zeros((m,m))
    for i in range(m+1):
        for j in range(m+1-i):
            update_matrix[m][m]=diffeq(x,i,j,coeffs)
    return update_matrix.reshape(-1)

def run_simulation_R2(a,q,m):
    x_counts=numpy.zeros((m,m))
    x_counts[1][0]=1
    x_counts[0][1]=1
    coeffs=R2(a,q,m,x_counts)
    t=range(0,100)
    output = integrate.odeint(update_matrix, x_counts.reshape(-1), t,
                              args=(coeffs, m))
    return output.reshape(m, m)

是的,我使用了一种类似的方法,我在更新矩阵和运行模拟之间创建了一个接口,因此每次都会对矩阵进行展平和重塑,这确实解决了问题。fyi:我创建了一个名为
odeint
的包装器,用于处理矩阵微分方程: