Сгенерируйте код для 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

Шаги генерации кода

Чтобы решить ту же проблему с помощью генерации кода, выполните следующие шаги.

  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)

Похожие темы