为 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® 中的问题,请设置选项和初始点。另外,请将 UseCodegenSolver
选项设置为 true
,以便可以在 MATLAB 中使用生成的相同代码来验证结果。
x0 = zeros(size(d)); options = optimoptions("lsqlin",... Algorithm="active-set",UseCodegenSolver=true);
要求解该问题,请调用 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);
Number of solution components at lower bounds: 3
fprintf('Number of solution components at upper bounds: %g\n',nu);
Number of solution components at upper bounds: 2
fprintf('Number of solution components at inequality: %g\n',ni);
Number of solution components at inequality: 5
fprintf('Number of unconstrained solution components: %g\n',nunonstrained);
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",UseCodegenSolver=true); [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
Code generation successful.
通过运行名为
solvelsqlin_mex.mexw64
或类似名称的生成文件来测试生成的代码。[x2,fv2,lam2] = solvelsqlin_mex;
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
这两个解具有相同类型的拉格朗日乘数数量。检查返回的解之间的差异。
disp([norm(x - x2), abs(fv - fv2)])
1.0e-12 * 0.0006 0.4547
这两种解之间的差异可以忽略不计。
另请参阅
quadprog
| lsqlin
| codegen
(MATLAB Coder) | optimoptions