为 lsqcurvefit
或 lsqnonlin
生成代码
此示例显示如何生成非线性最小二乘的 C 代码。
最小二乘的数据和模型
在此示例中,向量 xdata
表示 100 个数据点,向量 ydata
表示相关联的测量值。xdata
和 ydata
之间的建模关系是
生成问题的数据。
rng(5489,'twister') % For reproducibility xdata = -2*log(rand(100,1)); ydata = (ones(100,1) + .1*randn(100,1)) + (3*ones(100,1)+... 0.5*randn(100,1)).*exp((-(2*ones(100,1)+... 0.5*randn(100,1))).*xdata);
该代码基于 100 个独立样本(服从均值为 2 的指数分布)生成 xdata
。该代码使用 a = [1;3;2]
从其定义方程生成 ydata
,并通过添加具有标准差 [0.1;0.5;0.5]
的正态偏差进行扰动。
求解 lsqcurvefit
的生成代码
求解器方法
目标是找到最适合数据的模型 , i = 1, 2, 3 的参数。
为了使用 lsqcurvefit
将参数拟合到数据,您需要定义一个拟合函数。对于 lsqcurvefit
,拟合函数采用参数向量 a
和数据 xdata
并返回响应的预测,该预测应该等于 ydata
,没有噪音且模型完美。将拟合函数 predicted
定义为匿名函数。
predicted = @(a,xdata) a(1)*ones(100,1)+a(2)*exp(-a(3)*xdata);
为了对数据进行模型拟合,lsqcurvefit
需要参数的初始估计值 a0
。
a0 = [2;2;2];
调用 lsqcurvefit
以找到最佳拟合参数 。
[ahat,resnorm,residual,exitflag,output,lambda,jacobian] =...
lsqcurvefit(predicted,a0,xdata,ydata);
代码生成方法
要使用代码生成求解相同的问题,请完成以下步骤。
编写一个包含所有前面步骤的函数:生成数据、创建拟合函数、创建初始点并调用
lsqcurvefit
。function [x,res] = solvelsqcurve rng(5489,'twister') % For reproducibility xdata = -2*log(rand(100,1)); ydata = (ones(100,1) + .1*randn(100,1)) + (3*ones(100,1)+... 0.5*randn(100,1)).*exp((-(2*ones(100,1)+... 0.5*randn(100,1))).*xdata); predicted = @(a,xdata) a(1)*ones(100,1)+a(2)*exp(-a(3)*xdata); options = optimoptions('lsqcurvefit','Algorithm','levenberg-marquardt','Display','off'); a0 = [2;2;2]; lb = []; ub = []; [x,res] = lsqcurvefit(predicted,a0,xdata,ydata,lb,ub,options); end
创建代码生成的配置。在本例中,使用
'mex'
。cfg = coder.config('mex');
为
solvelsqcurve
函数生成代码。codegen -config cfg solvelsqcurve
通过运行名为
solvelsqcurve_mex.mexw64
或类似名称的生成文件来测试生成的代码。[x,res] = solvelsqcurve_mex
x = 1.0169 3.1444 2.1596 res = 7.4101
求解 lsqnonlin
的生成代码
求解器方法
目标是找到最适合数据的模型 , i = 1, 2, 3 的参数。
为了使用 lsqnonlin
将参数拟合到数据,您需要定义一个拟合函数。对于 lsqnonlin
,拟合函数采用参数向量 a
、数据 xdata
和数据 ydata
。拟合函数返回响应预测与数据 ydata
之间的差异,在没有噪音和完美模型的情况下,该差异应该等于 0。将拟合函数 predicted
定义为匿名函数。
predicted = @(a)(a(1)*ones(100,1)+a(2)*exp(-a(3)*xdata) - ydata)
为了对数据进行模型拟合,lsqnonlin
需要参数的初始估计值 a0
。
a0 = [2;2;2];
调用 lsqnonlin
以找到最佳拟合参数 。
[ahat,resnorm,residual,exitflag,output,lambda,jacobian] =...
lsqnonlin(predicted,a0);
代码生成方法
要使用代码生成求解相同的问题,请完成以下步骤。
编写一个包含所有前面步骤的函数:生成数据、创建拟合函数、创建初始点并调用
lsqnonlin
。function [x,res] = solvelsqnon rng(5489,'twister') % For reproducibility xdata = -2*log(rand(100,1)); ydata = (ones(100,1) + .1*randn(100,1)) + (3*ones(100,1)+... 0.5*randn(100,1)).*exp((-(2*ones(100,1)+... 0.5*randn(100,1))).*xdata); predicted = @(a) (a(1)*ones(100,1)+a(2)*exp(-a(3)*xdata) - ydata); options = optimoptions('lsqnonlin','Algorithm','levenberg-marquardt','Display','off'); a0 = [2;2;2]; lb = []; ub = []; [x,res] = lsqnonlin(predicted,a0,lb,ub,options); end
创建代码生成的配置。在本例中,使用
'mex'
。cfg = coder.config('mex');
为
solvelsqnon
函数生成代码。codegen -config cfg solvelsqnon
通过运行名为
solvelsqnon_mex.mexw64
或类似名称的生成文件来测试生成的代码。[x,res] = solvelsqnon_mex
x = 1.0169 3.1444 2.1596 res = 7.4101
该解与
solvelsqcurve_mex
生成的解相同,因为求解器具有相同的底层算法。因此,您可以使用您认为最方便的求解器。
另请参阅
lsqcurvefit
| lsqnonlin
| codegen
(MATLAB Coder) | optimoptions