在python(odeint)中求解具有时间相关系数的常微分方程

Posted

技术标签:

【中文标题】在python(odeint)中求解具有时间相关系数的常微分方程【英文标题】:solve ordinary differential equation with time dependent coefficients in python (odeint) 【发布时间】:2017-11-18 13:03:13 【问题描述】:

我想使用 scipy 的 odeint 函数求解具有 15 个时间相关系数的 7 个常微分方程 (ODE) 系统。

我将系数存储在字典中,以便我可以通过定义为与 odeint() 一起使用的函数 (func) 中的键名访问它们。系数取决于时间,因此在每个系数的字典中我调用函数 time_dep(t)。但是,由于我的字典存储在 odeint() 使用的函数之外,所以我在开始时初始化了一个时间变量 t = 0。现在我担心当 odeint() 分析访问这些系数时,它们会保持不变(在 t = 0 时)。

任何帮助将不胜感激!

这是一个最小工作示例的尝试,它并不完美,但我打印出系数值并且它没有改变,这是我不想要的:):

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint

t = 0 

def time_dep(t):
    return (10 * np.exp(-t))

coefficients = 'coeff1' : 1 + time_dep(t)

def func(state, t, coefficients):
    mrna    = state[0]
    protein = state[1]
    dt_mrna = coefficients['coeff1'] * mrna * protein
    dt_protein = coefficients['coeff1'] * protein
    print(coefficients['coeff1'])
    return[dt_mrna,dt_protein]

state0 = [1,1]
t = np.arange(0,100,0.1)

solve = odeint(func,state0,t,args=(coefficients,))
plt.plot(t,solve)
plt.show()

【问题讨论】:

【参考方案1】:

您已将单个数字1 + time_dep(0) 存储为coefficients['coeff1'] 的值。而不是这样做,将函数本身存储在字典中,并在func() 中调用函数。像这样的:

coefficients = 'coeff1' : time_dep

def func(state, t, coefficients):
    mrna    = state[0]
    protein = state[1]
    c1 = 1 + coefficients['coeff1'](t)
    dt_mrna = c1 * mrna * protein
    dt_protein = c1 * protein
    return [dt_mrna, dt_protein]

【讨论】:

【参考方案2】:

字典应该包含函数而不是评估值(就像现在一样):

coefficients = 'coeff1' : lambda x: 1+time_dep(x)

然后稍后获取函数并以正确的时间调用:

dt_mrna = coefficients['coeff1'](t) * mrna * protein

【讨论】:

不错的答案。在您看来,除了使用 lambda 来避免附加函数之外,还有什么特别的理由使用字典而不只是定义相关函数并从 func() 内部调用它们?

以上是关于在python(odeint)中求解具有时间相关系数的常微分方程的主要内容,如果未能解决你的问题,请参考以下文章

用 scipy odeint 在 python 中求解向量常微分方程

通过 Python 并行求解具有大量初始条件的 ODE

如何用Python求解微分方程组

python 的scipy 里的 odeint 这个求微分方程的函数怎么用啊

python中具有无限初始条件的ODE

在python中求解微分方程组