python nonlinear least squares fitting

前端 未结 2 1230
灰色年华
灰色年华 2020-12-13 03:11

I am a little out of my depth in terms of the math involved in my problem, so I apologise for any incorrect nomenclature.

I was looking at using the scipy function l

相关标签:
2条回答
  • 2020-12-13 03:34

    This is a bare-bones example of how to use scipy.optimize.leastsq:

    import numpy as np
    import scipy.optimize as optimize
    import matplotlib.pylab as plt
    
    def func(kd,p0,l0):
        return 0.5*(-1-((p0+l0)/kd) + np.sqrt(4*(l0/kd)+(((l0-p0)/kd)-1)**2))
    

    The sum of the squares of the residuals is the function of kd we're trying to minimize:

    def residuals(kd,p0,l0,PLP):
        return PLP - func(kd,p0,l0)
    

    Here I generate some random data. You'd want to load your real data here instead.

    N=1000
    kd_guess=3.5  # <-- You have to supply a guess for kd
    p0 = np.linspace(0,10,N)
    l0 = np.linspace(0,10,N)
    PLP = func(kd_guess,p0,l0)+(np.random.random(N)-0.5)*0.1
    
    kd,cov,infodict,mesg,ier = optimize.leastsq(
        residuals,kd_guess,args=(p0,l0,PLP),full_output=True,warning=True)
    
    print(kd)
    

    yields something like

    3.49914274899
    

    This is the best fit value for kd found by optimize.leastsq.

    Here we generate the value of PLP using the value for kd we just found:

    PLP_fit=func(kd,p0,l0)
    

    Below is a plot of PLP versus p0. The blue line is from data, the red line is the best fit curve.

    plt.plot(p0,PLP,'-b',p0,PLP_fit,'-r')
    plt.show()
    

    enter image description here

    0 讨论(0)
  • 2020-12-13 03:40

    Another option is to use lmfit.

    They provide a great example to get you started:.

    #!/usr/bin/env python
    #<examples/doc_basic.py>
    from lmfit import minimize, Minimizer, Parameters, Parameter, report_fit
    import numpy as np
    
    # create data to be fitted
    x = np.linspace(0, 15, 301)
    data = (5. * np.sin(2 * x - 0.1) * np.exp(-x*x*0.025) +
            np.random.normal(size=len(x), scale=0.2) )
    
    # define objective function: returns the array to be minimized
    def fcn2min(params, x, data):
        """ model decaying sine wave, subtract data"""
        amp = params['amp']
        shift = params['shift']
        omega = params['omega']
        decay = params['decay']
        model = amp * np.sin(x * omega + shift) * np.exp(-x*x*decay)
        return model - data
    
    # create a set of Parameters
    params = Parameters()
    params.add('amp',   value= 10,  min=0)
    params.add('decay', value= 0.1)
    params.add('shift', value= 0.0, min=-np.pi/2., max=np.pi/2)
    params.add('omega', value= 3.0)
    
    
    # do fit, here with leastsq model
    minner = Minimizer(fcn2min, params, fcn_args=(x, data))
    kws  = {'options': {'maxiter':10}}
    result = minner.minimize()
    
    
    # calculate final result
    final = data + result.residual
    
    # write error report
    report_fit(result)
    
    # try to plot results
    try:
        import pylab
        pylab.plot(x, data, 'k+')
        pylab.plot(x, final, 'r')
        pylab.show()
    except:
        pass
    
    #<end of examples/doc_basic.py>
    
    0 讨论(0)
提交回复
热议问题