基于问题的非线性最小二乘
此示例说明如何使用 基于问题的优化工作流 执行非线性最小二乘曲线拟合。
模型
此问题的模型方程是
其中 、、 和 是未知参数, 是响应, 是时间。该问题需要时间 tdata
和(含噪)响应测量 ydata
的数据。目标是找到最佳 和 ,也就是最小化下式的那些值:
样本数据
通常,您有针对某个问题的数据。在这种情况下,请为该问题生成人为含噪数据。使用 A = [1,2]
和 r = [-1,-3]
作为基础值,使用从 0
到 3 的 200 个随机值作为时间数据。绘制生成的数据点。
rng default % For reproducibility A = [1,2]; r = [-1,-3]; tdata = 3*rand(200,1); tdata = sort(tdata); % Increasing times for easier plotting noisedata = 0.05*randn(size(tdata)); % Artificial noise ydata = A(1)*exp(r(1)*tdata) + A(2)*exp(r(2)*tdata) + noisedata; plot(tdata,ydata,'r*') xlabel 't' ylabel 'Response'
数据是含噪数据。因此,该解可能不会很好地匹配原始参数 A
和 r
。
基于问题的方法
要找到最佳拟合参数 A
和 r
,首先用这些名称定义优化变量。
A = optimvar('A',2); r = optimvar('r',2);
为目标函数创建一个表达式,它是要最小化的平方和。
fun = A(1)*exp(r(1)*tdata) + A(2)*exp(r(2)*tdata); obj = sum((fun - ydata).^2);
用目标函数 obj
创建一个优化问题。
lsqproblem = optimproblem("Objective",obj);
对于基于问题的方法,将初始点指定为结构体,并将变量名称作为结构体的字段。指定初始 A = [1/2,3/2]
和初始 r = [-1/2,-3/2]
。
x0.A = [1/2,3/2]; x0.r = [-1/2,-3/2];
检查问题表示。
show(lsqproblem)
OptimizationProblem : Solve for: A, r minimize : sum(arg6) where: arg5 = extraParams{3}; arg6 = (((A(1) .* exp((r(1) .* extraParams{1}))) + (A(2) .* exp((r(2) .* extraParams{2})))) - arg5).^2; extraParams{1}: 0.0139 0.0357 0.0462 0.0955 0.1033 0.1071 0.1291 0.1385 0.1490 0.1619 0.1793 0.2276 0.2279 0.2345 0.2434 0.2515 0.2533 0.2894 0.2914 0.2926 : : extraParams{2}: 0.0139 0.0357 0.0462 0.0955 0.1033 0.1071 0.1291 0.1385 0.1490 0.1619 0.1793 0.2276 0.2279 0.2345 0.2434 0.2515 0.2533 0.2894 0.2914 0.2926 : : extraParams{3}: 2.9278 2.7513 2.7272 2.4199 2.3172 2.3961 2.2522 2.1974 2.1666 2.0944 1.9566 1.7989 1.7984 1.7540 1.8318 1.6745 1.6874 1.5526 1.5229 1.5680 : :
基于问题的解
求解。
[sol,fval] = solve(lsqproblem,x0)
Solving problem using lsqnonlin. Local minimum found. Optimization completed because the size of the gradient is less than the value of the optimality tolerance.
sol = struct with fields:
A: [2x1 double]
r: [2x1 double]
fval = 0.4724
绘制得到的解和原始数据。
figure responsedata = evaluate(fun,sol); plot(tdata,ydata,'r*',tdata,responsedata,'b-') legend('Original Data','Fitted Curve') xlabel 't' ylabel 'Response' title("Fitted Response")
该图显示拟合数据与原始含噪数据匹配良好。
查看拟合参数与原始参数 A = [1,2]
和 r = [-1,-3]
的匹配程度。
disp(sol.A)
1.1615 1.8629
disp(sol.r)
-1.0882 -3.2256
A
中的拟合参数偏差约为 15%,r
中的拟合参数偏差约为 8%。
不受支持的函数要求 fcn2optimexpr
如果您的目标函数不是由初等函数组成,您必须使用 fcn2optimexpr
将该函数转换为优化表达式。请参阅将非线性函数转换为优化表达式。对于本示例:
fun = @(A,r) A(1)*exp(r(1)*tdata) + A(2)*exp(r(2)*tdata); response = fcn2optimexpr(fun,A,r); obj = sum((response - ydata).^2);
求解此问题的其余步骤是相同的。唯一不同是在绘图例程中调用 response
而不是 fun
:
responsedata = evaluate(response,sol);
有关支持的函数列表,请参阅优化变量和表达式支持的运算。