matlab最小二乘函数,Matlab最小二乘法 函数 lsqcurvefit   nlinfit

clear;clc

x0=[-2 -1.7 -1.4 -1.1 -0.8 -0.5 -0.2 0.1 0.4 0.7 1 1.3 1.6 1.9 2.2

2.5 2.8 3.1 3.4 3.7 4.0 4.3 4.6 4.9];

y0=[0.10289 0.11741 0.13158 0.14483 0.15656 0.16622 0.17332 0.1775

0.17853 0.17635 0.17109 0.16302 0.15255 0.1402 0.12655 0.11219

0.09768 0.08353 0.07015 0.05786 0.04687 0.03729 0.02914

0.02236];

f=@(a,x)1/(sqrt(2*pi)*a(1))*exp(-(x-a(2)).^2/(2*a(1)^2));

a=lsqcurvefit(f,[2,2],x0,y0)

x1=-2:0.1:5;

f1=1/(sqrt(2*pi)*a(1))*exp(-(x1-a(2)).^2/(2*a(1)^2));

plot(x0,y0,x1,f1,'*r')

非线性曲线拟合是已知输入向量xdata和输出向量ydata,并且知道输入与输出的函数关系为ydata=F(x,

xdata),但不知道系数向量x。今进行曲线拟合,求x使得输出的如下最小二乘表达式成立:

min Σ(F(x,xdatai)-ydatai)^2

函数 lsqcurvefit

格式 x = lsqcurvefit(fun,x0,xdata,ydata)

x = lsqcurvefit(fun,x0,xdata,ydata,lb,ub)

x = lsqcurvefit(fun,x0,xdata,ydata,lb,ub,options)

[x,resnorm] = lsqcurvefit(…)

[x,resnorm,residual] = lsqcurvefit(…)

[x,resnorm,residual,exitflag] = lsqcurvefit(…)

[x,resnorm,residual,exitflag,output] = lsqcurvefit(…)

[x,resnorm,residual,exitflag,output,lambda] = lsqcurvefit(…)

[x,resnorm,residual,exitflag,output,lambda,jacobian]

=lsqcurvefit(…)

参数说明:

x0为初始解向量;xdata,ydata为满足关系ydata=F(x, xdata)的数据;

lb、ub为解向量的下界和上界lb≤x≤ub,若没有指定界,则lb=[ ],ub=[ ];

options为指定的优化参数;

fun为待拟合函数,计算x处拟合函数值,其定义为 function F = myfun(x,xdata)

resnorm=sum ((fun(x,xdata)-ydata).^2),即在x处残差的平方和;

residual=fun(x,xdata)-ydata,即在x处的残差;

exitflag为终止迭代的条件;

output为输出的优化信息;

lambda为解x处的Lagrange乘子;

jacobian为解x处拟合函数fun的jacobian矩阵。

例 求解如下最小二乘非线性拟合问题

已知输入向量xdata和输出向量ydata,且长度都是n,待拟合函数的表达式为

ydata(i)=x(1)-xdata(i)^2+x(2)-sin(xdata(i))+x(3)-xdata^3

即目标函数为min Σ(F(x,xdata(i))-ydata(i))^2

其中:F(x,xdata) = x(1)*xdata^2 + x(2)*sin(xdata) + x(3)*xdata^3

初始解向量为x0=[0.3, 0.4, 0.1],即表达式的 个参数[x(1),x(2),x(3)]。

先建立拟合函数文件,并保存为myfun.m

function F = myfun(x,xdata)

F = x(1)*xdata.^2 + x(2)*sin(xdata) + x(3)*xdata.^3;

然后给出数据xdata和ydata

>>xdata = [3.6 7.7 9.3 4.1 8.6 2.8 1.3 7.9 10.0 5.4];

>>ydata = [16.5 150.6 263.1 24.7 208.5 9.9 2.7 163.9 325.0

54.3];

