简体   繁体   English

使用 GEKKO 进行参数估计

[英]Parameters estimation with GEKKO

I have the enzymatic reaction:我有酶促反应:

R+L<->Y R+L<->Y

R+I<->X R+I<->X

Describes by the following system of coupled differential equations:由以下耦合微分方程系统描述:

  • dR/dt=k2 Y(t)-k1 R(t) L(t)+k4 X(t)-k3*R(t)*I(t) dR/dt=k2 Y(t)-k1 R(t) L(t)+k4 X(t)-k3*R(t)*I(t)
  • dL/dt=k2 Y(t)-k1 R(t)*L(t) dL/dt=k2 Y(t)-k1 R(t)*L(t)
  • dI/dt=k4 X(t)-k3 R(t)*I(t) dI/dt=k4 X(t)-k3 R(t)*I(t)
  • dY/dt=k1*R(t) L(t)-k2 Y(t) dY/dt=k1*R(t) L(t)-k2 Y(t)
  • dX/dt=k3*R(t) I(t)-k4 X(t) dX/dt=k3*R(t) I(t)-k4 X(t)

I have 4 set of data for Y, one per concentration of I, measured at the same time.我有 4 组 Y 数据,每个 I 浓度一个,同时测量。 I want to estimate k3 and k4 through non-linnear regression with all data using Gekko.我想通过非线性回归估计 k3 和 k4 使用 Gekko 的所有数据。 This is my code:这是我的代码:

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

#4 sets of data for Y with same tame and differente concentrations
texp=[0.0001,0.5,0.75,1,1.25,2,2.77,3.55,4.32,5.1,5.87,6.65,7.42,8.2,8.97,13.92,18.92,23.92,28.92,33.92,38.92,43.92,48.92,53.92,58.92,63.92,68.92,83.9,98.9,113.9,128.9,143.9,158.9,173.9,188.9,203.9,218.9,233.9,248.9]
yexp=[[0,134.0972365,101.6778993,95.40580822,77.46417317,97.38426357,94.95124669,92.01743212,103.1524256,101.6335581,100.8064012,97.36957339,98.54218566,105.1649371,100.7135276,91.76116765,98.50303784,99.09282871,101.2884698,98.16682444,98.95862295,100.1781904,97.67407619,98.05420149,101.7811854,99.65343296,99.35574195,101.5667478,97.8827634,99.21928788,100.2506635,103.3401759,97.77635857,95.59188964,97.63152972,98.68365575,97.94605393,94.40686956,101.4638065],
      [0,52.8368317,60.63226219,57.1596205,77.40224428,76.59558061,83.08583996,92.71540378,92.74825352,97.77466238,87.90927062,91.55955552,93.40910581,97.38680721,98.68892712,96.28587494,97.24139983,99.14913748,97.05786666,99.52031603,98.25378711,98.45507123,98.48665412,96.58596306,98.49718892,97.03260859,97.78876552,96.96130531,96.16927889,99.05385817,99.81984318,98.34275219,97.06707695,98.13554762,96.40027439,97.02992383,97.92157304,97.45153492,100.7723151],
      [0,6.651270535,-0.894974357,28.70354922,41.78345531,28.39710692,38.44803531,52.61165239,31.33900251,47.7098898,46.13716223,60.80324347,63.06296709,61.14672153,62.56302041,73.57634262,80.68134402,84.09161715,86.42168805,83.62885021,82.69730894,87.38430639,92.26394519,87.78013332,85.96624579,87.84265572,85.32430667,87.74945544,87.06258236,88.05326643,86.29714124,90.465153,86.36689116,81.69960378,87.69867171,82.08550027,85.6811316,88.07994935,87.69384792],
      [0,21.00084301,-54.20967226,-12.0118567,-25.27198718,-1.764831016,10.29814076,-5.340599221,6.988265971,9.56252586,-3.705303123,1.063813346,12.32611118,7.763248428,9.074028389,20.60003402,22.1001936,23.13229101,27.31536018,25.00455108,31.70315201,35.10288809,38.0816535,35.30253723,36.81655545,36.11171691,41.57221204,42.47852506,46.28315167,42.66070948,44.73318881,37.36241544,39.69557981,38.71667563,37.49757832,42.35943236,41.68017195,44.91883581,47.80088108]]

#It sould be used at the regression together so I put them in the same dataframe
data1=pd.DataFrame({'time':texp, 'cc1':yexp[0]})
data1.set_index('time',inplace=True)
data2=pd.DataFrame({'time':texp, 'cc2':yexp[1]})
data2.set_index('time',inplace=True)
data3=pd.DataFrame({'time':texp, 'cc3':yexp[2]})
data3.set_index('time',inplace=True)
data4=pd.DataFrame({'time':texp, 'cc4':yexp[3]})
data4.set_index('time',inplace=True)
datapd1=data1.join(data2, how='outer')
datapd2=data3.join(datapd1, how='outer')
data=data4.join(datapd2, how='outer')
#print(data.head())

