简体   繁体   English

在 Python 中求解一阶和二阶微分方程组

[英]Solving a system of first and second order differential equations in Python

I need to solve the following system of differential equations:我需要解决以下微分方程组:

$\frac{dx_1}{dt} = -k_1x_1+k_2x_2-(K_R)x_1y_1$
$\frac{dx_2}{dt} =  k_1x_1-k_2x_2-k_3x_2-(K_R)x_2y_2$
$\frac{dx_3}{dt} =  k_3x_3$
$\frac{dy_1}{dt} = -k_1y_1+k_2y_2-(K_R)x_1y_1$
$\frac{dy_2}{dt} =  k_1y_1-k_2y_2-k_3y_2-(K_R)x_2y_2$
$\frac{dy_3}{dt} =  k_3y_3$
$\frac{dz_1}{dt} = -k_1z_1+k_2z_2+(K_R)x_1y_1$
$\frac{dz_2}{dt} =  k_1z_1-k_2z_2-k_3z_2+(K_R)x_2y_2$
$\frac{dz_3}{dt} =  k_3z_3$

The initial conditions at t = 0, is x2 = 1. And at time t = 1, a compound y is introduced in y2 compartment, y2 = 10. The value of KR is 1e-3. t = 0 时的初始条件是 x2 = 1。在时间 t = 1 时,化合物 y 被引入 y2 隔室,y2 = 10。KR 的值为 1e-3。


I have solved a much simpler system using exponentiation of matrix, and was wondering whether it's possible to solve the above system using similar approach.我已经使用矩阵求幂解决了一个更简单的系统,并且想知道是否可以使用类似的方法解决上述系统。

I have a compartmental model system X, a simplified version of which, looks like this:我有一个分区模型系统 X,它的简化版本如下所示:

这个

The system of differential equations is then:那么微分方程组是:

下列

I can solve this system of equations using the following matrix approach.我可以使用以下矩阵方法求解这个方程组。

First, I write the rate matrix [R].首先,我写出速率矩阵 [R]。 From [R] one can obtain a new matrix [A] by first replacing each diagonal element of [R] by the negative of the sum of each of row elements, and then transposing it:从 [R] 可以通过首先将 [R] 的每个对角线元素替换为每个行元素之和的负数,然后对其进行转置来获得新矩阵 [A]:

在此处输入图片说明

I can calculate the amount in each compartment by doing the following:我可以通过执行以下操作来计算每个隔间中的数量:

在此处输入图片说明

In python:在蟒蛇中:

RMatrix = model_matrix.as_matrix()
row, col = np.diag_indices_from(RMatrix)
RMatrix[row, col] = -(RMatrix.sum(axis=1)-RMatrix[row,col])
AMatrix = RMatrix.T

def content(t):
    cont = np.dot(linalg.expm(t*AMatrix), x0))

This method is working well for me.这种方法对我来说效果很好。


The model above (the original question) is a little more complicated than just System X. In this model, reactants in compartments 1 and 2 of Systems X and Y combine to get product in System Z.上面的模型(原始问题)比系统 X 稍微复杂一些。在这个模型中,系统 X 和 Y 的隔室 1 和隔室 2 中的反应物结合起来得到系统 Z 中的产物。

X + Y --> Z, with a reaction constant of KR. X + Y --> Z,反应常数为 KR。

在此处输入图片说明

, and the corresponding system of differential equations would be: ,对应的微分方程组为:

在此处输入图片说明

I am struggling with a method to solve this system of differential equations (1st and 2nd order) to calculate the amount in each compartment at a certain time t, given the initial conditions, KR, and the transfer rates k1, k2, k3, etc...在给定初始条件、KR 和传输速率 k1、k2、k3 等的情况下,我正在努力寻找一种方法来解决这个微分方程系统(一阶和二阶),以计算在特定时间 t 每个隔间中的数量...

Can I solve it using the matrix method like the one above for a system of first order differential equations?对于一阶微分方程组,我可以使用上述矩阵方法解决它吗? What other options in Python do I have?我在 Python 中还有哪些其他选择?

Thanks in advance!提前致谢!

Well, as pointed out in the comments, your (more complicated) ODE is nonlinear.好吧,正如评论中指出的那样,您的(更复杂的)ODE 是非线性的。 Therefore, a matrix exponential approach will not work anymore.因此,矩阵指数方法将不再适用。

In general, there are two general approaches to solving ODEs.通常,有两种解决 ODE 的通用方法。 First, you can try to find a symbolic solution.首先,您可以尝试找到一个象征性的解决方案。 In most cases, you follow some approach based on an educated guess.在大多数情况下,您遵循一些基于有根据的猜测的方法。 There are several types of ODEs for which symbolic solutions are known.有几种类型的 ODE,其符号解是已知的。

However, this is not the case for the vast majority of ODEs.但是,对于绝大多数 ODE 而言,情况并非如此。 Hence, we generally contend ourselves with a numeric solution, essentially numerically integrating the ODE based on the right hand side.因此,我们通常使用数值解来解决问题,本质上是对基于右手边的 ODE 进行数值积分。

The result is not an explicit function, but instead an approximation on the function values at certain point.结果不是显式函数,而是某个点的函数值的近似值。 In python, you can use scipy to solve ODEs this way.在python中,您可以使用scipy以这种方式解决ODE。 Based on your right hand side (barring any errors on my part), this would look something like this:根据你的右手边(除非我有任何错误),这看起来像这样:

import numpy as np

import scipy.integrate 

k_1 = 1
k_2 = 1
k_3 = 1
K_R = 1

def eval_f(v, t):
    [x, y, z] = np.split(v, [3, 6])

    return np.array([-k_1*x[0] +k_2*x[1] - (K_R)*x[0]*y[0],
                     k_1*x[0] - k_2*x[1] - k_3*x[1] - (K_R)*x[1]*y[1],
                     k_3*x[2],
                     - k_1*y[0] + k_2*y[1] - (K_R)*x[0]*y[0],
                     k_1*y[0] - k_2*y[1] - k_3*y[1] - (K_R)*x[1]*y[1],
                     k_3*y[2],
                     - k_1*z[0] + k_2*z[1] + (K_R)*x[0]*y[0],
                     k_1*z[0] - k_2*z[1] - k_3*z[1] + (K_R)*x[1]*y[1],
                     k_3*z[2]])

initial = np.array([1, 2, 3, 4, 5, 6, 7, 8, 9])

t = np.linspace(0, 1, 10)

values = scipy.integrate.odeint(eval_f, initial, t)

# variable x[0]
print(values[:,0])

This yields the following values of x1:这将产生 x1 的以下值:

[1.         0.70643591 0.49587121 0.35045691 0.25034256 0.1809533
 0.13237994 0.09800056 0.07338967 0.05557138]

based on the grid points基于网格点

[0.         0.11111111 0.22222222 0.33333333 0.44444444 0.55555556
 0.66666667 0.77777778 0.88888889 1.        ]

If you want to see how the function behaves, an integrator may be sufficient.如果您想查看函数的行为方式,积分器可能就足够了。 Otherwise, I would recommend reading up on symbolic approaches to ODEs in a text book...否则,我建议在教科书中阅读 ODE 的符号方法......

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM