python - How do I put a constraint on SciPy curve fit? -


i'm trying fit distribution of experimental values custom probability density function. obviously, integral of resulting function should equal 1, results of simple scipy.optimize.curve_fit(function, databincenters, datacounts) never satisfy condition. best way solve problem?

you can define own residuals function, including penalization parameter, detailed in code below, known beforehand integral along interval must 2.. if test without penalization see getting conventional curve_fit:

enter image description here

import matplotlib.pyplot plt import scipy scipy.optimize import curve_fit, minimize, leastsq scipy.integrate import quad scipy import pi, sin x = scipy.linspace(0, pi, 100) y = scipy.sin(x) + (0. + scipy.rand(len(x))*0.4) def func1(x, a0, a1, a2, a3):     return a0 + a1*x + a2*x**2 + a3*x**3  # here include penalization factor def residuals(p,x,y):     integral = quad( func1, 0, pi, args=(p[0],p[1],p[2],p[3]))[0]     penalization = abs(2.-integral)*10000     return y - func1(x, p[0],p[1],p[2],p[3]) - penalization  popt1, pcov1 = curve_fit( func1, x, y ) popt2, pcov2 = leastsq(func=residuals, x0=(1.,1.,1.,1.), args=(x,y)) y_fit1 = func1(x, *popt1) y_fit2 = func1(x, *popt2) plt.scatter(x,y, marker='.') plt.plot(x,y_fit1, color='g', label='curve_fit') plt.plot(x,y_fit2, color='y', label='constrained') plt.legend(); plt.xlim(-0.1,3.5); plt.ylim(0,1.4) print 'exact   integral:',quad(sin ,0,pi)[0] print 'approx integral1:',quad(func1,0,pi,args=(popt1[0],popt1[1],                                                 popt1[2],popt1[3]))[0] print 'approx integral2:',quad(func1,0,pi,args=(popt2[0],popt2[1],                                                 popt2[2],popt2[3]))[0] plt.show()  #exact   integral: 2.0 #approx integral1: 2.60068579748 #approx integral2: 2.00001911981 

other related questions:


Comments

Popular posts from this blog

php - mySql Join with 4 tables -

css - Text drops down with smaller window -

c# - DetailsView in ASP.Net - How to add another column on the side/add a control in each row? -