Статическое выделение памяти для fmincon Генерация кода

Этот пример показывает, как использовать статическое выделение памяти в генерации кода, даже когда некоторые размеры матрицы изменяются во время расчета.

Задачей является простая нелинейная минимизация как с нелинейной функцией ограничения, так и с линейными ограничениями. Размеры линейных ограничительных матриц изменяются при каждой итерации, что заставляет требования к памяти увеличиваться при каждой итерации. Пример показывает, как использовать coder.varsize команда для установки соответствующих размеров переменных для статического выделения памяти.

The nlp_for_loop.m файл содержит целевую функцию, линейные ограничения и нелинейные ограничения. Скопируйте следующий код, чтобы создать этот файл на MATLAB® путь.

function nlp_for_loop 
% Driver for an example fmincon use case.  Adding constraints increases the
% minimum and uses more memory.

maxIneq = 4; % Number of linear inequality constraints
nVar = 5; % Number of problem variables x

A = zeros(0,nVar);
b = zeros(0,1);

% The next step is required for static memory support. Because you concatenate
% constraints in a "for" loop, you need to limit the dimensions of the
% constraint matrices.
%coder.varsize('var name', [maxRows, maxCols], [canRowsChange, canColsChange]);
coder.varsize('A',[maxIneq,nVar],[true,false]);
coder.varsize('b',[maxIneq,1],[true,false]);

Aeq = [1,0,0,0,1];
beq = 0;
lb = [];
ub = [];

% Initial point
x0 = [2;-3;0;0;-2];

options = optimoptions('fmincon','Algorithm','sqp','Display','none');
for idx = 1:maxIneq
    % Add a new linear inequality constraint at each iteration
    A = [A; circshift([1,1,0,0,0],idx-1)];
    b = [b; -1];
    
    [x,fval,exitflag] = fmincon(@rosenbrock_nd,x0,A,b,Aeq,beq,...
        lb,ub,@circleconstr,options);
    % Set initial point to found point
    x0 = x;
    % Print fval, ensuring that the datatypes are consistent with the
    % corresponding fprintf format specifiers
    fprintf('%i Inequality Constraints; fval: %f; Exitflag: %i \n',...
        int32(numel(b)),fval,int32(exitflag));
end

end


function fval = rosenbrock_nd(x)
fval = 100*sum((x(2:end)-x(1:end-1).^2).^2 + (1-x(1:end-1)).^2);
end


function [c,ceq] = circleconstr(x)

radius = 2;
ceq = [];
c = sum(x.^2) - radius^2;

end

Чтобы сгенерировать код из этого файла с помощью статического выделения памяти, установите строение кодера следующим образом.

cfg = coder.config('mex');
cfg.DynamicMemoryAllocation = 'Off'; % No dynamic memory allocation
cfg.SaturateOnIntegerOverflow = false; % No MATLAB integer saturation checking
cfg.IntegrityChecks = false; % No checking for out-of-bounds access in arrays

Сгенерируйте код для nlp_for_loop.m файл.

codegen -config cfg nlp_for_loop

Запустите полученный файл MEX.

nlp_for_loop_mex
1 Inequality Constraints; fval: 542.688894; Exitflag: 1 
2 Inequality Constraints; fval: 793.225322; Exitflag: 1 
3 Inequality Constraints; fval: 1072.945843; Exitflag: 1 
4 Inequality Constraints; fval: 1400.000000; Exitflag: 1 

Значение функции увеличивается при каждой итерации, потому что задача имеет больше ограничений.

Похожие темы