在我的项目中,我有多个预定义的函数族来拟合曲线。让我们看看最简单的:
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
注意:
我知道在这种特殊情况下,^{
(更简单)的函数,使配件看起来像这样:
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
我通过为
polyfit
函数创建全局配置来重写代码。这是if
更具python风格的版本。你知道吗我相信您发布了非常简化的代码版本(因为您当前的版本可以比我上面的代码更有效地最小化)。你知道吗
我认为
lmfit.models.PolynomialModel()
正是你想要的。该模型将多项式次数n
作为参数,并使用名为c0
、c1
、cn
(最多处理n=7
)的系数:请注意,这里可以过度指定系数。也就是说,如果
degree=3
,那么对fitModel.make_params(c0=0, ..., c7=0)
的调用实际上不会为c4
、c5
、c6
或c7
生成参数。你知道吗PolynomialModel
会产生一个TypeError
ifdegree > 7
,所以我没有考虑你的显式测试。你知道吗我希望这能让您开始学习,但看起来您可能也想包括其他模型函数。在这种情况下,我所做的是制作一本类名词典:
然后用它来构建模型:
相关问题 更多 >
编程相关推荐