# 比较 `lsqnonlin` 和 `fmincon` 的约束非线性最小二乘法

• 迭代次数

• 函数计数数量

• 残差结果

`runlsqfmincon;`

• 对于每个 $N$`fmincon` 的迭代次数是 `lsqnonlin` 的两倍多，并且随着 $N$ 近似线性增加。

• 迭代次数不依赖于导数估计方案。

• 有限差分 (FD) 估计的函数数量比自动微分的函数数量高得多。

• 对于相同的导数估计方案，`lsqnonlin` 的函数计数低于 `fmincon` 的函数计数。

• 残差与所有解方法相匹配，这意味着结果与求解器和导数估计方案无关。

### 辅助函数

```function [lsq,lsqfd,fmin,fminfd] = runlsqfmincon() optslsq = optimoptions("lsqnonlin",Display="none",... MaxFunctionEvaluations=1e5,MaxIterations=1e4); % Allow for many iterations and Fevals optsfmincon = optimoptions("fmincon",Display="none",... MaxFunctionEvaluations=1e5,MaxIterations=1e4); % Create structures to hold results z = zeros(1,50); lsq = struct('Iterations',z,'Fcount',z,'Residual',z); lsqfd = lsq; fmin = lsq; fminfd = lsq; rng(1) % Reproducible initial points x00 = -1/2 + randn(50,1); y00 = 1/2 + randn(50,1); for N = 1:50 x = optimvar("x",N,LowerBound=-3,UpperBound=3); y = optimvar("y",N,LowerBound=0,UpperBound=9); prob = optimproblem("Objective",sum((10*(y - x.^2)).^2 + (1 - x).^2)); x0.x = x00(1:N); x0.y = y00(1:N); % Include a set of nonlinear inequality constraints cons = optimconstr(N); for i = 1:N cons(i) = x(i)^2 + y(i)^2 <= 1/2 + 1/8*i; end prob.Constraints = cons; [sol,fval,exitflag,output] = solve(prob,x0,Options=optslsq); lsq.Iterations(N) = output.iterations; lsq.Fcount(N) = output.funcCount; lsq.Residual(N) = fval; [sol,fval,exitflag,output] = solve(prob,x0,Options=optslsq,... ObjectiveDerivative='finite-differences',ConstraintDerivative='finite-differences'); lsqfd.Iterations(N) = output.iterations; lsqfd.Fcount(N) = output.funcCount; lsqfd.Residual(N) = fval; [sol,fval,exitflag,output] = solve(prob,x0,Options=optsfmincon,Solver="fmincon"); fmin.Iterations(N) = output.iterations; fmin.Fcount(N) = output.funcCount; fmin.Residual(N) = fval; [sol,fval,exitflag,output] = solve(prob,x0,Options=optsfmincon,Solver="fmincon",... ObjectiveDerivative='finite-differences',ConstraintDerivative='finite-differences'); fminfd.Iterations(N) = output.iterations; fminfd.Fcount(N) = output.funcCount; fminfd.Residual(N) = fval; end N = 1:50; plot(N,lsq.Iterations,'k',N,lsqfd.Iterations,'b--',N,fmin.Iterations,'g',N,fminfd.Iterations,'r--') legend('lsqnonlin','lsqnonlin FD','fmincon','fmincon FD','Location','northwest') xlabel('N') ylabel('Iterations') title('Iterations') figure semilogy(N,lsq.Fcount,'k',N,lsqfd.Fcount,'b--',N,fmin.Fcount,'g',N,fminfd.Fcount,'r--') legend('lsqnonlin','lsqnonlin FD','fmincon','fmincon FD','Location','northwest') xlabel('N') ylabel('log(Function count)') title('Function count, log-scaled') figure plot(N,lsq.Residual,'k',N,lsqfd.Residual,'b--',N,fmin.Residual,'g',N,fminfd.Residual,'r--') legend('lsqnonlin','lsqnonlin FD','fmincon','fmincon FD','Location','southeast') xlabel('N') ylabel('Residual') ylim([0,0.4]) title('Residual') end```