简体   繁体   English

Python GEKKO ODE 错误结果

[英]Python GEKKO ODE wrong results

I've been trying to implement the Sedaghat model for simulation of the insulin signaling pathway, as it is presented here , using python's GEKKO .我一直在尝试使用 python 的GEKKO实现用于模拟胰岛素信号通路的Sedaghat模型,如此处所示。 The system modeled is the one without feedback and the model's equations and constants' values can be found in Appendix A. While the first 6 diagrams of my results seem to come out fine, the rest model states (x16-x21) seem a bit problematic (fig. 6,7 of the same paper used for comparison).建模的系统是没有反馈的系统,模型的方程和常数的值可以在附录 A 中找到。虽然我的结果的前 6 个图表看起来不错,但其余模型状态 (x16-x21) 似乎有点问题(用于比较的同一纸的图 6,7)。

I have checked the equations and constant values, tried adding lower and upper bounds to the variables and experimented with the m.options.IMODE and m.options.NODES parameters, but these didn't seem to help.我检查了方程和常数值,尝试为变量添加下限和上限,并尝试了m.options.IMODEm.options.NODES参数,但这些似乎没有帮助。

Any piece of advice would be much appreciated.任何建议将不胜感激。

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from gekko import GEKKO

def insulin_pathway_CM(insulin, time_interval): 

    m = GEKKO(remote=False)
    m.time = np.linspace(0, time_interval-1, time_interval)

    # initialization of variables 
    x1 = m.Param(value=insulin)
    x2 = m.Var(9*1e-13)
    x3 = m.Var()
    x4 = m.Var()
    x5 = m.Var()
    x6 = m.Var(1e-13)
    x7 = m.Var()
    x8 = m.Var()
    x9 = m.Var(1e-12)
    x10 = m.Var()
    x11 = m.Var(1e-13)
    x12 = m.Var()
    x13 = m.Var(0.0031)
    x14 = m.Var(0.994)
    x15 = m.Var(0.0029)
    x16 = m.Var(1)
    x17 = m.Var()
    x18 = m.Var(1)
    x19 = m.Var()
    x20 = m.Var(0.96)
    x21 = m.Var(0.04)
  
    # initialization of constants
    km1 = 0.2
    k1 = 6*1e7
    km2 = 100*km1
    k2 = k1
    km3 =  km1
    k3 = 2500
    km4 = 0.003
    k4 = km4/9
    km4a = 2.1*1e-4
    k4a = 2.1*1e-3
    km5 = 1.67*1e-18
    k5 = 10*km5    # simplification made after testing  
                   # x6 seems to be above 1e-13 for all values of interest
    k6 = 0.461
    k7 = 4.16
    km7 = (2.5/7.45)*k7
    km8 = 10
    k8 = km8 * (5/70.775) * 1e12
    km9 = (94/3.1)*1.39
    PI3K = 5*1e-15
    k9basal = (0.31/99.4)*km9
    k9 = m.Var() 
    m.Equation(k9 == (1.39 - k9basal)*(x12/PI3K) + k9basal)
    km10 = 2.77
    k10 = (3.1/2.9)*km10
    km11 = 6.9314718
    k11 = m.Var()
    m.Equation(k11 == (0.1*km11)*(x13-0.31)/2.79)
    km12 = 6.93147
    k12 = m.Var()
    m.Equation(k12 == (0.1*km12)*(x13-0.31)/2.79)
    km13 = 0.167
    k13 = (4/96)*km13
    km14 = 0.001155
    k14 = 96*km14
    
    Effect = m.Var()
    APequil = 100/11
    m.Equation(Effect == (0.2*x17 + 0.8*x19)/APequil)
    k13a = ((4/6) - (4/96))*km13*Effect
    
    SHIP = 1
    PTEN = 1
    PTP = 1
    IRp = 8.97*1e-13

    # equations
    m.Equation(x2.dt() == km1*x3 + km3*PTP*x5 - k1*x1*x2 + km4*x6 - k4*x2)
    m.Equation(x3.dt() == k1*x1*x2 - km1*x3 - k3*x3)
    m.Equation(x4.dt() == k2*x1*x5 -km2*x4 + km4a*x7 -k4a*x4)
    m.Equation(x5.dt() == k3*x3 + km2*x4 - k2*x1*x5 - km3*PTP*x5 + km4a*x8 - k4a*x5)
    m.Equation(x6.dt() == k5 - km5*x6 + k6*PTP*(x7 + x8) + k4*x2 - km4*x6)
    m.Equation(x7.dt() == k4a*x4 - km4a*x7 - k6*PTP*x7)
    m.Equation(x8.dt() == k4a*x5 - km4a*x8 - k6*PTP*x8)
    m.Equation(x9.dt() == km7*PTP*x10 - k7*x9*(x4+x5)/IRp)
    m.Equation(x10.dt() == k7*x9*(x4+x5)/IRp + km8*x12 - (km7*PTP + k8*x11)*x10)
    m.Equation(x11.dt() == km8*x12 - k8*x10*x11)
    m.Equation(x12.dt() == k8*x10*x11 - km8*x12)
    m.Equation(x13.dt() == k9*x14 + k10*x15 - (km9*PTEN + km10*SHIP)*x13)
    m.Equation(x14.dt() == km9*PTEN*x13 - k9*x14) 
    m.Equation(x15.dt() == km10*SHIP*x13 - k10*x15)
    m.Equation(x16.dt() == km11*x17 - k11*x16) 
    m.Equation(x17.dt() == k11*x16 - km11*x17)  
    m.Equation(x18.dt() == km12*x19 - k12*x18)  
    m.Equation(x19.dt() == k12*x18 - km12*x19)
    m.Equation(x20.dt() == km13*x21 - (k13 + k13a)*x20 + k14 - km14*x20)  
    m.Equation(x21.dt() == (k13 + k13a)*x20 - km13*x21) 
  
    m.options.IMODE = 7
    m.options.OTOL  = 1e-8
    m.options.RTOL  = 1e-8
    m.options.NODES = 3
    m.solve(disp=False)
  
    # plotting
    x45 = []
    for i in range(len(x4.value)):
        x45.append(x4[i]+x5[i])
  
    fig, axs = plt.subplots(4, 2, figsize=(20, 20))
    axs[0, 0].set_title('Free surface receptors (x2)')
    axs[0, 0].plot(m.time, x2)
    axs[0, 1].set_title('Once and twice bound phosphorylated receptors (x4:orange, x5:green)')
    axs[0, 1].plot(m.time, x4, 'tab:orange')
    axs[0, 1].plot(m.time, x5, 'tab:green')
    axs[1, 0].set_title('Surface phosphorylated receptors (x4 + x5)')
    axs[1, 0].plot(m.time, x45, 'tab:red')
    axs[1, 1].set_title('Unphosphorylated and tyrosine phosphorylated IRS-1 (x9:orange, x10:green)')
    axs[1, 1].plot(m.time, x9, 'tab:orange')
    axs[1, 1].plot(m.time, x10, 'tab:green')
    axs[2, 0].set_title('Activated PI 3-kinase (x12)')
    axs[2, 0].plot(m.time, x12, 'tab:orange')
    axs[2, 1].set_title('PI(3,4,5)P3 and PI(3,4,5)P2 (x13:orange, x15:green)')
    axs[2, 1].plot(m.time, x13, 'tab:orange')
    axs[2, 1].plot(m.time, x15, 'tab:green')
    axs[3, 0].set_title('Activated PKC-ζ (x19)')
    axs[3, 0].plot(m.time, x19, 'tab:red')
    axs[3, 1].set_title('Percentage of cell surface GLUT4 (x21)')
    axs[3, 1].plot(m.time, x21, 'tab:cyan')
    return