#Model
m=GEKKO(remote=False)

#···Gekko time
m.time=texp

#···Gekko arrays to store measured data
ym=m.Array(m.CV,4)
ym[0].value=data['cc1'].values
ym[0].FSTATUS=1
ym[1].value=data['cc2'].values
ym[1].FSTATUS=1
ym[2].value=data['cc3'].values
ym[2].FSTATUS=1
ym[3].value=data['cc4'].values
ym[3].FSTATUS=1

#···Variables
X,R,L,I=m.Array(m.Var,4, value=0)

#···Adjustable parameters
k3=m.FV(value=1e8,lb=0)
k3.STATUS=1
k4=m.FV(value=0.01, lb=0)
k4.STATUS=1

#···Fixed parameters or constants
k1=3.58e6
k2=1.29e-1

#···Sistem of differential equations
for j in range(len(yexp)):
    m.free_initial(ym[j])
    m.Equations([X.dt()==-k4*X+k3*R*I,
            ym[j].dt()==-k2*ym[j]+k1*R*L,
            R.dt()==k2*ym[j]-k1*R*L+k4*X-k3*R*I,
            L.dt()==k2*ym[j]-k1*R*L,
            I.dt()==k4*X-k3*R*I])

#···Dynamic estimation
m.options.IMODE=5
#···Solver
m.options.SOLVER = 3
#···Collocation nodes
m.options.NODES=3

#···Solve
m.solve(disp=False)

#···Results
print(k3.value[0], k4.value[0])

plt.figure()
plt.plot(m.time, y.value, label='y')
#plt.plot(m.time, yexp, label='yexp')
plt.show()

And this is my output:这是我的输出:

---------------------------------------------------------------------------
Exception                                 Traceback (most recent call last)
<ipython-input-17-ce9ae2a50d35> in <module>
     67 
     68 #···Solve
---> 69 m.solve(disp=False)
     70 
     71 #···Results

~\anaconda3\lib\site-packages\gekko\gekko.py in solve(self, disp, debug, GUI, **kwargs)
   2138                 print("Error:", errs)
   2139             if (debug >= 1) and record_error:
-> 2140                 raise Exception(apm_error)
   2141 
   2142         else: #solve on APM server

Exception: @error: Solution Not Found

I'm new with Gekko, what am I doing wrong?我是 Gekko 的新手,我做错了什么?

The variables X , R , L , and I need a definition for each data column.变量XRLI需要为每个数据列定义。

#···Variables
X=m.Array(m.Var,4, value=0)
R=m.Array(m.Var,4, value=0)
L=m.Array(m.Var,4, value=0)
I=m.Array(m.Var,4, value=0)

This allows each to have a separate trajectory for the prediction.这允许每个人都有一个单独的预测轨迹。

#···System of differential equations
for j in range(4):
    m.free_initial(ym[j])
    m.Equations([X[j].dt()==-k4*X[j]+k3*R[j]*I[j],
                 ym[j].dt()==-k2*ym[j]+k1*R[j]*L[j],
                 R[j].dt()==k2*ym[j]-k1*R[j]*L[j]+k4*X[j]-k3*R[j]*I[j],
                 L[j].dt()==k2*ym[j]-k1*R[j]*L[j],
                 I[j].dt()==k4*X[j]-k3*R[j]*I[j]])

Here is the solution, although it appears that there is no time-evolution (dynamics) of the predicted response.这是解决方案,尽管预测响应似乎没有时间演化(动力学)。

解决方案

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

#4 sets of data for Y with same time and different concentrations
texp=[0.0001,0.5,0.75,1,1.25,2,2.77,3.55,4.32,5.1,5.87,6.65,7.42,\
      8.2,8.97,13.92,18.92,23.92,28.92,33.92,38.92,43.92,48.92,53.92,\
      58.92,63.92,68.92,83.9,98.9,113.9,128.9,143.9,158.9,173.9,188.9,\
      203.9,218.9,233.9,248.9]
