Reputation: 31
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
Reputation: 26027
You could use lmfit to fit your parameters. Then the plot looks like this:
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