Matt Durkin
Matt Durkin

Reputation: 267

Passing additional arguments using scipy.optimize.curve_fit?

I am writing a program in Python that will fit Gaussian and Lorentzian shapes to some given resonance data. I originally began using scipy.optimize.leastsq but changed to using optimize.curve_fit after having difficulties in retrieving the errors in the optimized parameters from the covariance matrix.

I have defined a function to fit a sum of Gaussian and Lorentzian:

def mix(x,*p):
    ng = numg
    p1 = p[:3*ng]
    p2 = p[3*ng:]
    a = sumarray(gaussian(x,p1),lorentzian(x,p2))
    return a

where p is an array of the initial guesses at the fit parameters. Here is the instance where it is called using curve_fit:

leastsq,covar = opt.curve_fit(mix,energy,intensity,inputtot)

At the moment numg (the number of Gaussian shapes) is a global variable. Is there's any way that it can be incorporated into curve_fit as an extra argument instead, as can be done with leastsq?

Upvotes: 17

Views: 10087

Answers (2)

Reinderien
Reinderien

Reputation: 15318

Instead of doing an inner closure, you may also curry using functools.partial:

leastsq, covar = opt.curve_fit(
    partial(mix, numg=my_constant),
    # ...
)

Upvotes: 1

Shep
Shep

Reputation: 8380

The great thing about python is that you can define functions that return other functions, try currying:

def make_mix(numg): 
    def mix(x, *p): 
        ng = numg
        p1 = p[:3*ng]
        p2 = p[3*ng:]
        a = sumarray(gaussian(x,p1),lorentzian(x,p2))
        return a
    return mix

and then

leastsq, covar = opt.curve_fit(make_mix(numg),energy,intensity,inputtot)

Upvotes: 22

Related Questions