# input as in the paper
time_interval = 60
insulin = np.zeros(60)
insulin[:15] = 1e-7

insulin_pathway_CM(insulin, time_interval)

Here are a few suggestions:这里有一些建议:

  • Replace some of the states with Intermediate type.将某些状态替换为Intermediate类型。 This gives same solution but calculates faster.这给出了相同的解决方案,但计算速度更快。
    #k9 = m.Var() 
    #m.Equation(k9 == (1.39 - k9basal)*(x12/PI3K) + k9basal)
    k9 = m.Intermediate(1.39 - k9basal)*(x12/PI3K) + k9basal)
  • Add a few small time steps at the beginning in case of early fast dynamics that are not tracking well with time step of 1. This didn't have an effect, but it is a good thing to try.在开始时添加一些小时间步长,以防早期快速动态在时间步长为 1 时跟踪不佳。这没有效果,但尝试一下是件好事。
    m = GEKKO(remote=False)
    t = np.linspace(0, time_interval-1, time_interval)
    m.time = np.insert(t,1,[1e-5,1e-4,1e-3,1e-2,0.1])
    insulin = np.insert(insulin,1,[insulin[0]]*5)
  • Investigate any non-intuitive solutions such x17 and x19 as negative numbers.调查任何非直观的解决方案,如x17x19作为负数。

