Python:使用odeint实现阈值模型

Python:使用odeint实现阈值模型,python,differential-equations,threshold,numerical-integration,Python,Differential Equations,Threshold,Numerical Integration,我正在处理的问题(所示示例高度简化)似乎是一个常见问题,但我还没有找到解决方案。我有三种不同的反应,v1,v2和v3,它们的定义如下: def thresholdmodel (yn,tvec,allpara,R): (A, B, C, P) = yn k1, k2, k3 = allpara['kv'] Cthr = allpara['Cthresh'] if C <= Cthr: v3 = 0 else:

我正在处理的问题(所示示例高度简化)似乎是一个常见问题,但我还没有找到解决方案。我有三种不同的反应,v1,v2和v3,它们的定义如下:

def thresholdmodel (yn,tvec,allpara,R):

    (A, B, C, P) = yn

    k1, k2, k3 = allpara['kv']    

    Cthr = allpara['Cthresh']

    if C <= Cthr:
        v3 = 0
    else:      
        v3 = k3*A*B
        C = 0 #does not(!) affect the ouput, why?

    v1 = k1*(R - A*C/5000.)
    v2 = k2*(R - B*C/5000.)

    dA = v1 - v3
    dB = v2 - v3
    dC = v1 + v2
    dP = v3

    return (dA, dB, dC, dP) 
v1:ra+C;v1=k1*(R-A*C/5000)

v2:rb+C;v2=k2*(R-B*C/5000)

v3:A+B->p;v3=k3*A*B

使用资源R,前两个反应分别产生a和C以及B和C,而第三个反应将a和B转化为产物p(k1、k2、k3为常数,此处设置为1)

第三个反应假定仅在C超过称为Cthr的特定阈值(此处:Cthr=25)时发生,否则v3为0。所以这个想法是C积累,一旦达到一定浓度,就会产生产物P

我实施了以下措施:

def thresholdmodel (yn,tvec,allpara,R):

    (A, B, C, P) = yn

    k1, k2, k3 = allpara['kv']    

    Cthr = allpara['Cthresh']

    if C <= Cthr:
        v3 = 0
    else:      
        v3 = k3*A*B
        C = 0 #does not(!) affect the ouput, why?

    v1 = k1*(R - A*C/5000.)
    v2 = k2*(R - B*C/5000.)

    dA = v1 - v3
    dB = v2 - v3
    dC = v1 + v2
    dP = v3

    return (dA, dB, dC, dP) 
def阈值模型(yn、tvec、allpara、R): (A,B,C,P)=yn k1,k2,k3=所有参数['kv'] Cthr=所有段落['Cthresh']
如果C我不理解你的方程,但我可以告诉你为什么
C
没有降到0

由于
C
thresholdmodel()
中的局部变量,因此将
C
更改为任何值都不会更改
odeint
中的状态
odeint
将始终集成
thresholdmodel()
返回的
dC
。因此
C
将持续增加

编辑:

C将持续增加,因此每次C>threshold时都需要更改阈值,例如:

lastC = 0

def thresholdmodel (yn,tvec,allpara,R):
    global lastC
    (A, B, C, P) = yn

    k1, k2, k3 = allpara['kv']    

    Cthr = allpara['Cthresh']

    if C <= lastC + Cthr:
        v3 = 0
    else:      
        v3 = k3*A*B
        lastC = C

    v1 = k1*(R - A*C/5000.)
    v2 = k2*(R - B*C/5000.)

    dA = v1 - v3
    dB = v2 - v3
    dC = v1 + v2
    dP = v3

    return (dA, dB, dC, dP) 
lastC=0
def阈值模型(yn、tvec、allpara、R):
全球lastC
(A,B,C,P)=yn
k1,k2,k3=所有参数['kv']
Cthr=所有段落['Cthresh']

如果C Ok,非常感谢您的快速回复!好吧,这只是一个玩具的例子来说明我的问题。你到底不明白什么?只有简单的质量作用动力学,没有什么特别的。因此,感谢您澄清问题!你知道一个可行的方法来解决它吗?我不知道和->是什么意思。如果代码中的C可以通过C=0降到0,那么v3将几乎是0,只有当C==0时才是k3*A*B。这是你的意图吗?再次感谢你的回复表示反应是可逆的(双向的),“->”表示反应是不可逆的(只有一个方向)。几乎所有小于阈值(Cthr)的Cs的v3都是零。一旦达到该阈值,v3变为k3*A*B,并且可以产生P。之后C再次设置为零,因此v3变为零,再次建立C,直到下次达到阈值,依此类推。但是,由于C只是一个局部变量,正如您所指出的,似乎很难在总体输出中将其设置为零。有什么建议可以解决这个问题吗?我在答案中添加了一个可能的解决方案,请检查。谢谢,我没有看到。我检查了它:当我打印v3时,它总是为零,除了C超过阈值的时间点:到目前为止还不错。但是P仍然是0,它不会增加,尽管dP大于0(等于v3)。这个问题似乎很简单,但显然不是。也许我必须使用手工实现的龙格库塔积分器。那么,按照预期的方式操作C应该很容易,但我仍然更喜欢使用内置函数。无论如何,非常感谢你的评论和建议!