>>x0 = [10, 10, 10]; %初始估计值

>>[x,resnorm] = lsqcurvefit(@myfun,x0,xdata,ydata)

结果为:

Optimization terminated successfully:

Relative function value changing by less than OPTIONS.TolFun

x = 0.2269 0.3385 0.3021

=>即解出的系数最优估计值

resnorm = 6.2950

=>在x解值处的目标最小二乘表达式值。即所谓残差。

问题:有些时候我们需要拟合一些非线性的表达式。

比如:我们知道一个表达式的式子是y=A*sin(x).*exp(x)-B./log(x),现在我们手里面有x与y对应的一大把数据。我们如何根据x,y的值找出最佳的A、B值。则我们现在借助Matlab的函数lsqcurvefit、nlinfit,当然你也可以使用lsqnonlin.其具体用法请自己用Matlab的帮助命令进行查看。这里仅简单介绍一下常用的方式。

注意:如果对初值比较敏感,涉及到初值设置的问题;以及拟合表达式包含积分表达式或者微分项等问题;以及一些拟合降维的问题,可以参看我的另一篇博文《数据拟合遇见》

PS:如果使用Matlab以上函数拟合不出理想的结果的话,可以尝试使用我自己写的《数学计算器》里的nlinFit、nlinFit2、nlinFit4、nlinFitDE、nlinFitGA、nlinFitLM、nlinFitPSO、nlinFitPSO2、nlinFitPSO3函数

格式:lsqcurvefit(f,a,x,y)、nlinfit(x,y,f,a)

f:符号函数句柄,如果是以m文件的形式调用的时候,别忘记加@.这里需要注意,f函数的返回值是和y匹对的,即拟合参数的标准是(f-y)^2取最小值,具体看下面的例子

a:最开始预估的值(预拟合的未知参数的估计值)。如上面的问题如果我们预估A为1,B为2,则a=[1 2]

x:我们已经获知的x的值

y:我们已经获知的x对应的y的值

例子1:

问题:对于函数y=a*sin(x)*exp(x)-b/log(x)我们现在已经有多组(x,y)的数据,我们要求最佳的a,b值

%针对上面的问题,我们可以来演示下如何使用这个函数以及看下其效果

>> x=2:10;

>> y=8*sin(x).*exp(x)-12./log(x);

%上面假如是我们事先获得的值

>> a=[1 2];

>> f=@(a,x)a(1)*sin(x).*exp(x)-a(2)./log(x);

%第一种方法使用lsqcurvefit

>> lsqcurvefit(f,a,x,y)

ans =

7.999999999999987 11.999999999988997%和我们预期的值8和12结合得非常好

>>

%第二种方法使用nlinfit

>> nlinfit(x,y,f,a)

ans =

8.000000000000000 11.999999999999998

>>

%**********************************

%另一种方法,假如我们写了一个如下的m文件

function f=test(a,x)

f=a(1)*sin(x).*exp(x)-a(2)./log(x);

end

%则在上面lsqcurvefit函数调用如下,不要忘记那个@

lsqcurvefit(@test,a,x,y)

例子2:(多元的情况,注意看格式)

问题:我们已知z=a*(exp(y)+1)-sin(x)*b且有多组(x,y,z)的值,现在求最佳系数a,b

>> x=2:10;

>> y=10*sin(x)./log(x);

>> z=4.5*(exp(y)+1)-sin(x)*13.8;

>> f=@(a,x)a(1)*(exp(x(2,:))+1)-sin(x(1,:))*a(2);

%第一种方法使用lsqcurvefit

>> lsqcurvefit(f,[1 2],[x;y],z)%注意这里面的[x;y],这里的[1 2]表示我们设置f函数里的初始值a(1)=1,,a(2)=2

ans =

4.499999999999999 13.800000000000024

%第二种方法使用nlinfit

>> nlinfit([x;y],z,f,[1 2])

ans =

4.500000000000000 13.799999999999956

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值