Equations for x16 to x21 do not appear to influence other parts of the model and the only input is k11 that is also dependent on x13 , x14 , and x15 . x16x21的方程似乎不会影响模型的其他部分,唯一的输入是k11 ,它也依赖于x13x14x15

    km11 = 6.9314718
    k11 = m.Intermediate((0.1*km11)*(x13-0.31)/2.79)
    m.Equation(x13.dt() == k9*x14 + k10*x15 - (km9*PTEN + km10*SHIP)*x13)
    m.Equation(x14.dt() == km9*PTEN*x13 - k9*x14) 
    m.Equation(x15.dt() == km10*SHIP*x13 - k10*x15)

    m.Equation(x16.dt() == km11*x17 - k11*x16) 
    m.Equation(x17.dt() == k11*x16 - km11*x17)  
    m.Equation(x18.dt() == km12*x19 - k12*x18)  
    m.Equation(x19.dt() == k12*x18 - km12*x19)
    m.Equation(x20.dt() == km13*x21 - (k13 + k13a)*x20 + k14 - km14*x20)  
    m.Equation(x21.dt() == (k13 + k13a)*x20 - km13*x21) 

There may be a model error in those equations, possibly even in the original paper (it sometimes happens).这些方程中可能存在模型错误,甚至可能在原始论文中(有时会发生)。 Focusing on pairs x16 and x17 , it appears that x17 is just the change in x16 .着眼于x16x17对,看来x17只是x16的变化。 This is similar for x18 and x19 .这与x18x19类似。 At first glance, I couldn't see any obvious differences in the equations between the Python source code and the paper.乍一看,我看不出 Python 源代码和论文之间的方程式有任何明显差异。

结果 x16-x21

论文结果

Here is the complete script with some changes with Intermediates, 2 plots added, and the additional time points at the beginning.这是完整的脚本,其中包含中间体的一些更改,添加了 2 个图,以及开始时的附加时间点。

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
from gekko import GEKKO

