levenberg marquardt曲线拟合MATLAB

时间:2012-07-30 08:50:25

标签: matlab least-squares levenberg-marquardt

在此处输入图片说明我不知道如何在MATLAB中为lb选择ublsqcurvefit,以及x0,以使我的函数适合数据,我的意思是我有一些输出,但它们不正确,

这是我的数据:

xdata= [22.8700000000000;7.92000000000000;3.45000000000000;1.78000000000000;
        1.57000000000000;6.41000000000000;12.9000000000000;1.82000000000000;
        1.86000000000000;3.71000000000000;12.0900000000000;15.9900000000000;
        18.9600000000000;23.1500000000000;23.4500000000000;24.8200000000000;
        25.0700000000000;13.2800000000000];
ydata= [8.44300000000000;7.92100000000000;7.64600000000000;7.51600000000000;
        7.47100000000000;7.82100000000000;8.03200000000000;7.76200000000000;
        7.77400000000000;7.87800000000000;8.07000000000000;8.26000000000000;
        8.40000000000000;8.52000000000000;8.52000000000000;8.57000000000000;
        8.58000000000000;8.03200000000000];

然后我将myfunc放在一个单独的m文件中:

 function F = myfun(x,xdata)
  F=x(1)*(1-x(2)^2)./((1+x(2)^2+2*x(2)*cosd(xdata)).^1.5);

我有x(1)x(2),我想在拟合数据后估计不知道,而且我知道k x(2)不会是负值。

所以我像这样设置lsqcurvefit

[x, resnorm]=lsqcurvefit(@myfun,[-0.5:0.5], xdata, ydata, 0, 1.5, options)

这就是结果:

  

x = 1.5000 -0.4945
  resnorm = 52.1739

显示x(2)的负值!

你可以帮我吗?

非常感谢你回答我的问题,现在在命令计算出x和resnorm之后,我在我的函数中使用了结果,这意味着我使用了x(1)= 92.8054 x(2)= 0.7427

如此;

F = 92.8054 *(1-(0.7427)^ 2)./((1-0.7427)^ 2 + 2 *(0.7427)* COSD(XDATA))^ 1.5;

现在我有矢量F,当我绘制数据和结果时,绘图(xdata,ydata,'o',xdata,F,'*')

我不知道为什么轴y的范围是如此不同!也许我需要在我的函数中添加x(3)。

我附上了这个数字。enter image description here

enter image description here

enter image description here

3 个答案:

答案 0 :(得分:1)

您的上边界和下边界必须是与您尝试估算的元素数量相同的向量,在您的情况下为x。

因此,例如,如果您希望x(1)无界,x(2)介于0和1.5之间,请尝试

[x, resnorm]=lsqcurvefit(@myfun,[-0.5:0.5], xdata, ydata, [-inf, 0], [inf, 1.5], options)

要计算F,请使用您已创建的目标函数:

F = myfun(x, xdata)然后以您已有的方式绘制它。在下面的评论中,您已将+切换为-,这就是您的图表未对齐的原因。

答案 1 :(得分:1)

参数lbub是输出的下限和上限,即优化后的值xopt将满足lb <= xopt <= ub

正如您所知,x(2)不能为负数,您已经有一个下限 为零,即lb(2) = 0。现在,您只需要定义x(1)的下限和x(1)x(2)的上限。

以下代码将限制x(1) to [-inf, 1e3]x(2) to [0, 1e3]

lb = [-inf, 0];
ub = [1e3, 1e3];
[x, resnorm] = lsqcurvefit(@myfun,[-0.5:0.5], xdata, ydata, 0, 1.5, ...
                           lb, ub, options)

我也有点觉得你的方法很有效。根据{{​​3}}, 你应该传递空向量,如果你没有上限或下限但想要提供options,你的例子应该是

[x, resnorm] = lsqcurvefit(@myfun,[-0.5:0.5], xdata, ydata, 0, 1.5, ...
                           [], [], options)

可能我们有不同版本的Matlab。

答案 2 :(得分:0)

为什么不使用简单的最小二乘解决方案:

in = [ones(size(xdata, 1), 1), xdata];
w = in \ ydata;
ydata_fit = in * w;

结果:

enter image description here

>> disp(w)
    7.5744
    0.0401