1

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.

Cleb
  • 25,102
  • 20
  • 116
  • 151
Vicknesh
  • 31
  • 1
  • 6
  • I'm not sure what data types you're using, but `^` is conventionally "bitwise XOR" in Python, rather than exponentiation. What happens if you replace them with `**`? Also, when you say "its showing error", what exactly is the error message? – Kevin Sep 23 '15 at 15:10
  • Thanks kevin. I replaced ^ by **. After that i am getting this error RuntimeWarning: invalid value encountered in power. – Vicknesh Sep 23 '15 at 15:27
  • The error might result from the fact that you calculate roots from negative numbers. I corrected that and added an answer below; please let me know whether that solves your problem or whether the answer needs to be revised. – Cleb Oct 13 '15 at 19:34
  • Thanks cleb. It also didnt works. The error was too many parameter inside exponential. f_theory1 = lambda t, a, b, c, d: a * np.exp((b*t)^(c)) + d. so i changed formula to f_theory1 = lambda t, a, b, c, d: a * np.exp((b)(t)^(c)) + d. Then i am getting out of b^c, from that i calculated b value manually. Thanks once again to Kevin and cleb for your wonderful contribution, – Vicknesh Oct 19 '15 at 09:26

1 Answers1

1

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
Cleb
  • 25,102
  • 20
  • 116
  • 151
  • @Vicknesh: Welcome. If it solved your problem, I would also appreciate if you accepted this answer by clicking on the small check next to my answer which then turns green. Thanks! – Cleb Oct 19 '15 at 10:05