def insulin_pathway_CM(insulin, time_interval): 

    m = GEKKO(remote=False)
    t = np.linspace(0, time_interval-1, time_interval)
    m.time = np.insert(t,1,[1e-5,1e-4,1e-3,1e-2,0.1])
    print(m.time)
    insulin = np.insert(insulin,1,[insulin[0]]*5)

    # initialization of variables 
    x1 = m.Param(value=insulin)
    x2 = m.Var(9*1e-13)
    x3 = m.Var()
    x4 = m.Var()
    x5 = m.Var()
    x6 = m.Var(1e-13)
    x7 = m.Var()
    x8 = m.Var()
    x9 = m.Var(1e-12)
    x10 = m.Var()
    x11 = m.Var(1e-13)
    x12 = m.Var()
    x13 = m.Var(0.0031)
    x14 = m.Var(0.994)
    x15 = m.Var(0.0029)
    x16 = m.Var(1)
    x17 = m.Var()
    x18 = m.Var(1)
    x19 = m.Var()
    x20 = m.Var(0.96)
    x21 = m.Var(0.04)
  
    # initialization of constants
    km1 = 0.2
    k1 = 6*1e7
    km2 = 100*km1
    k2 = k1
    km3 =  km1
    k3 = 2500
    km4 = 0.003
    k4 = km4/9
    km4a = 2.1*1e-4
    k4a = 2.1*1e-3
    km5 = 1.67*1e-18
    k5 = 10*km5    # simplification made after testing  
                   # x6 seems to be above 1e-13 for all values of interest
    k6 = 0.461
    k7 = 4.16
    km7 = (2.5/7.45)*k7
    km8 = 10
    k8 = km8 * (5/70.775) * 1e12
    km9 = (94/3.1)*1.39
    PI3K = 5*1e-15
    k9basal = (0.31/99.4)*km9
    k9 = m.Intermediate((1.39 - k9basal)*(x12/PI3K) + k9basal)
    km10 = 2.77
    k10 = (3.1/2.9)*km10
    km11 = 6.9314718
    k11 = m.Intermediate((0.1*km11)*(x13-0.31)/2.79)
    km12 = 6.93147
    k12 = m.Intermediate((0.1*km12)*(x13-0.31)/2.79)
    km13 = 0.167
    k13 = (4/96)*km13
    km14 = 0.001155
    k14 = 96*km14
    
    APequil = 100/11
    Effect = m.Intermediate((0.2*x17 + 0.8*x19)/APequil)
    k13a = ((4/6) - (4/96))*km13*Effect
    
    SHIP = 1
    PTEN = 1
    PTP = 1
    IRp = 8.97*1e-13

    # equations
    m.Equation(x2.dt() == km1*x3 + km3*PTP*x5 - k1*x1*x2 + km4*x6 - k4*x2)
    m.Equation(x3.dt() == k1*x1*x2 - km1*x3 - k3*x3)
    m.Equation(x4.dt() == k2*x1*x5 -km2*x4 + km4a*x7 -k4a*x4)
    m.Equation(x5.dt() == k3*x3 + km2*x4 - k2*x1*x5 - km3*PTP*x5 + km4a*x8 - k4a*x5)
    m.Equation(x6.dt() == k5 - km5*x6 + k6*PTP*(x7 + x8) + k4*x2 - km4*x6)
    m.Equation(x7.dt() == k4a*x4 - km4a*x7 - k6*PTP*x7)
    m.Equation(x8.dt() == k4a*x5 - km4a*x8 - k6*PTP*x8)
    m.Equation(x9.dt() == km7*PTP*x10 - k7*x9*(x4+x5)/IRp)
    m.Equation(x10.dt() == k7*x9*(x4+x5)/IRp + km8*x12 - (km7*PTP + k8*x11)*x10)
    m.Equation(x11.dt() == km8*x12 - k8*x10*x11)
    m.Equation(x12.dt() == k8*x10*x11 - km8*x12)
    m.Equation(x13.dt() == k9*x14 + k10*x15 - (km9*PTEN + km10*SHIP)*x13)
    m.Equation(x14.dt() == km9*PTEN*x13 - k9*x14) 
    m.Equation(x15.dt() == km10*SHIP*x13 - k10*x15)
    m.Equation(x16.dt() == km11*x17 - k11*x16) 
    m.Equation(x17.dt() == k11*x16 - km11*x17)  
    m.Equation(x18.dt() == km12*x19 - k12*x18)  
    m.Equation(x19.dt() == k12*x18 - km12*x19)
    m.Equation(x20.dt() == km13*x21 - (k13 + k13a)*x20 + k14 - km14*x20)  
    m.Equation(x21.dt() == (k13 + k13a)*x20 - km13*x21) 
  
    m.options.IMODE = 7
    m.options.OTOL  = 1e-10
    m.options.RTOL  = 1e-10
    m.options.NODES = 3
    m.solve(disp=False)
  
    # plotting
    x45 = []
    for i in range(len(x4.value)):
        x45.append(x4[i]+x5[i])
  
    fig, axs = plt.subplots(4, 2, figsize=(20, 20))
    axs[0, 0].set_title('Free surface receptors (x2)')
    axs[0, 0].plot(m.time, x2)
    axs[0, 1].set_title('Once and twice bound phosphorylated receptors (x4:orange, x5:green)')
    axs[0, 1].plot(m.time, x4, 'tab:orange')
    axs[0, 1].plot(m.time, x5, 'tab:green')
    axs[1, 0].set_title('Surface phosphorylated receptors (x4 + x5)')
    axs[1, 0].plot(m.time, x45, 'tab:red')
    axs[1, 1].set_title('Unphosphorylated and tyrosine phosphorylated IRS-1 (x9:orange, x10:green)')
    axs[1, 1].plot(m.time, x9, 'tab:orange')
    axs[1, 1].plot(m.time, x10, 'tab:green')
    axs[2, 0].set_title('Activated PI 3-kinase (x12)')
    axs[2, 0].plot(m.time, x12, 'tab:orange')
    axs[2, 1].set_title('PI(3,4,5)P3 and PI(3,4,5)P2 (x13:orange, x15:green)')
    axs[2, 1].plot(m.time, x13, 'tab:orange')
    axs[2, 1].plot(m.time, x15, 'tab:green')
    axs[3, 0].set_title('Activated PKC-ζ (x19)')
    axs[3, 0].plot(m.time, x19, 'tab:red')
    axs[3, 1].set_title('Percentage of cell surface GLUT4 (x21)')
    axs[3, 1].plot(m.time, x21, 'tab:cyan')
    
    plt.figure()
    for ni in range(16,22):
        nx = 'x'+str(ni); x = eval(nx)
        plt.subplot(3,2,ni-15)
        plt.plot(m.time,x.value,label=nx); plt.legend()

    plt.figure()
    plt.subplot(2,1,1)
    plt.plot(m.time,k11.value,label='k11')
    plt.subplot(2,1,2)
    plt.plot(m.time,x13.value,label='x13')

    return

# input as in the paper
time_interval = 60
insulin = np.zeros(60)
insulin[:15] = 1e-7

insulin_pathway_CM(insulin, time_interval)

plt.show()

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

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