最小问题传递参数Python

时间:2017-04-10 07:33:41

标签: python curve-fitting least-squares bspline function-fitting

我正在尝试使用以下函数:将SNR enter image description here释放到我的数据中。 C1,C2和h是我需要从leastsq方法获得的参数。 C1和C2很简单,但问题是我的h(t)实际上是Function based on B-Splines。我想要获得的是该函数内部的系数hj(在我的例子中有35个不同的hj)。该函数是不同基础B样条的和,每个基线的B样条加权不同,系数的数量等于B样条的节数。因为我想获得C1,C2和h1..35,我会做以下事情:

funcLine = lambda tpl, eix_x: (tpl[0]*np.sin((4*math.pi*np.sum(bsplines_evaluades * np.transpose([tpl[2],tpl[3],tpl[4],tpl[5],tpl[6],tpl[7],tpl[8],tpl[9],tpl[10],tpl[11],tpl[12],tpl[13],tpl[14],tpl[15],tpl[16],tpl[17],tpl[18],tpl[19],tpl[20],tpl[21],tpl[22],tpl[23],tpl[24],tpl[25],tpl[26],tpl[27],tpl[28],tpl[29],tpl[30],tpl[31],tpl[32],tpl[33],tpl[34],tpl[35],tpl[36],tpl[37]]) , axis=0))*eix_x/lambda1) + tpl[1]*np.cos((4*math.pi*np.sum(bsplines_evaluades * np.transpose([tpl[2],tpl[3],tpl[4],tpl[5],tpl[6],tpl[7],tpl[8],tpl[9],tpl[10],tpl[11],tpl[12],tpl[13],tpl[14],tpl[15],tpl[16],tpl[17],tpl[18],tpl[19],tpl[20],tpl[21],tpl[22],tpl[23],tpl[24],tpl[25],tpl[26],tpl[27],tpl[28],tpl[29],tpl[30],tpl[31],tpl[32],tpl[33],tpl[34],tpl[35],tpl[36],tpl[37]]) , axis=0))*eix_x/lambda1))*np.exp(-4*np.power(k, 2)*lambda_big*np.power(eix_x, 2))
func = funcLine
ErrorFunc = lambda tpl, eix_x, ydata: np.power(func(tpl, eix_x) - ydata,2)
tplFinal1, success = leastsq(ErrorFunc, [2, -2, 8.2*np.ones(35)], args=(eix_x, ydata))

tpl(0)= C1,tpl(1)= C2和tpl(2..35)=我的系数。 bsplines_evaluades是一个矩阵[35,86000],其中每一行是每个基础b样条的时间函数,所以我用每个单独的系数加权每一行,86000是eix_x的长度。 ydata(eix_x)是我想要近似的函数。 lambda1 = 0.1903; lambda_big = 2; K = 2 * PI / lambda1。输出是相同的初始参数,而不是逻辑。 谁能帮我?我也尝试过使用curvefit,但它不起作用。 数据位于:http://www.filedropper.com/data_5>http://www.filedropper.com/download_button.png width = 127 height = 145 border = 0 />
http:// www .filedropper.com>在线备份存储

修改 现在的代码是:

lambda1 = 0.1903
k = 2 * math.pi / lambda1
lambda_big = 2
def funcLine(tpl, eix_x):
    C1, C2, h = tpl[0], tpl(1), tpl[2:]
    hsum = np.sum(bsplines_evaluades * h, axis=1)  # weight each
    theta = 4 * np.pi * np.array(hsum) * np.array(eix_x) / lambda1
    return (C1*np.sin(theta)+C2*np.cos(theta))*np.exp(-4*lambda_big*(k*eix_x)**2)  # lambda_big = 2
if len(eix_x) != 0:
    ErrorFunc = lambda tpl, eix_x, ydata: funcLine(tpl, eix_x) - ydata
    param_values = 7.5 * np.ones(37)
    param_values[0] = 2
    param_values(1) = -2
    tplFinal2, success = leastsq(ErrorFunc, param_values, args=(eix_x, ydata))

问题是输出参数与初始参数相比没有变化。数据(x_axis,ydata,bsplines_evaluades): gist.github.com/hect1995/dcd36a4237fe57791d996bd70e7a9fc7 gist.github.com/hect1995/39ae4768ebb32c27f1ddea97e24d96af gist.github.com/hect1995/bddd02de567f8fcbedc752371b47ff71

2 个答案:

答案 0 :(得分:0)

这里可能有一些问题:我不确定您是否正确索引tpl数组(如果它有37个条目,则索引应为0:36)。并且你的errorFunc应该返回残差而不是平方残差。

最后,我认为您的h-sum可能不正确:您想要总结$ N $轴而不是$ x $轴,对吗?

您可以按照以下方式整理代码,看看它是否有帮助(没有一些数据,我自己很难测试):

def funcLine(tpl, eix_x):
    C1, C2, h = tpl[0], tpl[1], tpl[2:]
    hsum = np.sum(bsplines_evaluades * h, axis=1)
    theta = 4 * np.pi * hsum * eix_x / lambda1
    return (C1 * np.sin(theta) + C2 * np.cos(theta)) * np.exp(-4  *lambda_big *
                 (k * eix_x)**2)

errorFunc = lambda tpl, eix_x, ydata: funcLine(tpl, eix_x) - ydata
tplFinal2, success = leastsq(errorFunc, [2, -2, 8.2*np.ones(35)],
                             args=(eix_x, ydata))

答案 1 :(得分:0)

总是有帮助(对我们自己以及我们)提供一个足以完全可运行的可读示例。你的lambda和非常长的行的例子肯定是不可读的,这使你很容易错过简单的错误。使用Python的一个要点是使代码更容易阅读。

将样条曲线系数作为拟合变量很好,但是您希望将变量的np.ndarray精确地设置为1维。所以你的参数数组应该是

param_values = 8.2 * np.ones(37)
param_values[0] = 2
param_values[1] = -2.
result_params, success = leastsq(errorFunc, param_values, ....)

使用curve_fit()也应该没问题。除此之外,很难提供很多帮助,因为既没有提供完整的可运行程序(保留许多未定义的术语),也没有提供运行代码的输出或错误消息。

相关问题