Main Content

lsqlin 生成代码

求解线性最小二乘问题

为最小化受边界和线性不等式约束的 C*x – d 范数的问题创建伪随机数据。创建一个包含 15 个变量的问题,受边界 lb = –1ub = 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

代码生成步骤

要使用代码生成求解相同的问题,请完成以下步骤。

  1. 编写一个包含所有前面步骤的函数。为了产生更少的输出,请将 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
  2. 创建代码生成的配置。在本例中,使用 'mex'

    cfg = coder.config('mex');
  3. solvelsqlin 函数生成代码。

    codegen -config cfg solvelsqlin
  4. 通过运行名为 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
  5. 各个边界处的解分量的数量与之前的解相比发生了变化。要了解这些差异是否重要,请比较求解解点差异和函数值差异。

    disp([norm(x - x2), abs(fv - fv2)])
       1.0e-12 *
    
        0.0007    0.2274

    这两种解之间的差异可以忽略不计。

另请参阅

| | (MATLAB Coder) |

相关主题