我尝试使用SciPy的optimize.minimize来拟合抛物线,根据一些约束条件来最小化一些分散的数据:曲线下的面积以及曲线通过数据的起点和终点。在这里,curve_fit
可以正常工作,但我希望在其他情况下也使用带有约束的minimize
。约束版本似乎不成功(可能是因为x
或y
的值范围...?)。有什么办法可以帮助它收敛吗?
import scipy
import numpy as np
import matplotlib.pyplot as plt
x = np.array([258.6669469, 258.831, 259.129, 259.428 , 259.726, 260.025, 260.324, 260.622,261.15238824])
y = np.array([0, -0.062, -0.139, -0.181, -0.197, -0.193, -0.17 , -0.129, 0])
def Func(x,a,b,c):
return a*x**2 + b*x + c
def FuncCons(x,params):
return params[2]*x**2 + params[1]*x + params[0]
def ConstraintIntegral(params):
integral = scipy.integrate.quad(FuncCons, x[0], x[-1], args=(params,))[0]
return integral- np.trapz(y,x)
def ConstraintBegin(params):
return y[0] - FuncCons(x[0],params)
def ConstraintEnd(params):
return y[-1] - FuncCons(x[-1],params)
def Objective(params,x,y):
y_pred = FuncCons(x,params)
return np.sum((y_pred - y) ** 2) # least squares
cons = [{'type':'eq', 'fun': ConstraintIntegral},
{'type':'eq', 'fun': ConstraintBegin},
{'type':'eq', 'fun': ConstraintEnd}]
sigma = np.ones(len(x))
sigma[[0, -1]] = 0.0001 # first and last points
popt1, _ = scipy.optimize.curve_fit(Func, x, y, sigma=sigma)
new = scipy.optimize.minimize(Objective, x0=popt1, args=(x,y), constraints=cons)
popt3 = new.x
y_fit1 = Func(x, *popt1)
y_fit3 = FuncCons(x, popt3)
fig, ax = plt.subplots(1)
ax.scatter(x,y)
ax.plot(x,y_fit1, color='g', alpha=0.75, label='curve_fit')
ax.plot(x,y_fit3, color='r', alpha=0.75, label='generally constrained')
plt.legend()
字符串
1条答案
按热度按时间vshtjzan1#
这不应使用迭代拟合;该问题是精确确定的,并且应该通过分析计算:
个字符
x1c 0d1x的数据