Search code examples
pythonpython-3.xcurve-fittingscipy-optimize

Scipy Optimize Curve fit not properly fitting with real data


I am trying to fit a decaying exponential function to real world data. I'm having a problem with aligning the function to the actual data.

Here's my code:

def test_func(x, a, b, c):
    return a*np.exp(-b*x)*np.sin(c*x)

my_time = np.linspace(0,2.5e-6,25000)
p0 = [60000, 700000, 2841842]

params, params_covariance = curve_fit(test_func, my_time, my_amp,p0)

My signal and fitted function My signal and fitted function

My question: why doesn't the fitted function start where my data starts increasing in amplitude?


Solution

  • As I said in my comment, the problem is that your function does not take into account that the exponential curve can be shifted. If you include this shift as an additional parameter, the fit will probably converge.

    from scipy.optimize import curve_fit 
    from matplotlib import pyplot as plt
    import numpy as np
    
    def test_func(x, a, b, c, d):  
        return a*np.exp(-b*(x+d))*np.sin(c*(x+d))
    
    my_time = np.linspace(0,2.5e-6,25000)
    
    #generate fake data
    testp0 = [66372, 765189, 2841842, -1.23e-7]
    test_amp = test_func(my_time, *testp0)
    my_amp = test_func(my_time, *testp0)
    my_amp[:2222] = my_amp[2222]
    
    p0 = [600, 700000, 2000, -2e-7]
    params, params_covariance = curve_fit(test_func, my_time, test_amp, p0)
    print(params)
    fit_amp = test_func(my_time, *params)
    
    plt.plot(my_time, my_amp, label="data")
    plt.plot(my_time, fit_amp, label="fit")
    plt.legend()
    
    plt.show()
    

    Sample output

    enter image description here