1

I have some function which behaves as shown below i.e. some tapered/decaying oscillations enter image description here

I want to fit the data using scipy's curve_fit. I have previously asked a question related to fitting functions with scipy, which was well answered here, and highlighted the importance of the initial guess for the values of the fitting parameters.

However, I am struggling to fit this data in a way which captures both the oscillations and the decay. My approach is as follows:

from scipy.optimize import curve_fit 
import numpy as np


def Fit(x,y):

    #Define the function fit
    func = ansatz

    #Define the initial guess of parameters

    mag = (y.max() + y.min()) / 2
    y_shifted = y - mag
    omega_guess = np.pi * np.sum(y_shifted[:-1] * y_shifted[1:] < 0) / (x.max() - x.min())
    lam = np.log(2) / 1e7 #Rough guess based on approximate half life 

    p0 = (mag,mag, omega_guess,mag,lam)

    #Do the fit
    popt, pcov = curve_fit(func, x,y,p0=p0)


    # return 

    return func(x, *popt)




def ansatz(x,A,B,omega,offset,lam):
    osc = A*np.sin(omega*x) + B*np.cos(omega*x) 
    linear = offset
    decay = np.exp(-x*lam)

    return  decay*osc + linear



data = np.load('example.npy')
x = data[:,0]
y = data[:,1]

yFit = Fit(x,y)

This approach captures the decay, but not the oscillations. What is erroneous with my approach? Guesses for fit parameters? Function ansatz? Code implementation?

user1887919
  • 829
  • 2
  • 9
  • 24
  • You could make succeive fit to find initial a good initial guess. First fit the offset, then remove it, then fit the exponential and remove it, and then fit only the oscillation. – Liris Mar 03 '20 at 09:14

0 Answers0