python - Solve equation with a set of points -
i have set of points. basically, have p = f(t).
i have, let's say, 50 measurements. 50 values of p, function of time. , these values follow established law.
what have find values of parameters in law, that's all. basically, have fit points best curve. here law:
p = v.t - ((v - w)(1 - exp(-k.t)) / k)
what need find numeric value v, w , k. have t , p. have idea how that?
edit:
here screenshot of want obtain:
on picture:
- v vs
- w vi
- k k
and that's obtained reptilicus's help:
http://i.imgur.com/f59eo29.png
import numpy np scipy.optimize import curve_fit matplotlib.pyplot import * import xlrd def myfunc(t, v, w, k): y = v * t - ((v - w) * (1 - np.exp(-k * t)) / k) return y classeur = xlrd.open_workbook(path) names_sheets = classeur.sheet_names() sheet = classeur.sheet_by_name(names_sheets[0]) row_start = 2 time = sheet.col_values(0, row_start) fluo = feuille.col_values(4, row_start) time = [ index index in time if index ] fluo = [ index index in fluo if index ] # generates fake data fit. youm read in # data in csv or whatever you've x = np.array(time) y = np.array(fluo) #fit data, return best fit parameters , covariance matrix #popt, pcov = curve_fit(myfunc, x, yn) popt, pcov = curve_fit(myfunc, x, y) print(popt) print(pcov) #plot data clf() #matplotlib plot(x, y, "rs") #overplot best fit curve plot(x, myfunc(x, popt[0], popt[1], popt[2])) grid(true) show()
not bad. managed extract data of excel workbook, , plotted it. can see, got linear regression, don't want. goal t reproduce fit got origin 8.
edit:
i have news. last guy did in team told me how did origin. in fact, use least square way well, find parameters chi 2 minimization. software iterations, , optimizes parameters.
edit 2:
because took me long figure out, share here results of researches. main problem facing fact values "too small". indeed, y values of order of 10^-7. explained here fitting curve: why small numbers better?, numbers of order of 1 better fit.
moreover, in case @ least, data of order, didn't need give initial parameters (by default, set 1). "normalized" values. example, transformed time values seconds hour, , multiplicated 10^7 y values, of order of 10^-7. then, transformed obtained parameters them in desired unities. here code:
import numpy np scipy.optimize import curve_fit, leastsq matplotlib.pyplot import * def myfunc(t, vs, vi, k): y = vs * t - ((vs - vi) * (1 - np.exp(-k * t)) / k) return y raw_x = some_input raw_y = some_input # scaling data time = [ index /3600 index in raw_x if index or index==0 ] fluo = [ index*10**7 index in raw_y if index or index==0 ] x = np.array(temps) y = np.array(fluo) popt, pcov = curve_fit(myfunc, x, y, maxfev=3000) # unities popt2 = list() popt2 = [ popt[0] / 3600 * 10**-7, popt[1] / 3600 * 10**-7, popt[2] / 3600 ] #plot data clf() #matplotlib plot(raw_x, raw_y, "rp") plot(raw_x, myfunc(raw_x, popt2[0], popt2[1], popt2[2]), 'b') grid(true) show()
and here picture illustrating difference:
http://i.imgur.com/yxkjg5j.png
the blue plot fitting curve using parameters obtained units rescaling (and transformed in unities). green 1 curve obtained fitting in original unities.
thanks of help.
just use curve_fit
in scipy.optimize
:
import numpy np scipy.optimize import curve_fit pylab import * def myfunc(t, v, w, k): y = v * t - ((v - w) * (1 - np.exp(-k * t)) / k) return y # generates fake data fit. youm read in # data in csv or whatever you've x = np.linspace(0,4,50) y = myfunc(x, 2.5, 1.3, 0.5) # add noise fake data make more realistic. . . yn = y + 0.2*np.random.normal(size=len(x)) #fit data, return best fit parameters , covariance matrix popt, pcov = curve_fit(myfunc, x, yn) print popt print pcov #plot data clf() plot(x, yn, "rs") #overplot best fit curve plot(x, myfunc(x, popt[0], popt[1], popt[2])) grid(true) show()
this gives plot below. red points (noisy) data, , blue line best fit curve, best fitting parameters particular data of:
[ 2.32751132, 1.27686053, 0.65986596]
which pretty close expected parameters of 2.5, 1.3, 0.5. difference due noise added in fake data.
Comments
Post a Comment