fmincon
Генерация кодаВ этом примере показано, как использовать выделение статического ЗУ в генерации кода, даже когда некоторые матричные размеры изменяются во время расчета.
Проблемой является простая нелинейная минимизация и с нелинейной ограничительной функцией и с линейными ограничениями. Размеры линейных ограничительных матриц изменяются в каждой итерации, которая заставляет требования к памяти увеличиваться в каждой итерации. Пример показывает, как использовать coder.varsize
команда, чтобы установить соответствующие переменные размеры для выделения статического ЗУ.
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
Значение функции увеличивается в каждой итерации, потому что проблема имеет больше ограничений.