You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用GEKKO实现带指定点值和斜率约束的非线性回归?

问题修正说明

你代码的核心问题是混用了SymPy符号体系和GEKKO的求解体系,GEKKO无法识别SymPy的符号运算结果,约束需要直接用GEKKO变量手动写表达式:

  • 原模型为 Cp = a + b*T + c*T^(-2),在T=70处的值约束直接代入T=70写等式即可
  • 对T手动求导得斜率公式为 dCp/dT = b - 2*c*T^(-3),代入T=70即可写斜率约束

修正后完整代码

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

T=np.array([  70.,   80.,   90.,  100.,  110.,  120.,  130.,  140.,  150.,
        160.,  170.,  180.,  190.,  200.,  210.,  220.,  230.,  240.,
        250.,  260.,  270.,  280.,  290.,  298.,  300.,  310.,  320.,
        330.,  340.,  343.,  350.,  360.,  363.,  370.,  380.,  383.,
        390.,  400.,  403.,  410.,  420.,  423.,  430.,  440.,  443.,
        450.,  460.,  463.,  470.,  480.,  483.,  490.,  500.,  503.,
        510.,  520.,  523.,  530.,  540.,  543.,  550.,  560.,  563.,
        570.,  580.,  583.,  590.,  600.,  610.,  620.,  623.,  630.,
        640.,  643.,  650.,  660.,  663.,  670.,  680.,  683.,  690.,
        700.,  703.,  710.,  720.,  723.,  730.,  740.,  743.,  750.,
        760.,  763.,  770.,  780.,  790.,  800.,  810.,  820.,  830.,
        840.,  850.,  860.,  870.,  880.,  890.,  900.,  910.,  920.,
        930.,  940.,  950.,  960.,  970.,  980.,  990., 1000., 1500.,
       1500.])
Cp=np.array([11.28642 , 13.19342 , 14.82796 , 16.606885, 17.3842  , 18.3733  ,
       19.21185 , 19.9262  , 20.53826 , 21.06597 , 21.52387 , 21.9238  ,
       22.27536 , 22.58634 , 22.8631  , 23.11088 , 23.33401 , 23.53603 ,
       23.71991 , 23.88818 , 24.04287 , 24.18579 , 24.31843 , 24.4     ,
       24.44204 , 24.55777 , 24.66653 , 24.7691  , 24.86624 , 24.81    ,
       24.95854 , 25.04652 , 25.02    , 25.13065 , 25.2114  , 25.24    ,
       25.28911 , 25.36401 , 25.33    , 25.43645 , 25.50675 , 25.49    ,
       25.57505 , 25.64156 , 25.6     , 25.70655 , 25.77003 , 25.7     ,
       25.83227 , 25.89344 , 25.81    , 25.95348 , 26.01259 , 26.145   ,
       26.07098 , 26.12865 , 25.98    , 26.18561 , 26.24207 , 26.04    ,
       26.29805 , 26.35354 , 26.17    , 26.4087  , 26.46352 , 26.27    ,
       26.5182  , 26.57262 , 26.62678 , 26.68089 , 26.49    , 26.73492 ,
       26.7889  , 26.59    , 26.84285 , 26.89681 , 26.69    , 26.95088 ,
       27.005   , 26.81    , 27.05915 , 27.11354 , 26.96    , 27.16812 ,
       27.22276 , 27.13    , 27.27771 , 27.33283 , 27.47    , 27.38814 ,
       27.44385 , 27.76    , 27.49973 , 27.55588 , 27.6125  , 27.66953 ,
       27.72683 , 27.78436 , 27.84238 , 27.9009  , 27.95975 , 28.01896 ,
       28.07876 , 28.13917 , 28.19976 , 28.26095 , 28.32291 , 28.38519 ,
       28.44783 , 28.51116 , 28.57536 , 28.63981 , 28.70504 , 28.77107 ,
       28.8372  , 28.90433 , 33.47658 , 33.47658 ])

m=GEKKO()
m.options.IMODE=2 
T_fit=m.Param(value=T)
a=m.FV() 
a.STATUS=1
b=m.FV() 
b.STATUS=1
c=m.FV() 
c.STATUS=1
Cp_fit=m.CV(value=Cp) 
Cp_fit.FSTATUS=1  

# 主拟合方程
m.Equation(Cp_fit == c*T_fit**(-2) + b*T_fit + a) 

val=11.8238767562590 
slope = 0.362994963854413
# T=70处的值约束
m.Equation(val == a + b*70 + c*(70**-2))
# T=70处的斜率约束,手动求导得dCp/dT = b - 2*c*T^-3
m.Equation(slope == b - 2*c*(70**-3))

m.options.SOLVER=1
m.solve(disp=False) 
print(f"拟合参数:a={a.value[0]}, b={b.value[0]}, c={c.value[0]}")

# 验证约束满足情况
pred_70 = a.value[0] + b.value[0]*70 + c.value[0]*(70**-2)
pred_slope_70 = b.value[0] - 2*c.value[0]*(70**-3)
print(f"T=70处预测值:{pred_70},目标值:{val},误差:{abs(pred_70-val)}")
print(f"T=70处预测斜率:{pred_slope_70},目标斜率:{slope},误差:{abs(pred_slope_70-slope)}")

plt.plot(T,Cp,'bo',label='原始数据')
plt.plot(T_fit.value,Cp_fit.value,'r-',label='约束回归拟合曲线')
plt.xlabel('T')
plt.ylabel('Cp')
plt.legend()
plt.show()

运行后可看到T=70处的值和斜率约束误差接近0,完全满足拟合要求。


内容的提问来源于stack exchange,提问作者Karthikeyan M mm20m013

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.04 07:51:02