主要内容

非线性数据拟合

此示例显示了如何使用多种优化工具箱™算法将非线性函数拟合到数据。

问题设置

考虑以下数据:

数据=...[0.0000 5.8955 0.1000 3.5639 0.2000 2.5173 0.3000 1.9790 0.4000 1.8990 0.5000 1.3938 0.6000 1.1359 0.7000 1.0096 0.8000 1.0343 0.9000 0.8435 1.0000 0.6856 1.1000 0.6100 1.2000 0.5392 1.3000 0.3946 1.4000 0.3903 1.5000 0.5474 1.6000 0.3459 1.7000 0.1370 1.8000 0.2211 1.9000 0.1704 2.0000 0.2636];

让我们绘制这些数据点。

t = data(:,1);y = data(:,2);%轴([0 2 -0.5 6])% 坚持,稍等情节(t,y,'ro') 标题('数据点'

图包含一个轴对象。带有标题数据点的轴对象包含类型行的对象。

%阻止

我们想适合该功能

y = c(1)*exp(-lam(1)*t) + c(2)*exp(-lam(2)*t)

到数据。

解决方案方法使用lsqcurvefit

lsqcurvefit功能可以轻松解决此类问题。

首先,用一个变量x来定义参数:

x(1)= c(1)

x(2)= lam(1)

x(3)= c(2)

X(4)= LAM(2)

然后将曲线定义为参数X的函数,数据t:

f = @(x,xdata)x(1)*exp(-x(2)*xdata) + x(3)*exp(-x(4)*xdata);

我们任意设置初始点x0如下:c(1)= 1,lam(1)= 1,c(2)= 1,lam(2)= 0:

x0 = [1 1 1 0];

我们运行求解器并绘制结果拟合。

[x,resnorm,〜,exitflag,output] = lsqcurvefit(f,x0,t,y)
当地的最低限度。LSQCURVEFIT停止了,因为平方之和相对于其初始值的最终变化小于函数公差的值。
x =1×43.0068 10.5869 2.8891 1.4003
RESNORM = 0.1477
出口= 3
输出=带有字段的结构:FirstorderOpt:7.8830E-06迭代:6 FUNCCOUNT:35 CGITERATIONS:0算法:“ Trust-Region-Reflyception”步骤:0.0096消息:“本地最小值可能...。
抓住图(t,f(x,t))保持离开

图包含一个轴对象。带有标题数据点的轴对象包含2个类型行的对象。

解决方案方法使用fminunc

使用fminunc,我们将目标函数设置为残差的平方之和。

fsumsquares = @(x)sum((f(x,t)-y)。^2);opts = optimoptions('fminunc',,,,'算法',,,,“准牛顿”);[xunc,ressquared,eflag,outputu] =...fminunc(fsumsquares,x0,opts)
找到局部最低限度。完成优化是因为梯度的大小小于最佳公差的值。
xunc =1×42.8890 1.4003 3.0069 10.5862
ressquared = 0.1477
eflag = 1
outputu =带有字段的结构:迭代:30 Funccount:185步骤:0.0017 LSSteplength:1 FirstorderOpt:2.9662e-05算法:“ Quasi-Newton”消息:“找到的本地最低最低限度....

注意fminunc找到与lsqcurvefit,但要进行更多的功能评估。参数fminunc与那些相反的顺序lsqcurvefit;较大的林是LAM(2),而不是Lam(1)。这不足为奇,变量的顺序是任意的。

fprintf([“使用fminunc有%d迭代,”...'和%d使用lsqcurvefit。\ n'],,...outputu.Iterations,output.Iterations)
使用fminunc进行了30次迭代,使用LSQCurveFit进行了6次迭代。
fprintf([“使用fminunc进行了%d函数评估”...“和%d使用LSQCurveFit。”],,...outputu.funccount,output.funccount)
使用Fminunc进行了185个功能评估,使用LSQCurveFit进行了35个功能。

分解线性和非线性问题

请注意,拟合问题是参数C(1)和C(2)中的线性。这意味着任何LAM(1)和LAM(2)的值,我们可以使用后斜线操作员找到解决最小二乘问题的C(1)和C(2)的值。

现在,我们将问题重新解决为二维问题,以寻找LAM(1)和LAM(2)的最佳值。如上所述,使用后斜线操作员在每个步骤中计算C(1)和C(2)的值。

类型FitVector
函数yest = fitVector(LAM,XDATA,YDATA)%fitvector datdemo用于返回拟合功能的值。%yest = fitvector(LAM,XDATA)返回拟合函数的值y%(以下定义),在数据点XDATA上,参数设置为LAM。%yest作为N-1列向量返回,其中n是%数据点的数量。%fitVector假设拟合函数y,以%%y = c(1)*exp(-lam(1)*t) + ... + c(n)*exp(-lam(-lam(n)*)t)n线性参数c和n非线性参数lam的%%。为了求解线性参数C的%%,我们构建一个矩阵A%,其中a的j-th列是exp(-lam(j)*xdata)(xdata是矢量)。%然后,我们为线性最小二乘解决方案C求解A*c = ydata,其中ydata是观察到的y的值。a = zeros(长度(xdata),长度(lam));%构建j = 1的矩阵:长度(lam)a(:,j)= exp(-lam(j)*xdata);结束c = a \ ydata;%求解A*c = y对于线性参数c Yest = a*c; % return the estimated response based on c

使用lsqcurvefit,从二维初始点Lam(1),Lam(2):

x02 = [1 0];f2 = @(x,t)fitvector(x,t,y);[x2,resnorm2,〜,exitflag2,output2] = lsqcurvefit(f2,x02,t,y)
当地的最低限度。LSQCURVEFIT停止了,因为平方之和相对于其初始值的最终变化小于函数公差的值。
x2 =1×210.5861 1.4003
RESNORM2 = 0.1477
Exitflag2 = 3
output2 =带有字段的结构:FirstorderOpt:4.4087E-06迭代:10 Funccount:33 Cgiterations:0算法:'Trust-Region-Refrofection'Stepize:0.0080消息:0.0080消息:'本地最小值可能......................................................

二维解决方案的效率与四维解决方案相似:

fprintf([“使用2-D进行%D功能评估”...使用4-D公式的公式和%d。”],,...output2.funccount,output.funccount)
使用2-D公式进行了33个功能评估,使用4-D公式进行了35个功能。

拆分问题对初始猜测更为强大

为原始四参数问题选择一个不良的起点会导致一个不是全局的本地解决方案。用相同的不良LAM(1)和LAM(2)值选择一个拆分两参数问题的起点会导致全局解决方案。为了证明这一点,我们将原始问题重新运行,从而导致相对较差的本地解决方案,并将结果拟合与全局解决方案进行比较。

x0bad = [5 1 1 0];[xbad,resnormbad,〜,exitflagbad,outputbad] =...lsqcurvefit(f,x0bad,t,y)
当地的最低限度。LSQCURVEFIT停止了,因为平方之和相对于其初始值的最终变化小于函数公差的值。
xbad =1×4-22.9036 2.4792 28.0273 2.4791
ResnormBad = 2.2173
exitflagbad = 3
outputbad =带有字段的结构:FirstOrderOpt:0.0056迭代:32 Funccount:165 CGITERATIONS:0算法:“ Trust-Region-Reflyceptive”步骤:0.0021消息:“本地最小值可能...。
抓住图(t,f(xbad,t),'G') 传奇('数据',,,,“全球拟合”,,,,“不良本地合身”,,,,'地点',,,,'ne') 抓住离开

图包含一个轴对象。带有标题数据点的轴对象包含3个类型行的对象。这些对象代表数据,全球拟合,局部拟合不良。

fprintf([“良好终点的剩余规范是%f,”...“不良终点的剩余规范是%f。”],,...RESNORM,RESNORMBAD)
良好终点的剩余规范为0.147723,不良终点的残留规范为2.217300。

相关话题