为 lsqlin
生成代码
求解线性最小二乘问题
为最小化受边界和线性不等式约束的 C*x – d
范数的问题创建伪随机数据。创建一个包含 15 个变量的问题,受边界 lb = –1
和 ub = 1
的限制,并受 150 个线性约束 A*x <= b
的限制。
N = 15; % Number of variables rng default % For reproducibility A = randn([10*N,N]); b = 5*ones(size(A,1),1); Aeq = []; % No equality constraints beq = []; ub = ones(N,1); lb = -ub; C = 10*eye(N) + randn(N); C = (C + C.')/2; % Symmetrize the matrix d = 20*randn(N,1);
使用 lsqlin
求解
代码生成需要 'active-set'
算法,该算法需要一个初始点 x0
。要使用代码生成所需的算法求解 MATLAB® 中的问题,请设置选项和初始点。
x0 = zeros(size(d)); options = optimoptions('lsqlin','Algorithm','active-set');
要求解该问题,请调用 lsqlin
。
[x,fv,~,ef,output,lam] = lsqlin(C,d,A,b,Aeq,beq,lb,ub,x0,options);
Minimum found that satisfies the constraints. Optimization completed because the objective function is non-decreasing in feasible directions, to within the value of the optimality tolerance, and constraints are satisfied to within the value of the constraint tolerance.
lsqlin
求解这个问题后,查看每种类型的非零拉格朗日乘数的数量。通过减去非零拉格朗日乘数的总数,查看有多少个解分量无约束。
nl = nnz(lam.lower); nu = nnz(lam.upper); ni = nnz(lam.ineqlin); nunconstrained = N - nl - nu - ni; fprintf('Number of solution components at lower bounds: %g\n',nl); fprintf('Number of solution components at upper bounds: %g\n',nu); fprintf('Number of solution components at inequality: %g\n',ni); fprintf('Number of unconstrained solution components: %g\n',nunconstrained);
Number of solution components at lower bounds: 3 Number of solution components at upper bounds: 2 Number of solution components at inequality: 5 Number of unconstrained solution components: 5
代码生成步骤
要使用代码生成求解相同的问题,请完成以下步骤。
编写一个包含所有前面步骤的函数。为了产生更少的输出,请将
Display
选项设置为'off'
。function [x,fv,lam] = solvelsqlin N = 15; % Number of variables rng default % For reproducibility A = randn([10*N,N]); b = 5*ones(size(A,1),1); Aeq = []; % No equality constraints beq = []; ub = ones(N,1); lb = -ub; C = 10*eye(N) + randn(N); C = (C + C.')/2; % Symmetrize the matrix d = 20*randn(N,1); x0 = zeros(size(d)); options = optimoptions('lsqlin','Algorithm','active-set',... 'Display','off'); [x,fv,~,ef,output,lam] = lsqlin(C,d,A,b,Aeq,beq,lb,ub,x0,options); nl = nnz(lam.lower); nu = nnz(lam.upper); ni = nnz(lam.ineqlin); nunconstrained = N - nl - nu - ni; fprintf('Number of solution components at lower bounds: %g\n',nl); fprintf('Number of solution components at upper bounds: %g\n',nu); fprintf('Number of solution components at inequality: %g\n',ni); fprintf('Number of unconstrained solution components: %g\n',nunconstrained); end
创建代码生成的配置。在本例中,使用
'mex'
。cfg = coder.config('mex');
为
solvelsqlin
函数生成代码。codegen -config cfg solvelsqlin
通过运行名为
solvelsqlin_mex.mexw64
或类似名称的生成文件来测试生成的代码。[x2,fv2,lam2] = solvelsqlin_mex;
Number of solution components at lower bounds: 1 Number of solution components at upper bounds: 5 Number of solution components at inequality: 6 Number of unconstrained solution components: 3
各个边界处的解分量的数量与之前的解相比发生了变化。要了解这些差异是否重要,请比较求解解点差异和函数值差异。
disp([norm(x - x2), abs(fv - fv2)])
1.0e-12 * 0.0007 0.2274
这两种解之间的差异可以忽略不计。
另请参阅
quadprog
| lsqlin
| codegen
(MATLAB Coder) | optimoptions