【问题标题】:Constraints on curve fitting parameters曲线拟合参数的约束
【发布时间】:2016-11-25 13:39:00
【问题描述】:

我试图在我的二次曲线拟合过程中施加界限和约束。目标是找到系数a,bc。对 b 施加约束:delta-2*a*x 是我的疑问。如何在我的约束中添加变量 x。可行代码:

from lmfit import Model, Parameters

#create x and y data to be used for curve fitting
xip=[ 0.02237461, 0.0983837 , 0.25707382, 0.56959641, 1.33419197, 4.95835927]
yip=[0.20085822, 0.23583258, 0.28996988, 0.36350284, 0.47981232, 0.67602165] 

#function to fit data: a,b,c needs to be found
def f(xx, a, b, c):
    # constraints: c <=0,  a>0  and 2*a*x+b >= 0
    return a*xx**2 + b*xx + c

fmodel = Model(f)
params = Parameters()

params.add('a', value=-1e-2, vary=True, min = -1e10, max = 0)
params.add('c', value=-4e-2, vary=True, min = -1e10, max =0)
params.add('delta', value=5e-2, vary=True, min=0, max=1e10)
params.add('xpara', value=5, vary=True)
params.add('b', expr = 'delta-2*a*xpara')

result = fmodel.fit(yip, params, xx=xip)
print(result.fit_report())


import  matplotlib.pyplot as plt
op = plt.subplot(1,1,1)
op.scatter(xip,yip)
plt.plot(xip, result.init_fit, 'k--')
#plt.plot(xip, result.best_fit, 'r-')

谢谢!

编辑:我更改了变量,以使该程序正常工作。但不确定这是否是应用约束的正确方法。

编辑 2:添加了必要的约束: c 0 和 2*a*x+b >= 0 ;

【问题讨论】:

    标签: python scipy lmfit


    【解决方案1】:

    你得到什么错误?

    在我看来代码应该可以工作。但是,在您的消息中,您说您想将c 限制为delta+b+2*a*x,而在您的代码中您有delta-b-2*a*xpara。有符号问题吗?

    您还将delta 初始化为 5e-2,但将其最大值设置为 0。这似乎是一个错误,可能与混淆符号有关。

    【讨论】:

    • @M 纽维尔,对不起!我已经用我的实际数据修改了我的代码。我在这里检查:是否可以在约束中添加变量 xx ?在这个曲线拟合过程中xpara 如何代表xx。其中 xx 只不过是xip,曲线拟合过程中使用的数据。谢谢!
    • 我不确定我是否完全理解您的问题。参数有标量而不是数组。当您说“2*ax+b > 0”时,x 可能意味着是一个数组。但由于这没有改变,您也许可以断言“2*ax_max + b > 0”,并在拟合之前知道 x_max 的值。 * cmets 不是进行此类讨论的好地方。请考虑适当的邮件列表。
    • 好的,纽维尔。我可以使用最小化功能。残差((y-a*x**2-b*x-c)**2).sum() 用作目标函数。
    • 好的,很高兴你成功了。但是,我不确定我们可以从您的经验中学到什么。如果您能澄清您正在做什么来解决您遇到的问题,这可能会对其他有类似问题的 SO 读者有所帮助。