How do I put a constraint on SciPy curve fit?

前端 未结 5 1985
旧巷少年郎
旧巷少年郎 2020-11-30 10:11

I\'m trying to fit the distribution of some experimental values with a custom probability density function. Obviously, the integral of the resulting function should always b

5条回答
  •  渐次进展
    2020-11-30 10:30

    Here is an almost-identical snippet which makes only use of curve_fit.

    import matplotlib.pyplot as plt
    import numpy as np
    import scipy.optimize as opt
    import scipy.integrate as integr
    
    
    x = np.linspace(0, np.pi, 100)
    y = np.sin(x) + (0. + np.random.rand(len(x))*0.4)
    
    def Func(x, a0, a1, a2, a3):
        return a0 + a1*x + a2*x**2 + a3*x**3
    
    # modified function definition with Penalization
    def FuncPen(x, a0, a1, a2, a3):
        integral = integr.quad( Func, 0, np.pi, args=(a0,a1,a2,a3))[0]
        penalization = abs(2.-integral)*10000
        return a0 + a1*x + a2*x**2 + a3*x**3 + penalization
    
    
    popt1, pcov1 = opt.curve_fit( Func, x, y )
    popt2, pcov2 = opt.curve_fit( FuncPen, x, y )
    
    y_fit1 = Func(x, *popt1)
    y_fit2 = Func(x, *popt2)
    
    plt.scatter(x,y, marker='.')
    plt.plot(x,y_fit2, color='y', label='constrained')
    plt.plot(x,y_fit1, color='g', label='curve_fit')
    plt.legend(); plt.xlim(-0.1,3.5); plt.ylim(0,1.4)
    print 'Exact   integral:',integr.quad(np.sin ,0,np.pi)[0]
    print 'Approx integral1:',integr.quad(Func,0,np.pi,args=(popt1[0],popt1[1],
                                                    popt1[2],popt1[3]))[0]
    print 'Approx integral2:',integr.quad(Func,0,np.pi,args=(popt2[0],popt2[1],
                                                    popt2[2],popt2[3]))[0]
    plt.show()
    
    #Exact   integral: 2.0
    #Approx integral1: 2.66485028754
    #Approx integral2: 2.00002116217
    

提交回复
热议问题