Vicknesh
Vicknesh

Reputation: 31

Reg: Error in stretched exponential function fitting

I am having data in.csv file and it contains 2 column x and y axis. The axis are read from .csv file and then fitting the data with stretched exponential function but its showing error.

Here I am giving example data to easy understanding.

My function is f(x) = a. exp (-b.t) ^ c + d. (Stretched exponential fitting). I want to fit this data according to this function and I want the final value of a, b, c and d.

My coding is:

# Reading data
x=data[1,2,3,4,5,6,7,8,9,10]
y=data[7.2489, 7.0123, 7.0006, 7.0003, 7, 7, 7, 7, 7, 7]
# Fitting Streched Exponential Decay Curve
smoothx = np.linspace(x[0], x[-1], (5*x[-1]))
guess_a, guess_b, guess_c, guess_d = 4000, -0.005, 4, 4000
guess = [guess_a, guess_b, guess_c, guess_d]
f_theory1 = lambda t, a, b, c, d: a * np.exp((b*t)^(c)) + d
p, cov = curve_fit(f_theory1, x, y, p0=np.array(guess))
f_fit1 = lambda t: p[0] * np.exp((p[1] * t)^((p[2]))) + p[3]
plt.show()

Here I am showing only guess and fitting part of my program.

Kindly correct mistakes in my code for better fitting.

Upvotes: 1

Views: 1591

Answers (1)

Cleb
Cleb

Reputation: 26027

You could use lmfit to fit your parameters. Then the plot looks like this:

enter image description here

and the corresponding parameters are the following:

a:   56.8404075 
b:  -5.43686170 
c:   49.9888343 
d:   7.00146666 

The advantage of lmfit is that you can also easily constrain the range of your parameters using the min and max argument (see code below).

Here is the code that produces the plot; please not that I slightly modified your model to avoid calculating roots from negative numbers:

from lmfit import minimize, Parameters, Parameter, report_fit
import numpy as np

x=np.array([1,2,3,4,5,6,7,8,9,10]  )
y=np.array([7.2489, 7.0123, 7.0006, 7.0003, 7, 7, 7, 7, 7, 7])  


def f_theory1(params, x, data):  
    a = params['a'].value
    b = params['b'].value
    c = params['c'].value
    d = params['d'].value

    model = a * np.exp(b*(x**c)) + d # now b can become negative; in your definition it could not

    return model - data #that's what you want to minimize

# create a set of Parameters
#'value' is the initial condition
#'min' and 'max' define your boundaries
params = Parameters()
params.add('a', value= 40, min=-10, max=10000) 
params.add('b', value= -0.005, min=-10, max=200)
params.add('c', value= .03, min=-10, max=400) 
params.add('d', value= 40.0, min=-10, max=400) 

# do fit, here with leastsq model
result = minimize(f_theory1, params, args=(x, y))

# calculate final result
final = y + result.residual

# write error report
report_fit(params)

#plot results
try:
    import matplotlib.pyplot as plt
    plt.plot(x, y, 'k+')
    plt.plot(x, final, 'r')
    plt.ylim([6.95, 7.3])
    plt.show()
except:
    pass

Upvotes: 1

Related Questions