В моем проекте у меня есть несколько семейств функций, предопределенных для соответствия кривой. Рассмотрим самые простые:
def polyfit3(x, b0, b1, b2, b3):
return b0+b1*x+b2*x**2+b3*x**3
def polyfit2(x, b0, b1, b2):
return b0+b1*x+b2*x**2
def polyfit1(x, b0, b1):
return b0+b1*x
Примечание. Я знаю, что в данном конкретном случае np.polyfit
< /a> будет лучшим выбором
Функция (намного более простая), которая делает фитинг, выглядит следующим образом:
from scipy.optimize import curve_fit
try:
from lmfit import Model
_has_lmfit = True
except ImportError:
_has_lmfit = False
def f(x, y, order=3):
if _has_lmfit:
if order == 3:
fitModel = Model(polyfit3)
params = fitModel.make_params(b0=0, b1=1, b2=1, b3=1)
result = fitModel.fit(y, x=x, params=params)
elif order == 2:
fitModel = Model(polyfit2)
params = fitModel.make_params(b0=0, b1=1, b2=1)
result = fitModel.fit(y, x=x, params=params)
elif order == 1:
fitModel = Model(polyfit1)
params = fitModel.make_params(b0=0, b1=1)
result = fitModel.fit(y, x=x, params=params)
else:
raise ValueError('Order is out of range, please select from [1, 3].')
else:
if order == 3:
popt, pcov = curve_fit(polyfit3, x, y)
_function = polyfit3
elif order == 2:
popt, pcov = curve_fit(polyfit2, x, y)
_function = polyfit2
elif order == 1:
popt, pcov = curve_fit(polyfit1, x, y)
_function = polyfit1
else:
raise ValueError('Order is out of range, please select from [1, 3].')
# more code there.. mostly working with the optimized parameters, plotting, etc.
Моя проблема в том, что это становится действительно уродливым быстро, и я повторяю это снова и снова. Есть ли способ построить это лучше?
ИЗМЕНИТЬ:
Я пробовал это:
def poly_fit(x, *args):
return sum(b*x**i for i, b in enumerate(args))
...
fitModel = Model(poly_fit)
fitModel.make_params(**{f'b{i}': 1 for i in range(order+1)})
но, к сожалению, lmfit выдает ошибку:
ValueError: varargs '*args' is not supported