Search code examples
pythonscipycurve-fitting

Fixing fit parameters in curve_fit


I have a function Imaginary which describes a physics process and I want to fit this to a dataset x_interpolate, y_interpolate. The function is a form of a Lorentzian peak function and I have some initial values that are user given, except for f_peak (the peak location) which I find using a peak finding algorithm. All of the fit parameters, except for the offset, are expected to be positive and thus I have set bounds_I accordingly.

def Imaginary(freq, alpha, res, Ms, off):
    numerator = (2*alpha*freq*res**2)
    denominator = (4*(alpha*res*freq)**2) + (res**2 - freq**2)**2
    Im = Ms*(numerator/denominator) + off
    return Im

pI = np.array([alpha_init, f_peak, Ms_init, 0])

bounds_I = ([0,0,0,0, -np.inf], [np.inf,np.inf,np.inf, np.inf])

poptI, pcovI = curve_fit(Imaginary, x_interpolate, y_interpolate, pI, bounds=bounds_I)

In some situations I want to keep the parameter f_peak fixed during the fitting process. I tried an easy solution by changing bounds_I to:

bounds_I = ([0,f_peak+0.001,0,0, -np.inf], [np.inf,f_peak-0.001,np.inf, np.inf])

This is for many reasons not an optimal way of doing this so I was wondering if there is a more Pythonic way of doing this? Thank you for your help


Solution

  • If a parameter is fixed, it is not really a parameter, so it should be removed from the list of parameters. Define a model that has that parameter replaced by a fixed value, and fit that. Example below, simplified for brevity and to be self-contained:

    x = np.arange(10)
    y = np.sqrt(x)    
    def parabola(x, a, b, c):
      return a*x**2 + b*x + c
    
    fit1 = curve_fit(parabola, x, y)  #  [-0.02989396,  0.56204598,  0.25337086]
    b_fixed = 0.5
    fit2 = curve_fit(lambda x, a, c: parabola(x, a, b_fixed, c), x, y) 
    

    The second call to fit returns [-0.02350478, 0.35048631], which are the optimal values of a and c. The value of b was fixed at 0.5.

    Of course, the parameter should be removed from the initial vector pI and the bounds as well.