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