yexp=[[0,134.0972365,101.6778993,95.40580822,77.46417317,97.38426357,\
       94.95124669,92.01743212,103.1524256,101.6335581,100.8064012,97.36957339,\
       98.54218566,105.1649371,100.7135276,91.76116765,98.50303784,99.09282871,\
       101.2884698,98.16682444,98.95862295,100.1781904,97.67407619,98.05420149,\
       101.7811854,99.65343296,99.35574195,101.5667478,97.8827634,99.21928788,\
       100.2506635,103.3401759,97.77635857,95.59188964,97.63152972,98.68365575,\
       97.94605393,94.40686956,101.4638065], \
      [0,52.8368317,60.63226219,57.1596205,77.40224428,76.59558061,83.08583996,\
       92.71540378,92.74825352,97.77466238,87.90927062,91.55955552,93.40910581,\
       97.38680721,98.68892712,96.28587494,97.24139983,99.14913748,97.05786666,\
       99.52031603,98.25378711,98.45507123,98.48665412,96.58596306,98.49718892,\
       97.03260859,97.78876552,96.96130531,96.16927889,99.05385817,99.81984318,\
       98.34275219,97.06707695,98.13554762,96.40027439,97.02992383,97.92157304,\
       97.45153492,100.7723151], \
      [0,6.651270535,-0.894974357,28.70354922,41.78345531,28.39710692,\
       38.44803531,52.61165239,31.33900251,47.7098898,46.13716223,60.80324347,\
       63.06296709,61.14672153,62.56302041,73.57634262,80.68134402,84.09161715,\
       86.42168805,83.62885021,82.69730894,87.38430639,92.26394519,87.78013332,\
       85.96624579,87.84265572,85.32430667,87.74945544,87.06258236,88.05326643,\
       86.29714124,90.465153,86.36689116,81.69960378,87.69867171,82.08550027,\
       85.6811316,88.07994935,87.69384792], \
      [0,21.00084301,-54.20967226,-12.0118567,-25.27198718,-1.764831016,\
       10.29814076,-5.340599221,6.988265971,9.56252586,-3.705303123,\
       1.063813346,12.32611118,7.763248428,9.074028389,20.60003402,\
       22.1001936,23.13229101,27.31536018,25.00455108,31.70315201,\
       35.10288809,38.0816535,35.30253723,36.81655545,36.11171691,\
       41.57221204,42.47852506,46.28315167,42.66070948,44.73318881,\
       37.36241544,39.69557981,38.71667563,37.49757832,42.35943236,\
       41.68017195,44.91883581,47.80088108]]

#It sould be used at the regression together so I put them in the same dataframe
data1=pd.DataFrame({'time':texp, 'cc1':yexp[0]})
data1.set_index('time',inplace=True)
data2=pd.DataFrame({'time':texp, 'cc2':yexp[1]})
data2.set_index('time',inplace=True)
data3=pd.DataFrame({'time':texp, 'cc3':yexp[2]})
data3.set_index('time',inplace=True)
data4=pd.DataFrame({'time':texp, 'cc4':yexp[3]})
data4.set_index('time',inplace=True)
datapd1=data1.join(data2, how='outer')
datapd2=data3.join(datapd1, how='outer')
data=data4.join(datapd2, how='outer')
print(data.head())

#Model
m=GEKKO(remote=False)

#···Gekko time
m.time=texp

#···Gekko arrays to store measured data
ym=m.Array(m.CV,4)
ym[0].value=data['cc1'].values
ym[0].FSTATUS=1
ym[1].value=data['cc2'].values
ym[1].FSTATUS=1
ym[2].value=data['cc3'].values
ym[2].FSTATUS=1
ym[3].value=data['cc4'].values
ym[3].FSTATUS=1

#···Variables
X=m.Array(m.Var,4, value=0)
R=m.Array(m.Var,4, value=0)
L=m.Array(m.Var,4, value=0)
I=m.Array(m.Var,4, value=0)

#···Adjustable parameters
k3=m.FV(value=1e8,lb=0)
k3.STATUS=1
k4=m.FV(value=0.01, lb=0)
k4.STATUS=1

#···Fixed parameters or constants
k1=3.58e6
k2=1.29e-1

#···System of differential equations
for j in range(4):
    m.free_initial(ym[j])
    m.Equations([X[j].dt()==-k4*X[j]+k3*R[j]*I[j],
                 ym[j].dt()==-k2*ym[j]+k1*R[j]*L[j],
                 R[j].dt()==k2*ym[j]-k1*R[j]*L[j]+k4*X[j]-k3*R[j]*I[j],
                 L[j].dt()==k2*ym[j]-k1*R[j]*L[j],
                 I[j].dt()==k4*X[j]-k3*R[j]*I[j]])

#···Dynamic estimation
m.options.IMODE=5
#···Solver
m.options.SOLVER = 3
#···Collocation nodes
m.options.NODES=3

#···Solve
m.solve(disp=True)

#···Results
print(k3.value[0], k4.value[0])

plt.figure()
for i in range(4):
    plt.subplot(4,1,i+1)
    plt.plot(m.time, ym[i].value,'-', label='y')
    plt.plot(m.time, yexp[i],'o', label='yexp')
    plt.legend()
plt.show()

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

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