在两个函数范围内拟合数据

时间:2018-06-30 01:03:27

标签: python numpy scipy

我有一组数据,根据一种理论,它们限制在两个范围之内。

上限为:f(x)= 1 / x(x <0.5)

下限是:f(x)= 1 + 1 /(2x)(x <0.5)

我得到的数据接近这两个界限之一。我正在尝试找到一种描述这些数据的功能。但是,如果我使用普通的拟合方法,则拟合曲线可能在这两个边界之外。如何使用scipy.curve_fit强制在这两个边界之间拟合曲线?我正在尝试使用Pade近似值进行拟合,我正在使用的代码如下:

def pfuncp_3_1(x, a0, a1, a2, a3, b1):
    p1 = ((a0+a1*x+a2*x**2+a3*x**3)*(1+b1*x)**(-1)-1-1/(2*x)<0)*2.0
    p2 = ((a0+a1*x+a2*x**2+a3*x**3)*(1+b1*x)**(-1)-1/x>0)*2.0
    return (a0+a1*x+a2*x**2+a3*x**3)*(1+b1*x)**(-1) + p1 + p2


def ffuncp_3_1(x, a0, a1, a2, a3, b1):
    return (a0+a1*x+a2*x**2+a3*x**3)*(1+b1*x)**(-1)


def data_fitter(pfunc, ffunc, fit_x, fit_y, new_x):
    popt, pcov = opt.curve_fit(pfunc, fit_x, fit_ny)
    perr = np.sqrt(np.diag(pcov))
    interp_y = np.zeros(len(interp_x))
    for k in range(len(interp_x)):
        interp_y[k] = ffunc(interp_x[k], *popt)
    return interp_y


if __name__ == "__main__":
    results = data_fitter(pfunc, ffunc, original_x, original_y, interpx)

1 个答案:

答案 0 :(得分:0)

首先,需要找到一个可以发送给scipy.curve_fit的函数,其中包含一些参数,这些参数可以描述我们想要的函数,即1/x1+1/(2x)h(x)=a+1/(b*x)

这将给出参数的上限和下限,如下所示:

1/x代表a=0b=1

1+1/(2x)代表a=1b=2

这意味着a[0,1]中,而b[1,2]中。

现在,我将能够告诉scipy.curve_fit,它必须选择参数abc才能保持在界限内:

import numpy as np
import matplotlib.pyplot as plt
from scipy.optimize import curve_fit

# Generate data
a_true,b_true=.45,1.35
h=lambda x,a,b: a+1/(b*x)
N=100
xmin=0.1
xmax=0.499
x=np.linspace(xmin,xmax,N)
y=h(x,a_true,b_true)+np.random.normal(0,0.05,N)
plt.plot(x,1/x,label="1/x")
plt.plot(x,1+1/(2*x), label="1+1/(2x)")
plt.plot(x,y)
plt.legend()
plt.show()
# Do curve fit
popt, pcov =curve_fit(h,x,y,bounds=[(0,1),(1,2)])
print(popt)
plt.plot(x,1/x,label="1/x")
plt.plot(x,1+1/(2*x), label="1+1/(2x)")
plt.plot(x,h(x,*popt))
plt.show()