How to fit multiple datasets which have a combination of shared and non-shared parameters

故事扮演 提交于 2019-12-04 20:35:08

A fit with lmfit always uses a single instance of a Parameters object, it does not take multiple Parameters objects.

In order to simultaneously fit multiple data sets with the similar models (perhaps the same mathematical model, but expecting different parameter values for each model), you need to have an objective function that concatenates the residuals from the different component models. And each of those models has to have parameters that are taken from the single instance of Parameters(), each parameter having a unique name.

So, to fit 2 data sets with the same function (let's use Gaussian, with parameters "center", "amplitude", and "sigma"), you might define the Parameters as

params =  Parameters()
params.add('center_1',    5., vary=True)
params.add('amplitude_1', 10., vary=True)
params.add('sigma_1',    1.0, vary=True
params.add('center_2',    8., vary=True)
params.add('amplitude_2', 3., vary=True)
params.add('sigma_2',    2.0, vary=True)

Then use 'center_1', 'amplitude_1', and 'sigma_1' to calculate the model for the first data set and 'center_2', etc to calculate the the model for the second, perhaps as

def residual(params, x, datasets):
    model1 = params['amplitude_1'] * gaussian(x, params['center_1'], params['sigma_1'])
    model2 = params['amplitude_2'] * gaussian(x, params['center_2'], params['sigma_2']

    resid1 = datasets[0] - model1
    resid2 = datasets[1] - model2
    return np.concatenate((resid1, resid2))

fit = lmfit.minimize(residual, params, fcn_args=(x, datasets))

As you might be able to see from this, Parameter values are independent by default. In order to share parameter values to be used in different datasets, you have to do that explicitly (as shown in the linked answer you provide).

For example, if you want to require the sigma values to be the same, would not change the residual function, just the Parameter definition above to:

params.add('sigma_2', expr='sigma_1')

You could require the two amplitudes to add to some value:

params.add('amplitude_2', expr='10 - amplitude_1')

or perhaps you would want to ensure that 'center_2' is larger than 'center_1', but by an amount to be determined in the fit:

params.add('center_offset', value=0.5, min=0)
params.add('center_2',  expr='center_1 + center_offset')

Those are all ways to tie parameter values. By default, they're independent. Of course, you can also have some parameters that get used in all the models (say, just call the parameter 'sigma' and use it in for all models).

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!